Initial revision
[ssr] / StraySrc / Glass / !Glass / c / wWinEvent
1 /*
2 * wWinEvent.c
3 *
4 * Handling events for template windows
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Glass.
12 *
13 * Glass 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)
16 * any later version.
17 *
18 * Glass 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.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31 * ANSI standard headers
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*
39 * Steel headers
40 */
41
42 #define _STDAPP
43 #define _LOWLVL
44 #include "steel/Steel.h"
45
46 #include "steel/interface.h"
47 #include "steel/sculptrix.h"
48 #include "steel/caretPtr.h"
49 #include "steel/akbd.h"
50 #include "steel/bbc.h"
51
52 /*
53 * Glass headers
54 */
55
56 #include "gStruct.h"
57 #include "gMenus.h"
58 #include "gIcons.h"
59
60 #include "glass.h"
61 #include "gPrefs.h"
62 #include "tfile.h"
63 #include "window.h"
64 #include "_window.h"
65 #include "intMsgs.h"
66 #include "toolbox.h"
67 #include "editIcon.h"
68 #include "editWin.h"
69 #include "tearEdit.h"
70
71 /*----- Main code ---------------------------------------------------------*/
72
73 /*
74 * void window__winIdles(void *handle)
75 *
76 * Use
77 * Changes the pointer shape to something appropriate for what its over.
78 *
79 * Parameters
80 * void *handle == pointer to window containing pointer
81 */
82
83 void window__winIdles(void *handle)
84 {
85 glass_windPointer *w=handle;
86 int i=window__pointerInfo(w,-1,TRUE);
87 #ifndef glass_DEMO
88 if (w->testMode)
89 i=window__SELECT;
90 #endif
91 window__setPtrShape(i);
92 window__updateInfoBar(FALSE);
93 }
94
95 /*
96 * int window__keyAhead(int k,int *nk)
97 *
98 * Use
99 * Counts how many times the given key k is pressed, and returns the next
100 * key in *nk (or -1 if no next key).
101 *
102 * Parameters
103 * int k == the key to check for
104 * int *nk == where to store next key value
105 *
106 * Returns
107 * Number of times key was buffered.
108 */
109
110 static int window__keyAhead(int k,int *nk)
111 {
112 int count=0;
113 *nk=k;
114 while (*nk==k)
115 {
116 count++;
117 if (!akbd_pollkey(nk))
118 *nk=-1;
119 else
120 *nk=akbd_translate(*nk);
121 }
122 return (count);
123 }
124
125 /*
126 * void window__testEvents(wimp_eventstr *e,void *handle)
127 *
128 * Use
129 * Handles all events for windows running in Test mode. Events handled
130 * are:
131 *
132 * Redraw Redraws the window using Interface/hatch pattern as requested.
133 * Open Moves the window around.
134 * Close Closes the window(!)
135 * Leave Ignored
136 * Enter Turn off STEEL pointer changing
137 * Click Handled by WIMP or Interface, except for menu, which opens
138 * the menu(!)
139 * Key Handled by WIMP, WimpExtension, or ignored
140 *
141 * Parameters
142 * wimp_eventstr *e == the event
143 * void *handle == pointer to window info
144 */
145
146 #ifndef glass_DEMO
147
148 void window__testEvents(wimp_eventstr *e,void *handle)
149 {
150 glass_windPointer *w=handle; /* Extract my data from the handle */
151 wimp_wstate s;
152 int ox,oy;
153 wimp_redrawstr r; /* For the redraw event */
154 BOOL more; /* To tell me when I've finished */
155 wimp_w wnd;
156 os_regset reg;
157 wimp_icon icon;
158 sculptrix_slabDescriptor d;
159
160 switch (e->e)
161 {
162 case wimp_EREDRAW:
163 r.w=w->h;
164 wimpt_noerr(wimp_redraw_wind(&r,&more)); /* Start the redraw */
165 window__redraw(w,&r,&more);
166 break;
167 case wimp_EOPEN:
168 if (e->data.o.x<=w->def->desc.w.scx &&
169 e->data.o.y>=w->def->desc.w.scy)
170 {
171 r.w=e->data.o.w;
172 r.box=w->tex;
173 if (tst(w->def->desc.w.flags,14))
174 {
175 r.box.x0=w->def->desc.w.ex.x0;
176 r.box.x1=max2(w->def->desc.w.ex.x1,e->data.o.x+e->data.o.box.x1-
177 e->data.o.box.x0);
178 }
179 if (tst(w->def->desc.w.flags,15))
180 {
181 r.box.y1=w->def->desc.w.ex.y1;
182 r.box.y0=min2(w->def->desc.w.ex.y0,e->data.o.y-e->data.o.box.y1+
183 e->data.o.box.y0);
184 }
185 if (memcmp(&r.box,&w->tex,sizeof(wimp_box)))
186 {
187 wimpt_noerr(wimp_set_extent(&r));
188 w->tex=r.box;
189 }
190 }
191
192 if (window_selectionOwner()==w)
193 window__setToolBarPositions(&e->data.o);
194 else
195 wimpt_noerr(wimp_open_wind(&e->data.o));
196 w->def->desc.w.box=e->data.o.box; /* Copy the information down */
197 w->def->desc.w.scx=e->data.o.x;
198 w->def->desc.w.scy=e->data.o.y;
199 w->def->desc.w.behind=e->data.o.behind;
200 if (!w->t->alts) /* Moving the window alters the template */
201 tfile_markAsAltered(w->t); /* But only if not already altered */
202 if (wimpt_justChangedMode() && w->antiAliased)
203 {
204 if (wnd=window__recreate(w),!wnd)
205 return;
206 win_register_event_handler(wnd,window__testEvents,w);
207 wimpt_noerr(wimp_get_wind_state(w->h,&s));
208 wimpt_noerr(wimp_delete_wind(w->h));
209 win_register_event_handler(w->h,0,0);
210 win_activedec();
211 w->h=wnd;
212 s.o.w=w->h;
213 wimpt_noerr(wimp_open_wind(&s.o));
214 }
215 break;
216 case wimp_ECLOSE:
217 window_close(w);
218 break;
219 case wimp_EBUT:
220 e=wimpt_last_event(); /* Get the real event */
221 switch (e->data.but.m.bbits)
222 {
223 case wimp_BMID:
224 if (gPrefs_current()->sSlabMenu && e->data.but.m.i!=-1)
225 sculptrix_slabIcon(e->data.but.m.w,e->data.but.m.i,&d);
226 if (gPrefs_current()->iSlabMenu && e->data.but.m.i!=-1)
227 {
228 wimpt_noerr(wimp_get_icon_info(w->h,e->data.but.m.i,&icon));
229 interface_slabButton(&e->data.but.m);
230 }
231 wimpt_noerr(wimp_get_wind_state(w->h,&s));
232 ox=s.o.box.x0-s.o.x;
233 oy=s.o.box.y1-s.o.y;
234 window__showMenu(e->data.but.m.x-ox,e->data.but.m.y-oy,w);
235 e->data.but.m.bbits=0;
236 if (gPrefs_current()->iSlabMenu && e->data.but.m.i!=-1)
237 {
238 interface_slabButton(&e->data.but.m);
239 if (icon.flags & wimp_IFONT)
240 {
241 wimpt_noerr(wimp_set_icon_state(w->h,
242 e->data.but.m.i,
243 icon.flags & 0xff000000,
244 0xff000000));
245 }
246 }
247 if (gPrefs_current()->sSlabMenu && e->data.but.m.i!=-1)
248 sculptrix_unslabIcon(&d);
249 break;
250 case wimp_BDRAGLEFT:
251 case wimp_BDRAGRIGHT:
252 break;
253 default:
254 if (gPrefs_current()->sSlabIcons && e->data.but.m.i!=-1)
255 sculptrix_slabIcon(e->data.but.m.w,e->data.but.m.i,&d);
256
257 if (gPrefs_current()->iSlabIcons && e->data.but.m.i!=-1)
258 {
259 wimpt_noerr(wimp_get_icon_info(w->h,e->data.but.m.i,&icon));
260 interface_slabButton(&e->data.but.m);
261 e->data.but.m.bbits=0;
262 interface_slabButton(&e->data.but.m);
263 if (icon.flags & wimp_IFONT)
264 {
265 wimpt_noerr(wimp_set_icon_state(w->h,
266 e->data.but.m.i,
267 icon.flags & 0xff000000,
268 0xff000000));
269 }
270 }
271
272 if (gPrefs_current()->sSlabIcons && e->data.but.m.i!=-1)
273 sculptrix_unslabIcon(&d);
274 break;
275 }
276 break;
277 case wimp_EPTRLEAVE:
278 w->ownPointer=FALSE;
279 win_removeIdleClaimer(window__winIdles,w);
280 window__updateInfoBar(FALSE);
281 window__setPtrShape(window__SELECT);
282 interface_spritearea((sprite_area *)1);
283 break;
284 case wimp_EPTRENTER:
285 w->ownPointer=TRUE;
286 win_addIdleClaimer(window__winIdles,win_DONTCARE,w);
287 caretPtr__pointer(FALSE); /* Don't change pointer in this window */
288 interface_spritearea(w->t->s);
289 break;
290 case wimp_EKEY:
291 if (gPrefs_current()->wKeyPress)
292 {
293 reg.r[0]=e->data.key.chcode;
294 reg.r[2]=w->h;
295 reg.r[3]=e->data.key.c.i;
296 os_swix(XWimpExt_MoveCaret,&reg);
297 if (reg.r[0])
298 wimpt_noerr(wimp_processkey(e->data.key.chcode));
299 else
300 {
301 reg.r[0]=2;
302 reg.r[2]=-1;
303 os_swix(XWimpExt_ViewIcon,&reg);
304
305 /* --- That may have moved the window, so... --- */
306
307 wimpt_noerr(wimp_get_wind_state(w->h,&s));
308 if (s.o.x!=w->def->desc.w.scx || s.o.y!=w->def->desc.w.scy)
309 {
310 w->def->desc.w.scx=s.o.x;
311 w->def->desc.w.scy=s.o.y;
312 if (!w->t->alts)
313 tfile_markAsAltered(w->t);
314 }
315 }
316 }
317 else
318 wimpt_noerr(wimp_processkey(e->data.key.chcode));
319 break;
320 case wimp_ESEND:
321 case wimp_ESENDWANTACK:
322 window__events(e,w);
323 break;
324 }
325 }
326
327 #endif
328
329 /*
330 * void window__events(wimp_eventstr *e,void *handle)
331 *
332 * Use
333 * Handles all events for template windows (this is the first chance I've
334 * had to get my fingers *REALLY* mucky on this whole project!)
335 *
336 * Parameters
337 * wimp_eventstr *e == the event that I am meant to be inerested in
338 * void *handle == a pointer to the structural information for this window
339 */
340
341 void window__events(wimp_eventstr *e,void *handle)
342 {
343 glass_windPointer *w=handle; /* Extract my data from the handle */
344 wimp_redrawstr r; /* For the redraw event */
345 BOOL more; /* To tell me when I've finished */
346 int i;
347 int zone;
348 glass_intMsgstr *m;
349 wimp_wstate s;
350 wimp_w wnd;
351 wimp_caretstr c;
352 int ox=0,oy=0;
353 int set=FALSE;
354 wimp_box b;
355 BOOL started=FALSE;
356 static BOOL dontDrag; /* Disable/ignore next drag event */
357 glass_iconDescription icd;
358 wimp_box bound;
359 int dragType;
360 int key,okey;
361
362 switch (e->e)
363 {
364 case wimp_EREDRAW:
365 r.w=w->h;
366 wimpt_noerr(wimp_redraw_wind(&r,&more)); /* Start the redraw */
367 window__redraw(w,&r,&more);
368 break;
369 case wimp_EOPEN:
370
371 /* --- Handle rubbery extents --- *
372 *
373 * We've got to make sure the window's not scrolling here, otherwise
374 * very strange things start happening.
375 */
376
377 if (e->data.o.x<=w->def->desc.w.scx &&
378 e->data.o.y>=w->def->desc.w.scy)
379 {
380 r.w=e->data.o.w;
381 r.box=w->tex;
382 if (tst(w->def->desc.w.flags,14))
383 {
384 r.box.x0=w->def->desc.w.ex.x0;
385 r.box.x1=max2(w->def->desc.w.ex.x1,e->data.o.x+e->data.o.box.x1-
386 e->data.o.box.x0);
387 }
388 if (tst(w->def->desc.w.flags,15))
389 {
390 r.box.y1=w->def->desc.w.ex.y1;
391 r.box.y0=min2(w->def->desc.w.ex.y0,e->data.o.y-e->data.o.box.y1+
392 e->data.o.box.y0);
393 }
394 if (memcmp(&r.box,&w->tex,sizeof(wimp_box)))
395 {
396 wimpt_noerr(wimp_set_extent(&r));
397 w->tex=r.box;
398 }
399 }
400
401 if (window_selectionOwner()==w)
402 window__setToolBarPositions(&e->data.o);
403 else
404 wimpt_noerr(wimp_open_wind(&e->data.o));
405 w->def->desc.w.box=e->data.o.box; /* Copy the information down */
406 w->def->desc.w.scx=e->data.o.x;
407 w->def->desc.w.scy=e->data.o.y;
408 w->def->desc.w.behind=e->data.o.behind;
409 if (!w->t->alts) /* Moving the window alters the template */
410 tfile_markAsAltered(w->t); /* But only if not already altered */
411 editWindow_windowMoved(w);
412 if (wimpt_justChangedMode() && w->antiAliased)
413 {
414 if (wnd=window__recreate(w),!wnd)
415 return;
416 win_register_event_handler(wnd,window__events,w);
417 wimpt_noerr(wimp_get_wind_state(w->h,&s));
418 wimpt_noerr(wimp_delete_wind(w->h));
419 win_register_event_handler(w->h,0,0);
420 win_activedec();
421 w->h=wnd;
422 s.o.w=w->h;
423 wimpt_noerr(wimp_open_wind(&s.o));
424 }
425 break;
426 case wimp_ECLOSE:
427 window_close(w);
428 break;
429 case wimp_EBUT:
430 if (window__qDragType()!=-1)
431 break;
432 switch (e->data.but.m.bbits)
433 {
434 case wimp_BMID:
435 wimpt_noerr(wimp_get_wind_state(w->h,&s));
436 ox=s.o.box.x0-s.o.x;
437 oy=s.o.box.y1-s.o.y;
438 window__showMenu(e->data.but.m.x-ox,e->data.but.m.y-oy,w);
439 break;
440 case wimp_BLEFT:
441 if (!(akbd_pollsh() && (w->lastClicked!=-1)) &&
442 !w->renumber &&
443 (!gPrefs_current()->mCtrlEdit || akbd_pollctl()))
444 {
445 i=window__pointerInfo(w,-1,TRUE);
446 if ((i & window__ZONEMASK)==window__HORGUIDE ||
447 (i & window__ZONEMASK)==window__VERGUIDE)
448 break;
449 if (i!=-1)
450 editIcon(w,i&window__ICONMASK);
451 else
452 {
453 i=window__pointerInfo(w,-1,FALSE);
454 if (i!=-1)
455 editIcon(w,i);
456 else
457 editWindow(w);
458 }
459 break;
460 }
461 /* Otherwise drop through to select... */
462 case wimp_BRIGHT:
463 /* Treat this as a normal click - drop to select */
464 case wimp_BCLICKLEFT:
465 case wimp_BCLICKRIGHT:
466
467 /* --- if we're in the toolbox, or grab mode, ignore click --- */
468
469 if (toolbox_toolSelected() || window_grabbing())
470 {
471 dontDrag=TRUE; /* The WIMP gives a drag on grab sprites! */
472 break;
473 }
474
475 /* --- give this window the selection, tool bars, and caret --- */
476
477 window__gainSelection(w);
478
479 /* --- special case for renumbering --- */
480
481 if (w->renumber)
482 {
483 i=window__pointerInfo(w,-1,FALSE);
484 if (!(i & window__ZONEMASK) && w->def->i[i].selected)
485 {
486 set=window__lowestSelected(w);
487 window__select(w,i,FALSE);
488 icd=w->def->i[i];
489 w->def->i[i]=w->def->i[set];
490 w->def->i[set]=icd;
491 window_redrawIcon(w,i);
492 window_redrawIcon(w,set);
493 tfile_markAsAltered(w->t);
494 if (w->selno)
495 window__nextRenumber(w);
496 else
497 window__renumber(w,FALSE);
498 }
499 window__updateMenu(w); /* May have changed focus */
500 break;
501 }
502
503 /* --- handle depthwise selection - no problem with guides --- */
504 /* --- because we know the pointer is over an icon --- */
505
506 if (akbd_pollsh() &&
507 w->lastClicked!=-1 &&
508 window__pointerOverIcon(w,w->lastClicked))
509 {
510 i=w->lastClicked;
511 w->lastClicked=window__pointerInfo(w,w->lastClicked,FALSE);
512 if (i!=w->lastClicked)
513 {
514 if (i==window__selectedIcon())
515 window__setSelectedIconDeselecting(w->lastClicked);
516 else
517 {
518 window__select(w,i,FALSE);
519 window__select(w,w->lastClicked,TRUE);
520 }
521 }
522 dontDrag=TRUE;
523 window__updateMenu(w);
524 break;
525 }
526
527 /* --- this is the complicated bit. ADJUST should just --- */
528 /* --- toggle the object. So do this, but remember, it --- */
529 /* --- could have been a double-click --- */
530
531 if (e->data.but.m.bbits==wimp_BCLICKRIGHT ||
532 e->data.but.m.bbits==wimp_BRIGHT)
533 {
534 i=window__pointerInfo(w,-1,FALSE);
535 if (i != -1 && (i & window__ZONEMASK)) {
536 i &= window__ICONMASK;
537 w->guide[i].selected=!w->guide[i].selected;
538 window__redrawGuide(w,i);
539 dontDrag=TRUE;
540 } else {
541 if (i!=-1)
542 {
543 window__select(w,i,!w->def->i[i].selected);
544 w->lastClicked=i;
545 dontDrag=TRUE;
546 }
547 else
548 dontDrag=FALSE;
549 }
550 window__updateMenu(w);
551 break;
552 }
553
554 /* --- now we're left with a SELECT click. If this is the --- */
555 /* --- start of a drag, then ignore it, otherwise do normal --- */
556 /* --- SELECT-type things (deselecting other icons etc.) --- */
557
558 i=window__pointerInfo(w,-1,TRUE);
559 if (i==-1)
560 {
561 i=window__pointerInfo(w,-1,FALSE);
562 zone=-1;
563 }
564 else
565 {
566 zone=i & window__ZONEMASK;
567 i&=window__ICONMASK;
568 }
569 w->lastClicked=i;
570
571 switch (zone)
572 {
573 case -1: /* Not previously selected */
574 if (w->lastClicked!=-1)
575 window__setSelectedIconDeselecting(w->lastClicked);
576 for (i=0;i<w->def->desc.w.nicons;i++)
577 {
578 if (i!=w->lastClicked)
579 window__select(w,i,FALSE);
580 }
581 dontDrag=FALSE;
582 break;
583 case window__HORGUIDE:
584 case window__VERGUIDE:
585 if (!w->guide[i].selected)
586 {
587 for (i=0;i<glass_GUIDELIMIT;i++)
588 {
589 if (w->guide[i].selected)
590 {
591 w->guide[i].selected=FALSE;
592 window__redrawGuide(w,i);
593 }
594 }
595 w->guide[w->lastClicked].selected=TRUE;
596 window__redrawGuide(w,w->lastClicked);
597 }
598 dontDrag=FALSE;
599 break;
600 default:
601 /* --- Any other zones we ignore - these are for drag --- */
602 /* --- operations --- */
603 window__setSelectedIcon(w->lastClicked);
604 dontDrag=FALSE;
605 break;
606 }
607 window__updateMenu(w);
608 break;
609 case wimp_BDRAGLEFT:
610 case wimp_BDRAGRIGHT:
611 if (dontDrag ||
612 toolbox_toolSelected() ||
613 window_grabbing() ||
614 w->renumber)
615 break;
616
617 /* --- YARB -- Yet Another RISC OS Bug --- *
618 *
619 * In a terribly cunning way, the WIMP gives me drag events even
620 * when the mouse button is up and the user didn't drag at all.
621 * This is phenomenally irritating, and so, hi-ho, a bodging we
622 * will go...
623 */
624
625 bbc_mouse(0,0,&i,0);
626 if (!i)
627 return;
628
629 if (e->data.but.m.bbits==wimp_BDRAGLEFT)
630 {
631 i=window__pointerInfo(w,-1,TRUE);
632 if (i == -1)
633 dragType = window__SELECT;
634 else
635 dragType=i & window__ZONEMASK;
636 }
637 else
638 dragType=window__SELECT;
639 switch (dragType)
640 {
641 case window__SELECT:
642 case window__HORGUIDE:
643 case window__VERGUIDE:
644 break;
645 default:
646 for (i=0;i<w->def->desc.w.nicons;i++)
647 {
648 if (w->def->i[i].selected)
649 {
650 window_boundingBox(w,i,&b);
651 if (!started)
652 {
653 bound=b;
654 started=TRUE;
655 }
656 else
657 {
658 if (bound.x0>b.x0)
659 bound.x0=b.x0;
660 if (bound.x1<b.x1)
661 bound.x1=b.x1;
662 if (bound.y0>b.y0)
663 bound.y0=b.y0;
664 if (bound.y1<b.y1)
665 bound.y1=b.y1;
666 }
667 }
668 }
669 bound.x1-=wimpt_dx();
670 bound.y1-=wimpt_dy();
671 break;
672 }
673 wimpt_noerr(wimp_get_wind_state(w->h,&s));
674 ox=s.o.box.x0-s.o.x;
675 oy=s.o.box.y1-s.o.y;
676 window__startDrag(dragType,
677 &bound,
678 w,
679 e->data.but.m.x-ox,
680 e->data.but.m.y-oy);
681 break;
682 }
683 break;
684 case wimp_EPTRLEAVE:
685 w->ownPointer=FALSE;
686 win_removeIdleClaimer(window__winIdles,w);
687 window__updateInfoBar(FALSE);
688 window__setPtrShape(window__SELECT);
689 break;
690 case wimp_EPTRENTER:
691 w->ownPointer=TRUE;
692 win_addIdleClaimer(window__winIdles,win_DONTCARE,w);
693 if (window__qDragType()==window__GRABICON && !window__dragWind())
694 window__setDragWind(w);
695 break;
696 case wimp_EKEY:
697 key=akbd_translate(e->data.key.chcode);
698 while (key!=-1)
699 {
700 okey=key;
701 key=-1;
702 switch (okey)
703 {
704
705 /* --- Normal short-cuts, simulate menu entries --- */
706
707 case key_cF1:
708 window__simMenu(w,glass_TWMISC,glass_TWMINFO);
709 break;
710 case key_cW:
711 window__simMenu(w,glass_TWMISC,glass_TWMEDITWIN);
712 break;
713 case key_cT:
714 window__simMenu(w,glass_TWMISC,glass_TWMTEST);
715 break;
716 case key_cF2:
717 window__simMenu(w,glass_TWMISC,glass_TWMCLOSE);
718 break;
719 case key_F3:
720 window__simMenu(w,glass_TWSAVE,0);
721 break;
722 case key_cA:
723 window__simMenu(w,glass_TWSELECT,glass_TWSALL);
724 break;
725 case key_cZ:
726 window__simMenu(w,glass_TWSELECT,glass_TWSCLR);
727 break;
728 case key_cC:
729 window__simMenu(w,glass_TWSELECT,glass_TWSCOPY);
730 break;
731 case key_cX:
732 window__simMenu(w,glass_TWSELECT,glass_TWSDEL);
733 break;
734 case key_cR:
735 window__simMenu(w,glass_TWSELECT,glass_TWSORDER);
736 break;
737 case key_scF:
738 window__simMenu(w,glass_TWSELECT,glass_TWSFRONT);
739 break;
740 case key_cF:
741 window__simMenu(w,glass_TWSELECT,glass_TWSRAISE);
742 break;
743 case key_cB:
744 window__simMenu(w,glass_TWSELECT,glass_TWSLOWER);
745 break;
746 case key_scB:
747 window__simMenu(w,glass_TWSELECT,glass_TWSBACK);
748 break;
749 case key_cP:
750 window__simMenu(w,glass_TWSELECT,glass_TWSPULL);
751 break;
752 case key_cL:
753 window__simMenu(w,glass_TWSELECT,glass_TWSALIGN);
754 break;
755 case key_scE:
756 tearEdit_open();
757 break;
758 case key_cE:
759 window__simMenu(w,glass_TWSELECT,glass_TWSEDIT);
760 break;
761 #ifdef glass_NOTLAZY
762 case key_cD:
763 window__simMenu(w,glass_TWSELECT,glass_TWSDATA);
764 break;
765 #endif
766 case key_cN:
767 window__simMenu(w,glass_TWICON,glass_TWINEW);
768 break;
769 case key_cG:
770 window__simMenu(w,glass_TWICON,glass_TWIGRAB);
771 break;
772
773 /* --- Cursor keys -- move icons around --- */
774
775 /* No modifiers -- move the whole icon */
776
777 case key_Up:
778 b.y0=b.y1=window__keyAhead(okey,&key);
779 b.x0=b.x1=0;
780 window__nudgeIcons(w,&b);
781 break;
782 case key_Down:
783 b.y0=b.y1=-window__keyAhead(okey,&key);
784 b.x0=b.x1=0;
785 window__nudgeIcons(w,&b);
786 break;
787 case key_Left:
788 b.y0=b.y1=0;
789 b.x0=b.x1=-window__keyAhead(okey,&key);
790 window__nudgeIcons(w,&b);
791 break;
792 case key_Right:
793 b.y0=b.y1=0;
794 b.x0=b.x1=window__keyAhead(okey,&key);
795 window__nudgeIcons(w,&b);
796 break;
797
798 /* Control pressed -- move the most significant edge */
799
800 case key_cUp:
801 b.y1=window__keyAhead(okey,&key);
802 b.x0=b.x1=b.y0=0;
803 window__nudgeIcons(w,&b);
804 break;
805 case key_cDown:
806 b.y1=-window__keyAhead(okey,&key);
807 b.x0=b.x1=b.y0=0;
808 window__nudgeIcons(w,&b);
809 break;
810 case key_cLeft:
811 b.x1=-window__keyAhead(okey,&key);
812 b.y0=b.y1=b.x0=0;
813 window__nudgeIcons(w,&b);
814 break;
815 case key_cRight:
816 b.x1=window__keyAhead(okey,&key);
817 b.y0=b.y1=b.x0=0;
818 window__nudgeIcons(w,&b);
819 break;
820
821 /* Shift pressed -- move the least significant edge */
822
823 case key_sUp:
824 b.y0=window__keyAhead(okey,&key);
825 b.x0=b.x1=b.y1=0;
826 window__nudgeIcons(w,&b);
827 break;
828 case key_sDown:
829 b.y0=-window__keyAhead(okey,&key);
830 b.x0=b.x1=b.y1=0;
831 window__nudgeIcons(w,&b);
832 break;
833 case key_sLeft:
834 b.x0=-window__keyAhead(okey,&key);
835 b.y0=b.y1=b.x1=0;
836 window__nudgeIcons(w,&b);
837 break;
838 case key_sRight:
839 b.x0=window__keyAhead(okey,&key);
840 b.y0=b.y1=b.x1=0;
841 window__nudgeIcons(w,&b);
842 break;
843
844 /* Shift and control pressed -- scroll the window --- */
845
846 case key_scUp:
847 window__nudgeScroll(w,0,window__keyAhead(okey,&key));
848 break;
849 case key_scDown:
850 window__nudgeScroll(w,0,-window__keyAhead(okey,&key));
851 break;
852 case key_scLeft:
853 window__nudgeScroll(w,-window__keyAhead(okey,&key),0);
854 break;
855 case key_scRight:
856 window__nudgeScroll(w,window__keyAhead(okey,&key),0);
857 break;
858
859 /* --- No match -- pass on keypress --- */
860
861 default:
862 wimp_processkey(e->data.key.chcode);
863 break;
864 }
865 }
866 break;
867 case wimp_ESEND:
868 case wimp_ESENDWANTACK:
869 switch (e->data.msg.hdr.action)
870 {
871 case wimp_MHELPREQUEST:
872 help_startHelp();
873 help_addLine(msgs_lookup("wdhWIN"),w->id);
874 if (i=window__pointerInfo(w,-1,FALSE),i!=-1)
875 help_addLine(msgs_lookup("wdhICN"),i);
876 else
877 help_addLine(msgs_lookup("wdhBKG"));
878 help_endHelp();
879 break;
880 case wimp_MINTERNAL:
881 m=intMsgs_receive(e);
882 switch (e->data.msg.data.words[0])
883 {
884 case glass_REDRAW:
885 if (m->rdr.t==w->t || m->rdr.t==0)
886 {
887 wimpt_noerr(wimp_get_wind_state(w->h,&s));
888 r.w=w->h;
889 r.box.x0=s.o.x;
890 r.box.x1=r.box.x0+s.o.box.x1-s.o.box.x0;
891 r.box.y1=s.o.y;
892 r.box.y0=r.box.y1+s.o.box.y0-s.o.box.y1;
893 wimpt_noerr(wimp_force_redraw(&r));
894 }
895 break;
896 case glass_RENAME:
897 if (m->rn.w==w && w==window_selectionOwner())
898 window__updateInfoName(w->id);
899 break;
900 case glass_SPRITECHANGE:
901 if (m->sc.t==w->t)
902 {
903 wimpt_noerr(wimp_get_caret_pos(&c));
904 if (wnd=window__recreate(w),!wnd)
905 return;
906 if (c.w==w->h)
907 c.w=wnd;
908 #ifndef glass_DEMO
909 win_register_event_handler(wnd,
910 w->testMode ? window__testEvents : window__events,w);
911 #else
912 win_register_event_handler(wnd,window__events,w);
913 #endif
914 wimpt_noerr(wimp_get_wind_state(w->h,&s));
915 wimpt_noerr(wimp_delete_wind(w->h));
916 win_register_event_handler(w->h,0,0);
917 win_activedec();
918 w->h=wnd;
919 s.o.w=w->h;
920 wimpt_noerr(wimp_open_wind(&s.o));
921 if (c.w==wnd)
922 wimp_set_caret_pos(&c);
923 }
924 break;
925 }
926 break;
927 }
928 break;
929 }
930 }