4 * Low level Wimp interface
6 * © 1994-1998 Straylight
9 /*----- Licensing note ----------------------------------------------------*
11 * This file is part of Straylight's Steel library.
13 * Steel is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * Steel is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 /*----- Header files ------------------------------------------------------*/
50 #include "interface.h"
51 #include "exception.h"
55 #include "sculptrix.h"
58 /*----- Veneered internal functions ---------------------------------------*/
61 extern void _dllEntry(wimpt__signals)(int sig);
62 extern void _dllEntry(wimpt__escapeHandler)(int sig);
63 extern void _dllEntry(wimpt__exit)(void);
66 /*----- Static data -------------------------------------------------------*/
68 /* --- Event handling --- */
70 static BOOL wimpt__fakeWaiting;
71 static wimp_eventstr wimpt__fakeEvent;
72 static wimp_eventstr wimpt__lastEvent;
74 /* --- Wimp task management --- */
76 static wimp_t wimpt__task;
77 static char *wimpt__name="<Untitled>";
78 static int wimpt__wimpVersion;
79 static int *wimpt__messages;
80 static BOOL wimpt__justChangedMode;
81 static int wimpt__pollingTime=100/50;
82 static int wimpt__options=wimpt_OSCULPTRIX;
84 /* --- Mode information --- */
86 static int wimpt__currentMode;
89 static int wimpt__bpp;
90 static int wimpt__xwind;
91 static int wimpt__ywind;
93 /*----- Internal functions ------------------------------------------------*/
95 /* --- Signal handling --- */
97 _dll_static void wimpt__escapeHandler(int sig)
100 signal(SIGINT,_dllEntry(wimpt__escapeHandler));
103 _dll_static void wimpt__signals(int sig)
105 static char *errors[]=
120 signal(sig,_dllEntry(wimpt__signals));
121 exception_generate(msgs_lookup("wimptSIGC:%s - code=%s"),
122 _kernel_last_oserror()->errmess,
123 sig>0 && sig<8 ? errors[sig] : "SIGUKN");
126 /* --- Exit handler --- */
128 _dll_static void wimpt__exit(void)
130 if (wimpt__options & wimpt_OINTERFACE)
131 interface_closeDown(wimpt__task);
132 if (wimpt__options & wimpt_OWIMPEXT)
133 os_swiv(XWimpExt_CloseDown,wimpt__task);
134 wimp_taskclose(wimpt__task);
137 /*----- Screen mode information -------------------------------------------*/
139 BOOL wimpt_checkmode(void)
142 int old=wimpt__currentMode;
143 os_byte(135,&dummy,&wimpt__currentMode);
145 wimpt__dx=1<<bbc_vduvar(bbc_XEigFactor);
146 wimpt__dy=1<<bbc_vduvar(bbc_YEigFactor);
147 wimpt__bpp=1<<bbc_vduvar(bbc_Log2BPP);
148 wimpt__xwind=(bbc_vduvar(bbc_XWindLimit)+1)*wimpt_dx();
149 wimpt__ywind=(bbc_vduvar(bbc_YWindLimit)+1)*wimpt_dy();
151 return (old!=wimpt__currentMode);
169 int wimpt_scwidth(void)
171 return (wimpt__xwind);
174 int wimpt_scheight(void)
176 return (wimpt__ywind);
181 return (wimpt__currentMode);
184 /*----- Redrawing things --------------------------------------------------*/
186 void wimpt_forceredraw(void)
192 r.box.x1=wimpt__xwind;
193 r.box.y1=wimpt__ywind;
195 wimp_force_redraw(&r);
198 void wimpt_redraw(wimpt_redraw_proc p,void *handle)
200 wimp_eventstr *e=wimpt_last_event();
205 wimpt_noerr(wimp_redraw_wind(&r,&more));
210 if (wimpt__options & wimpt_OSCULPTRIX)
212 wimpt_noerr(sculptrix_setSpriteArea(resspr_area()));
213 wimpt_noerr(sculptrix_redrawWindow(&r));
215 if (wimpt__options & wimpt_OINTERFACE)
216 wimpt_noerr(interface_render3dWindow(&r));
217 if (wimpt__options & wimpt_OWIMPEXT)
218 wimpt_noerr(os_swiv(XWimpExt_Redraw,0,&r));
219 wimpt_noerr(wimp_get_rectangle(&r,&more));
223 /*----- Initialisation ----------------------------------------------------*/
225 void wimpt_setOptions(int eor,int bic)
227 wimpt__options=(wimpt__options & ~bic) ^ eor;
230 int wimpt_options(void)
232 return (wimpt__options);
235 void wimpt_setMessages(int msg,...)
244 if (wimpt__messages=mem_alloc(256*sizeof(int)),!wimpt__messages)
247 msgs_lookup("wimptNEMI:Not enough memory to initialise."));
252 wimpt__messages[i++]=msg;
260 if (wimpt__messages=mem_reAlloc(wimpt__messages,sz*sizeof(int)),
264 msgs_lookup("wimptNEMI:Not enough memory to initialise."));
268 wimpt__messages[i++]=msg;
272 if (wimpt__wimpVersion<300)
273 wimpt__wimpVersion=300;
276 void wimpt_wimpversion(int version)
278 wimpt__wimpVersion=version;
281 int wimpt_getVersion(void)
283 return (wimpt__wimpVersion);
286 void wimpt_init(char *progname)
290 signal(SIGABRT, _dllEntry(wimpt__signals));
291 signal(SIGFPE, _dllEntry(wimpt__signals));
292 signal(SIGILL, _dllEntry(wimpt__signals));
293 signal(SIGINT, _dllEntry(wimpt__escapeHandler));
294 signal(SIGSEGV, _dllEntry(wimpt__signals));
295 signal(SIGTERM, _dllEntry(wimpt__signals));
296 signal(SIGOSERROR, _dllEntry(wimpt__signals));
298 wimpt__name=progname;
300 if (!wimpt__wimpVersion)
302 /* --- Guess the current WIMP version --- */
304 switch (bbc_inkey(0xFF00))
306 case 0xA0: /* Arthur */
308 msgs_lookup("wimptARTH:Operating system too old. Try "
309 "upgrading to RISC OS!\n"));
312 case 0xA1: /* OS 2.00 */
313 case 0xA2: /* OS 2.01 */
314 wimpt__wimpVersion=200;
316 case 0xA3: /* OS 3.00 */
317 wimpt__wimpVersion=300;
319 case 0xA4: /* OS 3.10 */
320 default: /* Anything later */
321 wimpt__wimpVersion=310;
326 if (wimpt__wimpVersion==300 && !wimpt__messages)
328 /* Set up some sensible default messages for brain-damaged OS */
329 wimpt_setMessages(1,2,3,4,5,6,7,8,9,10,
331 0x400c0,0x400c1,0x400c9,
332 0x80140,0x80145,0x80147,
336 if (e=wimp_taskinit(progname,
345 msgs_lookup("wimptFTI:Failed to initialise: '%s'"),
347 fprintf(stderr,"\n");
352 atexit(_dllEntry(wimpt__exit));
354 /* --- Initialise any extensions --- */
356 if (wimpt__options & wimpt_OINTERFACE)
357 wimpt_noerr(interface_initialise(wimpt__task));
359 /* --- Handle WimpExtension with care... --- *
361 * If WimpExtension isn't initialised yet, it will start up its Wimp task,
362 * corrupting the application handle in the process, causing a bad crash
363 * when we return through app__epilogue.
366 if (wimpt__options & wimpt_OWIMPEXT)
372 dll_saveHandle(&handle);
373 err=os_swiv(XWimpExt_Initialise,16,wimpt__task,0);
374 dll_restoreHandle(&handle);
377 wimpt_noerr(os_swiv(XWimpExt_Initialise,16,wimpt__task,0));
382 char *wimpt_programname(void)
384 return (wimpt__name);
387 wimp_t wimpt_task(void)
389 return (wimpt__task);
392 /*----- Error handling ----------------------------------------------------*/
394 os_error *wimpt_complain(os_error *e)
397 werr_error(1,"%s",e->errmess);
401 void wimpt_noerr(os_error *e)
404 exception_generate("%s",e->errmess);
407 void wimpt_reporterror(os_error *e, wimp_errflags f)
409 werr_error((f & 3==3) ? 2 : 1,"%s",e->errmess);
412 /*----- Polling the WIMP --------------------------------------------------*/
414 os_error *wimpt_poll(wimp_emask mask,wimp_eventstr *result)
422 if (wimpt__fakeWaiting /* && !(mask & (1<<wimpt__fakeEvent.e)) */ )
424 *result=wimpt__fakeEvent;
425 wimpt__fakeWaiting=0;
426 wimpt__lastEvent=wimpt__fakeEvent;
430 alarming=alarm_next(&nextAlarm);
432 if (wimpt__options & wimpt_OWIMPEXT)
433 os_swiv(XWimpExt_PrePoll);
435 vs=visdelay_suspend();
437 if (alarming && (mask & wimp_EMNULL))
438 e=wimp_pollidle(mask & ~wimp_EMNULL,result,nextAlarm);
441 if ((mask & wimp_EMNULL) || !wimpt__pollingTime)
442 e=wimp_poll(mask,result);
445 timeNow=alarm_timenow()+wimpt__pollingTime;
446 if (alarming && nextAlarm<timeNow)
448 e=wimp_pollidle(mask,result,timeNow);
455 if (wimpt__options & wimpt_OWIMPEXT)
457 wimpt_noerr(os_swi3r(XWimpExt_Action,wimpt__task,
460 (int *)&result->e,0,0));
462 if (wimpt__options & wimpt_OINTERFACE)
463 interface_poll(result,wimpt__task);
465 wimpt__lastEvent=*result;
470 case wimp_ESENDWANTACK:
471 if (result->data.msg.hdr.action==0x400C1)
473 wimpt__justChangedMode=TRUE;
477 wimpt__justChangedMode=FALSE;
480 /* Could be part of the mode change */
483 caretPtr__pointer(FALSE);
484 wimpt__justChangedMode=FALSE;
487 caretPtr__pointer(TRUE);
488 wimpt__justChangedMode=FALSE;
491 wimpt__justChangedMode=FALSE;
497 BOOL wimpt_justChangedMode(void)
499 return (wimpt__justChangedMode);
502 int wimpt_pollingTime(int new)
504 int temp=wimpt__pollingTime;
506 wimpt__pollingTime=new;
510 void wimpt_fake_event(wimp_eventstr * e)
512 if (!wimpt__fakeWaiting)
514 wimpt__fakeWaiting=TRUE;
519 wimp_eventstr *wimpt_last_event(void)
521 return (&wimpt__lastEvent);
524 int wimpt_last_event_was_a_key(void)
526 return (wimpt__lastEvent.e == wimp_EKEY);
529 /*----- String width ------------------------------------------------------*/
532 * int wimpt_stringWidth(char *s)
535 * Determines the width of a string in OS units, taking into account the
536 * fact that it may be represented in a WIMP anti-aliased font.
539 * char *s == pointer to the string to font the length of
542 * The width of the string in OS units
545 int wimpt_stringWidth(char *s)
550 if (wimp_readsysinfo(wimp_IFONTHANDLE,&f) || !f)
551 return (strlen(s)*16);
555 font_converttopoints(1000,1000,&fs.x,&fs.y);
559 font_converttoos(fs.x,0,&fs.x,&fs.y);