§1  EVENTS  EVENT HANDLING 1

1. Event Handling. This file describe the main event loop, and most of the functions called from it to handle specific types of events. We start with some standard header stuff.

#include #include #include

2. There is one general header file that does all the includes needed for the graphical interface compilation units, in a proper order.

#include

3. Because there are so many local functions in this file, and only a few global ones, we choose to define all local functions in the unnamed module. This does mean that for a top-down presentation we shall often have to give explicit declarations for local functions that are used before they are defined.

#define local static

format local static

⟨ Local function declarations 21 ⟩

4. The file records declarations exported from this file.

⟨ 4 ⟩ ≡ ⟨ Global function declarations 5 ⟩

2  EVENT HANDLING  EVENTS §5

5. Now we come to the main event loop. All events pass through here, whether generated for the main window or for some other window of our program. For this reason all event types specified the mask for any window must be considered. ⟨ Global function declarations 5 ⟩ ≡

void event handler (void);

See also sections 7, 9, 11, 13, 15, 17, and 19. This code is used in section 4.

6. Each event type is dispatched to a function handling it. The one exceptional extra action is to clear any menu activation whenever the first mouse button is released, since this may occur in any window (including menu entry windows).

void event handler (void) { XEvent report ; /∗ details of the event are stored here ∗/

do { int t ⇐ (XNextEvent (display , &report ), report .type); win p p ⇐ lookup(report .xany .window );

event handler table ∗event tab ⇐ event table[p→type]; switch (t) { case Expose: event tab→expose(p); break; case ButtonPress : event tab→press (p, &report .xbutton); break; case ButtonRelease:

if (report .xbutton.button = Button_{1}) release menu( );

if (event tab→release ≠ ⊙) event tab→release(p, &report .xbutton); break;

case KeyPress : event tab→key (p, &report .xkey ); break; case MotionNotify : event tab→move(p, &report .xmotion); break; case EnterNotify : event tab→enter (p); break; case LeaveNotify : event tab→leave(p); break; case ConfigureNotify : event tab→configure(p, &report .xconfigure); break; case MappingNotify : XRefreshKeyboardMapping (&report .xmapping ); break; }

} while (true); }

§7  EVENTS  THE EXPOSE EVENT 3

7. The Expose event. ⟨ Global function declarations 5 ⟩ +≡

void icon expose (win p);

8.

void icon expose (win p p) { int i ⇐ p→data.nr ;

p outer window pane ⇐ p→type = diag icon win ? &info→dw [i]→pane : &info→pw [i]→pane; display icon graphics (pane→icon, pane→title, pane→visibility ); if ((p→type = diag icon win ? info→sel diag : info→sel pict ) = i) display select icon(pane→icon);

}

9. ⟨ Global function declarations 5 ⟩ +≡

void comment expose (win p);

10.

void comment expose (win p p) { print comment (p→data.inner ); }

11. Clicking in the scale or help window unmaps it. ⟨ Global function declarations 5 ⟩ +≡

void scale press (win p, XButtonEvent∗); void help press (win p, XButtonEvent∗);

12.

void scale press (win p p, XButtonEvent ∗xbutton) { if (info→scale.mapped ∧ xbutton→button = Button_{1})

info→scale.mapped ⇐ false, XUnmapWindow (display , info→scale.win→w); } void help press (win p p, XButtonEvent ∗xbutton) { if (info→help mapped ∧ xbutton→button = Button_{1})

info→help mapped ⇐ false, XUnmapWindow (display , info→help win→w); }

4  THE EXPOSE EVENT  EVENTS §13

13. ⟨ Global function declarations 5 ⟩ +≡

void icon press (win p, XButtonEvent∗);

14.

void icon press (win p p, XButtonEvent ∗xbutton) { int i ⇐ p→data.nr ;

p outer window pane ⇐ p→type = diag icon win ? &info→dw [i]→pane : &info→pw [i]→pane; if (xbutton→button = Button_{1})

if (p→type = diag icon win)

if (pane→visibility = iconised ) deiconise diagram window (info→dw [i]); else diag menu iconise func(info→dw [i]→pane.win);

else if (pane→visibility = iconised ) deiconise picture window (info→pw [i]); else pict menu iconise func(info→pw [i]→pane.win);

else if (xbutton→button = Button_{2})

if (p→type = diag icon win)

if (i = info→sel diag ) diag menu deselect func(info→dw [i]→pane.win); else diag menu select func(info→dw [i]→pane.win);

else if (i = info→sel pict ) pict menu deselect func(info→pw [i]→pane.win); else pict menu select func(info→pw [i]→pane.win);

}

§15  EVENTS  THE KEYPRESS EVENT 5

15. The KeyPress event. When a key is pressed in the entry window of the default settings window, a key press event occurs.

When a key is pressed in the box size entry window this function is executed. It first collects the KeySym from the XKeyEvent structure. If the character is a carriage return (or any variation on it) and the string is two digits long, the box size in all the windows is changed. If the character is a digit (0-9), then this digit is added, unless the string is already two characters long. Finally, if the character is a backspace or delete key, the the last character of the string is set to 0, thereby removing the last character. If none of these keys are pressed, a bell is sounded. ⟨ Global function declarations 5 ⟩ +≡

void scale entry key (win p, XKeyEvent∗);

16.

void scale entry key (win p p, XKeyEvent ∗xkey ) { int bufsize ⇐ 4; char buffer [4] ⇐ ; KeySym keysym; XComposeStatus compose;

(void) XLookupString (xkey , buffer , bufsize, &keysym, &compose); if ((keysym = XK Return) ∨ (keysym = XK KP Enter ) ∨ (keysym = XK Linefeed )) { if (strlen(info→scale.bs string ) = 2)

{ info→scale.box size ⇐ atoi (info→scale.bs string ); reprint all windows ( );

} } else if ((keysym ≥ ) ∧ (keysym ≤ )) { if (strlen(info→scale.bs string ) < 2)

{ if (strlen(info→scale.bs string ) ≠ 0 ∨ keysym ≠ )

{ strcat (info→scale.bs string , buffer ); XClearWindow (display , p→w); }

} } else if ((keysym = XK BackSpace) ∨ (keysym = XK Delete)) { if (strlen(info→scale.bs string ) > 0)

{ info→scale.bs string [strlen(info→scale.bs string ) − 1] ⇐ ; XClearWindow (display , p→w); }

} else XBell (display , 100); scale entry enter (p); /∗ display frame ∗/ scale entry expose(p);

}

6  THE ENTER AND LEAVE EVENTS  EVENTS §17

17. The Enter and Leave events. When the mouse pointer enters or leaves a specific window, an event occurs, and is dealt with by these functions. ⟨ Global function declarations 5 ⟩ +≡

void inner enter (win p); void inner leave (win p);

18.

void inner enter (win p p) { p inner window win ⇐ p→type = inner diag win ? &p→data.diag →disp : p→type = pict dom win

? &p→data.pict →i : &p→data.pict →d; if (win→m state = 2) win→m state ⇐ 1;

} void inner leave (win p p) { p inner window win ⇐ p→type = inner diag win ? &p→data.diag →disp : p→type = pict dom win

? &p→data.pict →i : &p→data.pict →d; if (win→m state = 1) win→m state ⇐ 2;

}

§19  EVENTS  THE CONFIGURE AND MAPPING EVENTS 7

19. The Configure and Mapping events. Whenever the parent window is resized, all the sub-windows are unmapped because there size is relative to the parent window size. Then window width and window height variables must be updated so that all the window size dependent routines can be adjusted. If the resize is too small the minimum window size is used. Finally all the sub-windows are mapped again. ⟨ Global function declarations 5 ⟩ +≡

void outer configure (win p, XConfigureEvent∗);

20.

void outer configure (win p p, XConfigureEvent ∗xconfig ) { if (p→type = outer diag win) configure diagram window (p→data.diag , xconfig );

else configure picture window (p→data.pict , xconfig ); }

21. These functions configure the diagram (picture) window then the window is resized. ⟨ Local function declarations 21 ⟩ ≡

local void configure diagram window (p diagram window, XConfigureEvent∗); local void configure picture window (p picture window, XConfigureEvent∗);

This code is used in section 3.

22.

local void configure diagram window (p diagram window dw , XConfigureEvent ∗xconfig ) { p outer window pane ⇐ &dw →pane;

pane→width ⇐ xconfig →width; pane→height ⇐ xconfig →height ;

resize menubar (pane→mb→win, pane→width); resize diagram scrollbars (dw ); resize inner window (&dw →disp, pane, inner diag win);

} local void configure picture window (p picture window pw , XConfigureEvent ∗xconfig ) { p outer window pane ⇐ &pw →pane;

pane→width ⇐ xconfig →width; pane→height ⇐ xconfig →height ;

resize menubar (pane→mb→win, pane→width); resize picture scrollbars (pw ); resize inner window (&pw →d, pane, pict dom win); resize inner window (&pw →i, pane, pict im win);

}

8  INDEX  EVENTS §23

23. Index.

atoi : 16. box size: 16. bs string : 16. buffer : \underline{16}. bufsize: \underline{16}. button: 6, 12, 14. ButtonPress : 6. ButtonRelease: 6. Button_{1}: 6, 12, 14. Button_{2}: 14. comment expose: \underline{9}, \underline{10}. compose: \underline{16}. configure: 6. configure diagram window : 20, \underline{21}, \underline{22}. configure picture window : 20, \underline{21}, \underline{22}. ConfigureNotify : 6. data: 8, 10, 14, 18, 20. deiconise diagram window : 14. deiconise picture window : 14. diag : 18, 20. diag icon win: 8, 14. diag menu deselect func: 14. diag menu iconise func: 14. diag menu select func: 14. disp: 18, 22. display : 6, 12, 16. display icon graphics : 8. display select icon: 8. dw : 8, 14, \underline{22}. enter : 6. EnterNotify : 6. event handler : \underline{5}, \underline{6}. event handler table: 6. event tab: \underline{6}. event table: 6. expose: 6. Expose: 6. false: 12. height : 22. help mapped : 12. help press : \underline{11}, \underline{12}. help win: 12. i: \underline{8}, \underline{14}. icon: 8. icon expose: \underline{7}, \underline{8}. icon press : \underline{13}, \underline{14}. iconised : 14. info: 8, 12, 14, 16. inner : 10. inner diag win: 18, 22. inner enter : \underline{17}, \underline{18}. inner leave: \underline{17}, \underline{18}. key : 6. KeyPress : 6. keysym: \underline{16}. KeySym: 15, 16. leave: 6. LeaveNotify : 6. local: \underline{3}. lookup: 6. m state: 18. mapped : 12. MappingNotify : 6. mb: 22. MotionNotify : 6. move: 6. nr : 8, 14. outer configure: \underline{19}, \underline{20}. outer diag win: 20. p: \underline{6}, \underline{8}, \underline{10}, \underline{12}, \underline{14}, \underline{16}, \underline{18}, \underline{20}. p diagram window: 21, 22. p inner window: 18. p outer window: 8, 14, 22. p picture window: 21, 22. pane: \underline{8}, \underline{14}, \underline{22}. pict : 18, 20. pict dom win: 18, 22. pict im win: 22. pict menu deselect func: 14. pict menu iconise func: 14. pict menu select func: 14. press : 6. print comment : 10. pw : 8, 14, \underline{22}. release: 6. release menu: 6. report : \underline{6}. reprint all windows : 16. resize diagram scrollbars : 22. resize inner window : 22. resize menubar : 22. resize picture scrollbars : 22. scale: 12, 16. scale entry enter : 16. scale entry expose: 16. scale entry key : \underline{15}, \underline{16}. scale press : \underline{11}, \underline{12}. sel diag : 8, 14. sel pict : 8, 14. strcat : 16. strlen: 16. t: \underline{6}.

§23  EVENTS  INDEX 9

title: 8. true: 6. type: 6, 8, 14, 18, 20. visibility : 8, 14. width: 22. win: 12, 14, \underline{18}, 22. win p: 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,

17, 18, 19, 20. window : 6. window height : 19. window width: 19. xany : 6. XBell : 16. xbutton: 6, \underline{12}, \underline{14}. XButtonEvent: 11, 12, 13, 14. XClearWindow : 16. XComposeStatus: 16. xconfig : \underline{20}, \underline{22}. xconfigure: 6. XConfigureEvent: 19, 20, 21, 22. XEvent: 6. XK BackSpace: 16. XK Delete: 16. XK KP Enter : 16. XK Linefeed : 16. XK Return: 16. : 16. : 16. xkey : 6, \underline{16}. XKeyEvent: 15, 16. XLookupString : 16. xmapping : 6. xmotion: 6. XNextEvent : 6. XRefreshKeyboardMapping : 6. XUnmapWindow : 12.

⟨ Global function declarations 5, 7, 9, 11, 13, 15, 17, 19 ⟩ Used in section 4.

⟨ Local function declarations 21 ⟩ Used in section 3. ⟨ 4 ⟩

EVENTS

Section Page

Event Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 The Expose event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3 The KeyPress event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5 The Enter and Leave events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 6 The Configure and Mapping events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 7 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 8