§1  WINDOWS  INTRODUCTION 1

1. Introduction. This file describes the major windows of the program (the ones that the use perceives as such), namely the main window (of which there is just one) and the diagram and picture windows, of which a substantial number may exist. 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 #define local static

format local static

⟨ Global variable definitions 18 ⟩

⟨ Local function definitions 24 ⟩

3. The file records declarations exported from this file.

⟨ 3 ⟩ ≡ ⟨ Global constant and macro definitions 4 ⟩ ⟨ Global typedefs 5 ⟩ ⟨ Global function declarations 19 ⟩

4. The following constants are the maximum number of picture and diagram windows, respectively, that can be opened at one time, maximum string lengths for a window title, and for a comment string displayed within some window. Although these constants are not used directly in other source files, they must be defined globally since they are used in the global typedefs.

⟨ Global constant and macro definitions 4 ⟩ ≡ #define picture limit 20 #define diagram limit 10 #define max title length 25 #define max comment length 100

See also section 10. This code is used in section 3.

2  INTRODUCTION  WINDOWS §5

5. Now we come to the data structures associated to the major windows of the program. We start with a structure outer window that contains the elements common to diagram and picture windows. Two win p values are directly associated to it: win for the outer window itself, and icon for its icon window, which is actually situated on the main window. Further windows are accessed indirectly via the menu bar structure pointed to by mb. The dimensions of the window win are stored in width and height , and the field visibility indicates whether this window is visible or just represented by its icon on the main window. The string title names the window and may be displayed by the window manager. ⟨ Global typedefs 5 ⟩ ≡

struct outer window

{ win p win, icon; /∗ outer window and “icon” on main window ∗/ int width, height ; /∗ dimension of win ∗/ enum { visible, iconised , removed } visibility ; struct m bar ∗mb; /∗ menu bar ∗/ char title[max title length];

};

See also sections 7, 9, 12, 14, and 16. This code is used in section 3.

6. While the order of the fields is still fresh in our memory, let us give the initiliser list for this structure, when it gets created. The win p fields are left null, since they can only be filled when the corresponding windows have actually been created. ⟨ Initialiser for outer window 6 ⟩ ≡

{ ⊙, ⊙, 0, 0, visible, ⊙, }

This code is used in sections 11 and 13.

7. Inside an outer window , objects are displayed within an inner window , of which there is one for a diagram window and two for a picture window. It contains the inner area win where the diagram will be actually displayed, and a window com for the comment line, a pair of horizontal and vertical “scroll bars” pointed to by hor and vert (which control the location of the logical origin within win), a variable m state indicating the state of the mouse button, the coordinates (i, j) of the square presently being queried (if any) and the comment string comment . ⟨ Global typedefs 5 ⟩ +≡

struct inner window

{ win p win, com; /∗ inner window and comment line ∗/ struct scrollbar ∗hor , ∗vert ; /∗ scroll bars ∗/ int m state; /∗ state of mouse: 0: not pressed here, 1: down inside, 2: down outside ∗/ int i, j; /∗ coordinates of query ∗/ char comment [max comment length];

};

8. ⟨ Initialiser for inner window 8 ⟩ ≡

{ ⊙, ⊙, ⊙, ⊙, 0, 0, 0, }

This code is used in sections 11 and 13.

9. Here is the structure for a complete diagram window. There is an outer window structure pane and an inner window structure disp. The flag mode records the current interaction mode, and d points to a diagram structure that contains the diagram itself. ⟨ Global typedefs 5 ⟩ +≡

struct diagram window

{ struct outer window pane; struct inner window disp; enum diagram window modes mode; /∗ selected interaction mode ∗/ diag p d;

};

10. This enumeration defines the modes a diagram window can be set to. ⟨ Global constant and macro definitions 4 ⟩ +≡

enum diagram window modes { add mode, remove br mode, remove tl mode, anti diagonal mode, query mode };

11. The only new feature to be initialised is the mode. ⟨ Initialiser for diagram window 11 ⟩ ≡

{ ⟨ Initialiser for outer window 6 ⟩ , ⟨ Initialiser for inner window 8 ⟩ , add mode, ⊙ }

This code is used in section 65.

12. Windows for pictures are similar. If set, the coordinate pairs (d.x, d.y) and (i.x, i.y) indicate a matching point-image pair that is highlighted. Picture windows are intended to display complete pictures, but while entering them initially, they must also accomodate partially defined pictures. At such times the relevant information is contained in a part pict structure pointd to by the field p, otherwis a complete picture is pointed to by the field f (these fields could have been combined in a union, but that would make selecting them more tedious to the progammer). By convention the picture is incomplete if and only if the p field differs from ⊙; if so the f field must be ⊙. ⟨ Global typedefs 5 ⟩ +≡

struct picture window

{ struct outer window pane; struct inner window d, i; part pict ∗p; pict p f;

};

13. A picture window is initialised by initialising its substructures. ⟨ Initialiser for picture window 13 ⟩ ≡

{ ⟨ Initialiser for outer window 6 ⟩

, ⟨ Initialiser for inner window 8 ⟩ , ⟨ Initialiser for inner window 8 ⟩

, ⊙, ⊙ }

This code is used in section 67.

14. The following structure will be part of the structure for the main window; it contains the data pertaining to the window that can be popped up for controlling the size of squares of all diagrams and pictures being displayed. Like before there is an outer and inner window, but a win p will suffice here to represent each of these. These are called win and bs win, where the latter is used to enter a two-digit size string that is stored in bs string . Its numerical value is recorded in box size. The field mapped tells whether the window is currently displayed. ⟨ Global typedefs 5 ⟩ +≡

typedef struct

{ win p win, bs win; int box size; char bs string [4]; bool mapped ;

} scale window;

15. The box size is set to 40 initially. ⟨ Initialiser for scale structure 15 ⟩ ≡

{ 0, 0, 40, , false }

This code is used in section 17.

16. And here is the structure of the main window. Since there is always only one main window, the fields of this window might also have been declared as global variables, but it is convenient to group them together, like for the other windows. In this case there is no inner win p directly represented, but a help window help win may be popped up elsewhere on the screen, and the window for adjusting the size of squares is called scale. The help mapped field is similar to the scale.mapped subfield. The main window has a menu bar, and all picture and menu windows are accessed from here via the arrays dw and pw . The number of such windows in existence (which may increase up to the stated maxima) are recorded in num diags and num picts . One window of either kind may be selected at any time, in which case its index is recorded in sel diag or sel pict . ⟨ Global typedefs 5 ⟩ +≡

struct main window

{ win p main win, help win; scale window scale; bool help mapped ; struct m bar ∗mb; p picture window pw [picture limit + 1]; p diagram window dw [diagram limit + 1]; int num diags , num picts ; int sel diag , sel pict ;

};

17. And here are the constant parts of the value to which the structure will be initialised. ⟨ Initialiser for main window structure 17 ⟩ ≡

{ 0, 0, ⟨ Initialiser for scale structure 15 ⟩ , false, ⊙, { ⊙ }, { ⊙ }, 0, 0, −1, −1 }

This code is used in section 22.

§18  WINDOWS  THE MAIN WINDOW 5

18. The main window. Each window has an associated set of events and event handlers. Here is what will be used for the main window.

⟨ Global variable definitions 18 ⟩ ≡

event handler table main handlers ⇐

{ ExposureMask | StructureNotifyMask , main expose, ⊙, ⊙, ⊙, ⊙, ⊙, ⊙, main configure };

See also sections 23, 25, 30, and 61. This code is used in section 2.

19. While main expose is defined in , we can give main configure right away. It is the first configure event for the main window that defines its real dimensions (which may or may not be equal to the hints supplied).

⟨ Global function declarations 19 ⟩ ≡

void main configure (win p, XConfigureEvent∗);

See also sections 21, 28, 31, 33, 35, 37, 39, 43, 45, 48, 51, 62, 64, 66, and 68. This code is used in section 3.

20.

void main configure (win p p, XConfigureEvent ∗xconfig )

{ window width ⇐ xconfig →width; window height ⇐ xconfig →height ;

if (info→mb = ⊙) /∗ then this is the first encounter ∗/

info→mb ⇐ create main menus (info→main win, window width); }

6  THE MAIN WINDOW  WINDOWS §21

21. The info structure associated with the main window is initialised to mainly blank values, which have been given before. However the window identifiers are all installed, although the scale and help windows are not yet mapped. #define 400 #define 150 #define 500 #define 230 ⟨ Global function declarations 19 ⟩ +≡

void init main data (void);

22.

void init main data (void)

{ static struct main window ini ⇐ ⟨ Initialiser for main window structure 17 ⟩ ; info ⇐ new (struct main window ); ∗info ⇐ ini ; /∗ set most fields of info ∗/ info→main win ⇐ base window ; info→scale.win ⇐

make window (scale win, root window , 100, 100, , ); { XSizeHints size;

size.flags ⇐ PMinSize | PMaxSize; size.min width ⇐ ;

size.max width ⇐ ; size.min height ⇐ ; size.max height ⇐ ; XSetStandardProperties (display , info→scale.win→w,

␣ , , icon pixmap, ⊙, 0, &size); } info→scale.bs win ⇐ make window (scale entry win, info→scale.win, 300, 85, 80, bf height + 10); map window (info→scale.bs win); /∗ nothing happens yet ∗/ info→help win ⇐

make window (help win, root window , 100, 100, , ); { XSizeHints size;

size.flags ⇐ PMinSize | PMaxSize; size.min width ⇐ ;

size.max width ⇐ ; size.min height ⇐ ;

size.max height ⇐ ; XSetStandardProperties (display , info→help win→w,

␣ , , icon pixmap, ⊙, 0, &size); }

}

23. ⟨ Global variable definitions 18 ⟩ +≡

event handler table scale handlers ⇐

{ (ExposureMask | ButtonPressMask ), scale expose, ⊙, ⊙, scale press , ⊙, ⊙, ⊙, ⊙ }; event handler table scale entry handlers ⇐

{ (ExposureMask | EnterWindowMask | LeaveWindowMask | KeyPressMask ), scale entry expose, scale entry enter , scale entry leave, ⊙, ⊙, scale entry key , ⊙, ⊙ };

§24  WINDOWS  DIAGRAM AND PICTURE WINDOW CREATION FUNCTIONS 7

event handler table help handlers ⇐ { (ExposureMask | ButtonPressMask ), help expose, ⊙, ⊙, help press , ⊙, ⊙, ⊙, ⊙ }; 24. Diagram and Picture window creation functions. The following routines set up the relevant structures and create the windows and menus for each diagram or picture window. This is similar to creating the main parent window. We start with the function map outer window that will create and map the outer window of a diagram or picture window. It sets a flag by means of XSetTransientForHint , which tells the window manager to use no icon for these windows, since that is done by the program itself in the main window. It does no harm that the window manager thinks the diagram and picture windows are transients (such as dialog boxes) for the main window, even though the are in fact the real thing. #define 500 #define 500 #define 700 #define 500 ⟨ Local function definitions 24 ⟩ ≡

local void map outer window (p outer window pane, enum window type t, int i)

{ sprintf (pane→title, ␣ , t = outer diag win ?  :  , i + 1);
pane→width ⇐ t = outer diag win ?  :  ;
pane→height ⇐ t = outer diag win ?  :  ;

pane→win ⇐ make window (t, root window , 300, 300, pane→width, pane→height );

if (t = outer diag win) pane→win→data.diag ⇐ info→dw [i];

else pane→win→data.pict ⇐ info→pw [i]; #ifndef notransient

XSetTransientForHint (display , pane→win→w, info→main win→w); #endif

{ XSizeHints size; size.flags ⇐ PMinSize; size.min width ⇐ 400; size.min height ⇐ 400; XSetStandardProperties (display , pane→win→w, pane→title, pane→title, icon pixmap, ⊙, 0, &size);

}

map window (pane→win); }

See also sections 26, 53, 54, 55, 56, 57, 58, and 60. This code is used in section 2.

25. ⟨ Global variable definitions 18 ⟩ +≡

event handler table outer handlers ⇐ { StructureNotifyMask , ⊙, ⊙, ⊙, ⊙, ⊙, ⊙, ⊙, outer configure };

26. The function map inner window is similar to map outer window , but the window it creates does not have the root window as parent, but rather the corresponding outer window, which is passed as a parameter pane. For this reason there is no need to inform the window manager about an icon or other special properties, or to declare the window transient. ⟨ Local function definitions 24 ⟩ +≡

local void map inner window

(p inner window win, p outer window pane, enum window type kind ) { int x ⇐ kind ≠ pict im win ? 20 : 20 + pane→width/2, y ⇐ bf height + 32;

unsigned int w ⇐ (kind = inner diag win ? pane→width : pane→width/2) − 24,

h ⇐ pane→height − (bf height + 32) − (bf height + 14); win→win ⇐ make window (kind , pane→win, x, y, w, h); map window (win→win); x −⇐ 20, w +⇐ 20; y ⇐ pane→height − bf height − 10, h ⇐ bf height + 6; win→com ⇐ make window (comment win, pane→win, x, y, w, h); win→com→data.inner ⇐ win; map window (win→com); ⟨ Install scroll bars 27 ⟩

8  DIAGRAM AND PICTURE WINDOW CREATION FUNCTIONS  WINDOWS §27

} 27. When we enter this module we still have the x value from the comment line. ⟨ Install scroll bars 27 ⟩ ≡

{ y ⇐ bf height + 12 + 20, w ⇐ 20, h ⇐ pane→height − (bf height + 20 + 12) − (bf height + 14); win→vert ⇐ create vert scrollbar (pane→win, win→win, x, y, w, h); win→vert →offset ⇐ 3 ∗ info→scale.box size; x +⇐ 20, y −⇐ 20, w ⇐ (kind = inner diag win ? pane→width : pane→width/2) − 24, h ⇐ 20; win→hor ⇐ create hor scrollbar (pane→win, win→win, x, y, w, h); win→hor →offset ⇐ 3 ∗ info→scale.box size;

}

This code is used in section 26.

28. This function resizes the inner window and its related sibling windows. ⟨ Global function declarations 19 ⟩ +≡

void resize inner window (p inner window, p outer window, enum window type);

29.

void resize inner window (p inner window win, p outer window pane, enum window type kind ) { int x ⇐ kind ≠ pict im win ? 0 : pane→width/2, y ⇐ pane→height − bf height − 10;

unsigned int w ⇐ (kind = inner diag win ? pane→width : pane→width/2) − 4, h ⇐ bf height + 6; XMoveResizeWindow (display , win→com→w, x, y, w, h); /∗ adjust comment line ∗/ x +⇐ 20, y ⇐ bf height + 32, w −⇐ 20, h ⇐ pane→height − (2 ∗ bf height + 46); XMoveResizeWindow (display , win→win→w, x, y, w, h); /∗ adjust inner window ∗/

}

30. ⟨ Global variable definitions 18 ⟩ +≡

event handler table inner handlers ⇐ { ExposureMask | EnterWindowMask | LeaveWindowMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask , inner expose, inner enter , inner leave, inner press , inner release, ⊙, inner move, ⊙ };

event handler table comment handlers ⇐ { ExposureMask , comment expose, ⊙, ⊙, ⊙, ⊙, ⊙, ⊙, ⊙ };

31. ⟨ Global function declarations 19 ⟩ +≡

void inner expose (win p);

32.

void inner expose (win p p) { if (p→type = inner diag win)

{ p diagram window dw ⇐ p→data.diag ; p inner window disp ⇐ &dw →disp;

print outline(p, dw →d, disp→hor →offset , disp→vert →offset ); } else { p picture window pw ⇐ p→data.pict ;

if (pw →p ≠ ⊙) print partial picture(pw );

else if (p→type = pict dom win) print complete domain(pw );

else print complete image(pw ); }

} 33. This function handles a mouseclick in an inner window. Which action actually is taken depends on the nature of the inner window and the location of the click relative to the diagram displayed in the window. ⟨ Global function declarations 19 ⟩ +≡

void inner press (win p, XButtonEvent∗);

34.

void inner press (win p p, XButtonEvent ∗xbutton) { if (p→type = inner diag win)

{ p diagram window dw ⇐ p→data.diag ; static void (∗f[ ]) (p diagram window, int, int) ⇐ { add square to diagram, remove br square from diagram, remove tl square from diagram,

add anti to diagram, query diagram }; if (xbutton→button = Button_{1}) (∗f[dw →mode])(dw , xbutton→x, xbutton→y);

} else { p picture window pw ⇐ p→data.pict ;

if (xbutton→button = Button_{1})

{ int i, j; logical coordinates (p→type = pict dom win ? &pw →d : &pw →i, xbutton→x, xbutton→y, &i, &j); if (pw →p ≠ ⊙ ∧ p→type = pict im win) add point to image(pw , xbutton→x, xbutton→y); else if (pw →p = ⊙) { if (inside(p→type = pict dom win ? pw →f→domain : pw →f→image, i, j))

if (p→type = pict dom win)

pw →d.m state ⇐ 1, query domain window (pw , xbutton→x, xbutton→y); else pw →i.m state ⇐ 1, query image window (pw , xbutton→x, xbutton→y);

else if (p→type = pict dom win) glissement domain window (pw , xbutton→x, xbutton→y); else glissement image window (pw , xbutton→x, xbutton→y);

} } else if (xbutton→button = Button_{3} ∧ pw →p = ⊙ ∧ pw →d.m state = 0 ∧ pw →i.m state = 0)

if (p→type = pict dom win) multiglissement domain window (pw , xbutton→x, xbutton→y); else multiglissement image window (pw , xbutton→x, xbutton→y);

} }

35. ⟨ Global function declarations 19 ⟩ +≡

void inner release (win p, XButtonEvent∗);

36.

void inner release (win p p, XButtonEvent ∗xbutton) { if (p→type = inner diag win)

{ p diagram window dw ⇐ p→data.diag ;

if (dw →mode = query mode) dw →disp.m state ⇐ 0, clear diagram query (dw ); } else { p picture window pw ⇐ p→data.pict ;

if (pw →d.m state = 3) pw →d.m state ⇐ 0, remove warning highlight (pw );

else if (pw →p = ⊙ ∧ (pw →d.m state ≠ 0 ∨ pw →i.m state ≠ 0))

pw →d.m state ⇐ pw →i.m state ⇐ 0, clear picture query (pw ); }

} 37. When the first button of the mouse is pressed in an inner window and it is moved, a motion event is created; this is relevant in query mode. ⟨ Global function declarations 19 ⟩ +≡

void inner move (win p, XMotionEvent∗);

38.

void inner move (win p p, XMotionEvent ∗xmotion)

{ if (p→type = inner diag win)

{ p diagram window dw ⇐ p→data.diag ;

if (dw →mode = query mode) moving diagram query (dw , xmotion→x, xmotion→y); } else { p picture window pw ⇐ p→data.pict ;

if (pw →p = ⊙)

if (p→type = pict dom win) moving domain query (pw , xmotion→x, xmotion→y); else moving image query (pw , xmotion→x, xmotion→y);

} }

39. To print a query, it first highlights the square in the diagram in which the mouse click occured and then displays an explainitory message in the diagram comment window. To query a picture, if the mouse click coordinates are within the diagram, the boxes’ coordinate strings are calculated. Then the box is highlighted and the string redisplayed. ⟨ Global function declarations 19 ⟩ +≡

void print diagram query (p diagram window, int, int); void query domain window (p picture window, int, int); void query image window (p picture window, int, int);

40.

void print diagram query (p diagram window dw , int i, int j)

{ int x, y; dw →disp.i ⇐ i; dw →disp.j ⇐ j; window coordinates (&dw →disp, i, j, &x, &y); highlight box (dw →disp.win, , x, y, info→scale.box size); sprintf (dw →disp.comment , ␣ ␣ ␣ ␣ ␣ ␣ ␣ , i, j,

inside(dw →d, i, j) ? ¬corner (dw →d, i, j, 0) ? ␣ ␣ : corner (dw →d, i, j, 1)

? corner (dw →d, i, j, −1) ? ␣        ␣  : ␣     ␣  : corner (dw →d, i, j, −1)
? ␣     ␣  : ␣     ␣  : ¬cocorner (dw →d, i, j, 0) ? ␣     ␣
: cocorner (dw →d, i, j, 1) ? cocorner (dw →d, i, j, −1) ? ␣ ␣

: ␣ ␣ : cocorner (dw →d, i, j, −1) ? ␣ ␣ : ␣ ␣ ); display message(dw →disp.com, dw →disp.comment , 15, bf height );

} 41.

void query domain window (p picture window pw , int x, int y) { int i, j;

logical coordinates (&pw →d, x, y, &i, &j); if (inside(pw →f→domain, i, j)) { point p ⇐ pict point (pw →f, i, j); char string [20], inv string [20];

if (info→scale.box size ≥ 40) sprintf (string ,  , p.i, p.j), sprintf (inv string ,  , i, j);
else if (info→scale.box size ≥ 20) sprintf (string ,  , p.j), sprintf (inv string ,  , j);

pw →d.i ⇐ i; pw →d.j ⇐ j; window coordinates (&pw →d, i, j, &x, &y); highlight box (pw →d.win, string , x, y, info→scale.box size); pw →i.i ⇐ p.i; pw →i.j ⇐ p.j; window coordinates (&pw →i, p.i, p.j, &x, &y); highlight box (pw →i.win, inv string , x, y, info→scale.box size);

} }

42.

void query image window (p picture window pw , int x, int y) { int i, j;

logical coordinates (&pw →i, x, y, &i, &j); if (inside(pw →f→image, i, j)) { char string [20], inv string [20]; pict p inv ⇐ inverse pict (pw →f);

point p ⇐ pict point (inv , i, j);

if (info→scale.box size ≥ 40) sprintf (string ,  , p.i, p.j), sprintf (inv string ,  , i, j);
else if (info→scale.box size ≥ 20) sprintf (string ,  , p.j), sprintf (inv string ,  , j);

pw →i.i ⇐ i; pw →i.j ⇐ j; window coordinates (&pw →i, i, j, &x, &y); highlight box (pw →i.win, string , x, y, info→scale.box size); pw →d.i ⇐ p.i; pw →d.j ⇐ p.j; window coordinates (&pw →d, p.i, p.j, &x, &y); highlight box (pw →d.win, inv string , x, y, info→scale.box size); del pict (inv );

} } 43. When the first mouse button is pressed, diagram query mode is set and you are within the printing window, whenever the mouse is moved an event occurs which executed this function. If the mouse is moved out of the current square, this square will be removed an the new square highlighted and the new comment displayed, except when the mouse is outside the printing window when the comment is not displayed.

⟨ Global function declarations 19 ⟩ +≡ void moving diagram query (p diagram window, int, int);

44.

void moving diagram query (p diagram window dw , int p, int q) { int i, j;

logical coordinates (&dw →disp, p, q, &i, &j); if (dw →disp.m state = 1 ∧ (dw →disp.i ≠ i ∨ dw →disp.j ≠ j)) { int x, y;

window coordinates (&dw →disp, dw →disp.i, dw →disp.j, &x, &y); remove highlighted box (dw →disp.win, , x, y, info→scale.box size); print origin cross (dw →disp.win, dw →disp.hor →offset , dw →disp.vert →offset ); window coordinates (&dw →disp, i, j, &x, &y); highlight box (dw →disp.win, , x, y, info→scale.box size); sprintf (dw →disp.comment ,

␣ ␣ ␣ ␣ ␣ ␣ ␣ , i, j, inside(dw →d, i, j)

? ¬corner (dw →d, i, j, 0) ? ␣ ␣ : corner (dw →d, i, j, 1) ? corner (dw →d, i, j, −1)

? ␣        ␣  : ␣     ␣  : corner (dw →d, i, j, −1) ? ␣     ␣
: ␣     ␣  : ¬cocorner (dw →d, i, j, 0) ? ␣     ␣  : cocorner (dw →d, i, j, 1)
? cocorner (dw →d, i, j, −1) ? ␣ ␣ : ␣ ␣

: cocorner (dw →d, i, j, −1) ? ␣ ␣ : ␣ ␣ ); dw →disp.i ⇐ i; dw →disp.j ⇐ j; XClearWindow (display , dw →disp.com→w); display message(dw →disp.com, dw →disp.comment , 15, bf height );

} } 45. When the first mouse button pressed, if the mouse pointer has moved out of the present square, that square is cleared and the corresponding query window function is called. ⟨ Global function declarations 19 ⟩ +≡

void moving domain query (p picture window, int, int); void moving image query (p picture window, int, int);

46.

void moving domain query (p picture window pw , int p, int q) { int i, j;

logical coordinates (&pw →d, p, q, &i, &j); if (pw →d.m state = 1 ∧ (pw →d.i ≠ i ∨ pw →d.j ≠ j)) { if (inside(pw →f→domain, i, j))

{ int x, y; window coordinates (&pw →d, pw →d.i, pw →d.j, &x, &y); remove highlighted box (pw →d.win, , x, y, info→scale.box size); window coordinates (&pw →i, pw →i.i, pw →i.j, &x, &y); remove highlighted box (pw →i.win, , x, y, info→scale.box size); print complete picture(pw ); query domain window (pw , p, q);

} }

}

47.

void moving image query (p picture window pw , int p, int q) { int i, j;

logical coordinates (&pw →i, p, q, &i, &j); if (pw →i.m state = 1 ∧ (pw →i.i ≠ i ∨ pw →i.j ≠ j)) { if (inside(pw →f→image, i, j))

{ int x, y; window coordinates (&pw →i, pw →i.i, pw →i.j, &x, &y); remove highlighted box (pw →i.win, , x, y, info→scale.box size); window coordinates (&pw →d, pw →d.i, pw →d.j, &x, &y); remove highlighted box (pw →d.win, , x, y, info→scale.box size); print complete picture(pw ); query image window (pw , p, q);

} }

} 48. To clear a diagram query, the comment is updated, and the disp.x and disp.y fields in the diagram structure are used to remove the highlighted square. For a picture, the query fields are used to clear both the highlighted squares and the complete picture is reprinted. ⟨ Global function declarations 19 ⟩ +≡

void clear diagram query (p diagram window); void clear picture query (p picture window);

49.

void clear diagram query (p diagram window dw ) { int x, y;

strcpy (dw →disp.comment , ␣ ); XClearWindow (display , dw →disp.com→w); print comment (&dw →disp); window coordinates (&dw →disp, dw →disp.i, dw →disp.j, &x, &y); remove highlighted box (dw →disp.win, , x, y, info→scale.box size); print origin cross (dw →disp.win, dw →disp.hor →offset , dw →disp.vert →offset );

}

50.

void clear picture query (p picture window pw ) { int x, y;

window coordinates (&pw →d, pw →d.i, pw →d.j, &x, &y);

remove highlighted box (pw →d.win, , x, y, info→scale.box size);

window coordinates (&pw →i, pw →i.i, pw →i.j, &x, &y);

remove highlighted box (pw →i.win, , x, y, info→scale.box size); print complete picture(pw ); }

51. ⟨ Global function declarations 19 ⟩ +≡

void set warning hightlight (p picture window); void remove warning highlight (p picture window);

52.

void set warning hightlight (p picture window pw ) { int x, y; char coords [20];

sprintf (coords , , pw →i.i, pw →i.j); window coordinates (&pw →d, pw →d.i, pw →d.j, &x, &y); highlight box (pw →d.win, coords , x, y, info→scale.box size); window coordinates (&pw →i, pw →i.i, pw →i.j, &x, &y); highlight box (pw →i.win, , x, y, info→scale.box size);

} void remove warning highlight (p picture window pw ) { int x, y; char coords [20];

sprintf (coords , , pw →i.i, pw →i.j); window coordinates (&pw →d, pw →d.i, pw →d.j, &x, &y); remove highlighted box (pw →d.win, coords , x, y, info→scale.box size); window coordinates (&pw →i, pw →i.i, pw →i.j, &x, &y); remove highlighted box (pw →i.win, , x, y, info→scale.box size);

}

§53  WINDOWS  AUXILIARY FUNCTIONS FOR THE INNER WINDOW 15

53. Auxiliary functions for the inner window. The following functions help implement the actions described above. ⟨ Local function definitions 24 ⟩ +≡

local void add square to diagram (p diagram window dw , int x, int y) { int i, j;

logical coordinates (&dw →disp, x, y, &i, &j); close diagram(&dw →d, i, j);

print outline(dw →disp.win, dw →d, dw →disp.hor →offset , dw →disp.vert →offset ); }

54. This is the function that removes the square under the mouse pointer and the removes all other other squares below and to the right (or above and to the left), to maintain the diagram properties. ⟨ Local function definitions 24 ⟩ +≡

local void remove br square from diagram (p diagram window dw , int x, int y) { int i, j;

logical coordinates (&dw →disp, x, y, &i, &j); remove square(&dw →d, i, j, 1);

XClearWindow (display , dw →disp.win→w);

print outline(dw →disp.win, dw →d, dw →disp.hor →offset , dw →disp.vert →offset ); }

55. ⟨ Local function definitions 24 ⟩ +≡

local void remove tl square from diagram (p diagram window dw , int x, int y) { int i, j;

logical coordinates (&dw →disp, x, y, &i, &j); remove square(&dw →d, i, j, −1);

XClearWindow (display , dw →disp.win→w);

print outline(dw →disp.win, dw →d, dw →disp.hor →offset , dw →disp.vert →offset ); }

56. This function calculates the anti-diagonal on which the mouse pointer was clicked and fills this diagonal in the positive quadrent and all the other squares required to maintain the diagrams properties. ⟨ Local function definitions 24 ⟩ +≡

local void add anti to diagram (p diagram window dw , int x, int y) { int i; int diagonal ⇐ calculate diagonal (dw , x, y);

if (diagonal ≥ 0)

{ for (i ⇐ 0; i ≤ diagonal ; ^{++}i) close diagram(&dw →d, i, diagonal − i);

print outline(dw →disp.win, dw →d, dw →disp.hor →offset , dw →disp.vert →offset ); }

}

57. This function displays information about the square under the mouse click. ⟨ Local function definitions 24 ⟩ +≡

local void query diagram (p diagram window dw , int x, int y) { int i, j;

16  TO ADD A POINT TO THE IMAGE  WINDOWS §58

dw →disp.m state ⇐ 1; logical coordinates (&dw →disp, x, y, &i, &j); print diagram query (dw , i, j); } 58. To add a point to the image. This function adds a point to the image if possible. The point is sent to the add image function and depending on what returns on whether it is added or what comment is displayed. If after adding the image the picture is complete the picture structure is moved from the partial picture and the complete picture is displayed. ⟨ Local function definitions 24 ⟩ +≡

local void add point to image (p picture window pw , int x, int y) { if (¬pw →p→complete)

{ int i, j, e; logical coordinates (&pw →i, x, y, &i, &j); e ⇐ add image(pw →p, i, j); ⟨ Check if adding coordinate to image is valid 59 ⟩

} if (pw →p→complete) { pw →f ⇐ pw →p→f; free(pw →p); pw →p ⇐ ⊙; strcpy (pw →i.comment , );

XClearWindow (display , pw →i.com→w); strcpy (pw →d.comment , ␣ ); print comment (&pw →d); XClearWindow (display , pw →d.win→w); print complete picture(pw );

} }

59. This module checks the validity of the coordinated trying to by added to the image of a partial picture. If these coordinates are valid then the square is added to the image else an error message is displayed in the comment window of the picture. ⟨ Check if adding coordinate to image is valid 59 ⟩ ≡

{ if (e = 0) /∗ valid addition ∗/

{ strcpy (pw →i.comment , ); XClearWindow (display , pw →i.com→w);

XClearWindow (display , pw →d.win→w); print partial picture(pw ); } else if (e = 1) /∗ backward morphism condition violated ∗/ { char string [80];

sprintf (string , ␣ ␣ ␣ ␣ ␣ ␣ ␣ , i, j); XClearWindow (display , pw →i.com→w); display message(pw →i.com, string , 15, bf height ); XBell (display , 100);

} else /∗ forward morphism condition violated ∗/ { point ∗loc; char ∗dir ; char string [80];

pw →d.i ⇐ pw →p→i, pw →d.j ⇐ pw →p→j; if (e = 2) ^{−}pw →d.j, dir ⇐ ␣ ␣ ␣ ; else ^{++}pw →d.i, dir ⇐ ; loc ⇐ &pict point (pw →p→f, pw →d.i, pw →d.j); pw →i.i ⇐ loc→i, pw →i.j ⇐ loc→j; sprintf (string , ␣ ␣ ␣ ␣ ␣ , i, j, dir , loc→i, loc→j); XClearWindow (display , pw →i.com→w); display message(pw →i.com, string , 15, bf height ); set warning hightlight (pw ), pw →d.m state ⇐ 3; XBell (display , 100);

} }

This code is used in section 58.

§60  WINDOWS  TO ADD A POINT TO THE IMAGE 17

60. This function creates the icon that appears in the main window to show that a diagram or picture window is present and whether that window is iconised and/or selected.

⟨ Local function definitions 24 ⟩ +≡ void map window icon (p outer window pane, enum window type kind , int n) { int half w ⇐ window width/2, x ⇐ kind = diag icon win ? 0 : half w ,

y ⇐ (bf height + 12) ∗ (n + 2) + 10; unsigned int w ⇐ half w − 4, h ⇐ bf height + 10;

pane→icon ⇐ make window (kind , info→main win, x, y, w, h); pane→icon→data.nr ⇐ n; map window (pane→icon);

}

61.

⟨ Global variable definitions 18 ⟩ +≡

event handler table icon handlers ⇐ { ExposureMask | ButtonPressMask , icon expose, ⊙, ⊙, icon press , ⊙, ⊙, ⊙, ⊙ }; 62. When an icon is removed or inserted, we need to adjust the positions of the ones below it. We compute the new location of an icon in an absolute rather than relative way, since the old position is not recorded. However, the function adjust icons assumes that icons numbered up to and including loc are all present and positioned correctly (in case of doubt use loc = 0). Icons of windows that have been removed are treated as if they were still present (and in fact they only have been unmapped) at the position where they would reappear if they were reused now, however we don’t advance the position loc so that no gap will be visible. ⟨ Global function declarations 19 ⟩ +≡

void adjust icons (enum window type, int);

63.

void adjust icons (enum window type kind , int loc) { int i, x ⇐ kind = inner diag win ? 0 : window width/2,

n ⇐ kind = inner diag win ? diagram limit : picture limit ; for (i ⇐ loc; i < n; ^{++}i)

if (kind = inner diag win ? info→dw [i] ≠ ⊙ : info→pw [i] ≠ ⊙) { p outer window pane ⇐ kind = inner diag win ? &info→dw [i]→pane : &info→pw [i]→pane;

int y ⇐ (bf height + 12) ∗ (loc + 2) + 10; XMoveWindow (display , pane→icon→w, x, y); if (pane→visibility ≠ removed ) ^{++}loc;

} }

64. The function new diagram window creates and initialises (you guessed it) a new diagram window, and returns its index in info→dw , or −1 on failure. ⟨ Global function declarations 19 ⟩ +≡

int new diagram window (void);

65.

int new diagram window (void) { int i;

for (i ⇐ 0; i < diagram limit ; ^{++}i) if (info→dw [i] = ⊙ ∨ info→dw [i]→pane.visibility = removed ) { static struct diagram window ini ⇐ ⟨ Initialiser for diagram window 11 ⟩ ;

p diagram window dw ⇐ info→dw [i]; ++info→num diags ; if (dw = ⊙) /∗ then create a fresh window ∗/ { ∗(dw ⇐ info→dw [i] ⇐ new (struct diagram window )) ⇐ ini ;

map outer window (&dw →pane, outer diag win, i);

dw →pane.mb ⇐ create diag menus (dw →pane.win, dw →pane.width);

map inner window (&dw →disp, &dw →pane, inner diag win);

dw →disp.win→data.diag ⇐ dw ; map window icon(&dw →pane, diag icon win, i); } else /∗ reuse a used window ∗/ { map window (dw →pane.win); map window (dw →pane.icon); /∗ remap window ∗/

dw →pane.visibility ⇐ visible; } strcpy (dw →disp.comment , ␣ ); dw →mode ⇐ add mode; adjust icons (inner diag win, i + 1); return i;

} return −1;

} 66. The function new picture window is used when a new picture is being created; the may be either because one is generated from a diagram, or because a new complete picture is produced either by duplication or by computation (the Robinson-Schensted algorithm). For since the object needs to be present when the new window is mapped it is supplied as an argument, and rather than making a discriminated union of a diagram and a picture we supply pointers to both, with the convention that the unintended one is ⊙. In case both arguments are ⊙ we behave as if a complete (but empty) picture was created. ⟨ Global function declarations 19 ⟩ +≡

int new picture window (diag p, pict p);

67. The actions are similar to those of new diagram window , but some are doubled.

int new picture window (diag p d, pict p f) { int i;

for (i ⇐ 0; i < picture limit ; ^{++}i) if (info→pw [i] = ⊙ ∨ info→pw [i]→pane.visibility = removed ) { static struct picture window ini ⇐ ⟨ Initialiser for picture window 13 ⟩ ;

p picture window pw ⇐ info→pw [i]; ++info→num picts ; if (pw = ⊙) /∗ then create a fresh window ∗/ { ∗(pw ⇐ info→pw [i] ⇐ new (struct picture window )) ⇐ ini ;

map outer window (&pw →pane, outer pict win, i);

pw →pane.mb ⇐ create pict menus (pw →pane.win, pw →pane.width);

map inner window (&pw →d, &pw →pane, pict dom win); pw →d.win→data.pict ⇐ pw ; map inner window (&pw →i, &pw →pane, pict im win); pw →i.win→data.pict ⇐ pw ; map window icon(&pw →pane, pict icon win, i);

} else /∗ reuse a used window ∗/ { map window (pw →pane.win); map window (pw →pane.icon); /∗ remap window ∗/

pw →pane.visibility ⇐ visible; } if (d ≠ ⊙) { strcpy (pw →d.comment , ␣ );

setup new pict (pw →p ⇐ new (part pict), dup diag (d)); } else { strcpy (pw →d.comment , ␣ ); pw →f ⇐ f; } adjust icons (pict dom win, i + 1); return i;

} return −1;

} 68. These functions map an iconised window, therefore making it visible and usable. Finally it updates the icon graphics by removing the tick icon. ⟨ Global function declarations 19 ⟩ +≡

void deiconise diagram window (p diagram window); void deiconise picture window (p picture window);

69.

void deiconise diagram window (p diagram window dw ) { map window (dw →pane.win); dw →pane.visibility ⇐ visible;

XClearArea(display , dw →pane.icon→w, window width/4, 0, window width/4, bf height + 12, false); display icon graphics (dw →pane.icon, dw →pane.title, visible);

}

70.

void deiconise picture window (p picture window pw ) { map window (pw →pane.win); pw →pane.visibility ⇐ visible;

XClearArea(display , pw →pane.icon→w, window width/4, 0, window width/4, bf height + 12, false); display icon graphics (pw →pane.icon, pw →pane.title, visible);

§71  WINDOWS  INDEX 21

} 71. Index.

add anti to diagram: 34, \underline{56}. add image: 58. add mode: \underline{10}, 11, 65. add point to image: 34, \underline{58}. add square to diagram: 34, \underline{53}. adjust icons : \underline{62}, \underline{63}, 65, 67. anti diagonal mode: \underline{10}. base window : 22. bf height : 22, 26, 27, 29, 40, 44, 59, 60, 63, 69, 70. bool: 14, 16. box size: \underline{14}, 27, 40, 41, 42, 44, 46, 47, 49, 50, 52. bs string : \underline{14}. bs win: \underline{14}, 22. button: 34. ButtonPressMask : 23, 30, 61. ButtonReleaseMask : 30. Button_{1}: 34. Button1MotionMask : 30. Button_{3}: 34. calculate diagonal : 56. clear diagram query : 36, \underline{48}, \underline{49}. clear picture query : 36, \underline{48}, \underline{50}. close diagram: 53, 56. cocorner : 40, 44. com: \underline{7}, 26, 29, 40, 44, 49, 58, 59. comment : \underline{7}, 40, 44, 49, 58, 59, 65, 67. comment expose: 30. comment handlers : \underline{30}. comment win: 26. complete: 58. coords : \underline{52}. corner : 40, 44. create diag menus : 65. create hor scrollbar : 27. create main menus : 20. create pict menus : 67. create vert scrollbar : 27. d: \underline{9}, \underline{12}, \underline{67}. data: 24, 26, 32, 34, 36, 38, 60, 65, 67. deiconise diagram window : \underline{68}, \underline{69}. deiconise picture window : \underline{68}, \underline{70}. del pict : 42. diag : 24, 32, 34, 36, 38, 65. diag icon win: 60, 65. diag p: 9, 66, 67. diagonal : \underline{56}. diagram: 9. diagram limit : 4, 16, 63, 65. : \underline{24}. : \underline{24}. diagram window : \underline{9}, 65. diagram window modes : 9, 10. dir : \underline{59}. disp: \underline{9}, \underline{32}, 36, 40, 44, 48, 49, 53, 54, 55, 56, 57, 65. display : 22, 24, 29, 44, 49, 54, 55, 58, 59, 63, 69, 70. display icon graphics : 69, 70. display message: 40, 44, 59. domain: 34, 41, 46. dup diag : 67. dw : \underline{16}, 24, \underline{32}, \underline{34}, \underline{36}, \underline{38}, \underline{40}, \underline{44}, \underline{49}, \underline{53}, \underline{54},

\underline{55}, \underline{56}, \underline{57}, 63, 64, \underline{65}, \underline{69}.

e: \underline{58}.

EnterWindowMask : 23, 30.

event handler table: 18, 23, 25, 30, 61.

ExposureMask : 18, 23, 30, 61.

f: \underline{12}, \underline{34}, \underline{67}.

false: 15, 17, 69, 70.

flags : 22, 24. free: 58. glissement domain window : 34. glissement image window : 34. h: \underline{26}, \underline{29}, \underline{60}. half w : \underline{60}. height : \underline{5}, 20, 24, 26, 27, 29. help expose: 23. help handlers : \underline{23}. help mapped : \underline{16}. help press : 23. help win: \underline{16}, 22. : \underline{21}, 22. : \underline{21}, 22. highlight box : 40, 41, 42, 44, 52. hor : \underline{7}, 27, 32, 44, 49, 53, 54, 55, 56. i: \underline{7}, \underline{12}, \underline{24}, \underline{34}, \underline{40}, \underline{41}, \underline{42}, \underline{44}, \underline{46}, \underline{47}, \underline{53}, \underline{54},

\underline{55}, \underline{56}, \underline{57}, \underline{58}, \underline{63}, \underline{65}, \underline{67}.

icon: \underline{5}, 60, 63, 65, 67, 69, 70.

icon expose: 61. icon handlers : \underline{61}. icon pixmap: 22, 24. icon press : 61. iconised : \underline{5}. image: 34, 42, 47. info: 20, 21, 22, 24, 27, 40, 41, 42, 44, 46, 47,

49, 50, 52, 60, 63, 64, 65, 67. ini : \underline{22}, \underline{65}, \underline{67}. init main data: \underline{21}, \underline{22}. inner : 26. inner diag win: 26, 27, 29, 32, 34, 36, 38, 63, 65. inner enter : 30. inner expose: 30, \underline{31}, \underline{32}. inner handlers : \underline{30}. inner leave: 30.

22  INDEX  WINDOWS §71

inner move: 30, \underline{37}, \underline{38}. inner press : 30, \underline{33}, \underline{34}. inner release: 30, \underline{35}, \underline{36}. inner window : \underline{7}, 9, 12. inside: 34, 40, 41, 42, 44, 46, 47. inv : \underline{42}. inv string : \underline{41}, \underline{42}. inverse pict : 42. j: \underline{7}, \underline{34}, \underline{40}, \underline{41}, \underline{42}, \underline{44}, \underline{46}, \underline{47}, \underline{53}, \underline{54}, \underline{55}, \underline{57}, \underline{58}. KeyPressMask : 23. kind : \underline{26}, 27, \underline{29}, \underline{60}, \underline{63}. LeaveWindowMask : 23, 30. loc: \underline{59}, 62, \underline{63}. local: \underline{2}. logical coordinates : 34, 41, 42, 44, 46, 47, 53,

54, 55, 57, 58. m bar : 5, 16. m state: \underline{7}, 34, 36, 44, 46, 47, 57, 59. main configure: 18, \underline{19}, \underline{20}. main expose: 18, 19. main handlers : \underline{18}. main win: \underline{16}, 20, 22, 24, 60. main window : \underline{16}, 22. make window : 22, 24, 26, 60. map inner window : \underline{26}, 65, 67. map outer window : \underline{24}, 26, 65, 67. map window : 22, 24, 26, 60, 65, 67, 69, 70. map window icon: \underline{60}, 65, 67. mapped : \underline{14}, 16. max comment length: 4, 7. max height : 22. max title length: 4, 5. max width: 22. mb: \underline{5}, \underline{16}, 20, 65, 67. min height : 22, 24. min width: 22, 24. mode: \underline{9}, 34, 36, 38, 65. moving diagram query : 38, \underline{43}, \underline{44}. moving domain query : 38, \underline{45}, \underline{46}. moving image query : 38, \underline{45}, \underline{47}. multiglissement domain window : 34. multiglissement image window : 34. n: \underline{60}, \underline{63}. new : 22, 65, 67. new diagram window : \underline{64}, \underline{65}, 67. new picture window : \underline{66}, \underline{67}. notransient : 24. nr : 60. num diags : \underline{16}, 65. num picts : \underline{16}, 67. offset : 27, 32, 44, 49, 53, 54, 55, 56. outer configure: 25. outer diag win: 24, 65. outer handlers : \underline{25}. outer pict win: 67. outer window : \underline{5}, 7, 9, 12. p: \underline{12}, \underline{20}, \underline{32}, \underline{34}, \underline{36}, \underline{38}, \underline{41}, \underline{42}, \underline{44}, \underline{46}, \underline{47}. p diagram window: 16, 32, 34, 36, 38, 39, 40, 43, 44, 48, 49, 53, 54, 55, 56, 57, 65, 68, 69.

p inner window: 26, 28, 29, 32.

p outer window: 24, 26, 28, 29, 60, 63.

p picture window: 16, 32, 34, 36, 38, 39, 41, 42, 45, 46, 47, 48, 50, 51, 52, 58, 67, 68, 70. pane: \underline{9}, \underline{12}, \underline{24}, \underline{26}, 27, \underline{29}, \underline{60}, \underline{63}, 65, 67, 69, 70. part pict: 12, 67. pict : 24, 32, 34, 36, 38, 67. pict dom win: 32, 34, 38, 67. pict icon win: 67. pict im win: 26, 29, 34, 67. pict p: 12, 42, 66, 67. pict point : 41, 42, 59. picture: 12. picture limit : 4, 16, 63, 67. : \underline{24}. : \underline{24}. picture window : \underline{12}, 67. PMaxSize: 22. PMinSize: 22, 24. point: 41, 42, 59. print comment : 49, 58. print complete domain: 32. print complete image: 32. print complete picture: 46, 47, 50, 58. print diagram query : \underline{39}, \underline{40}, 57. print origin cross : 44, 49. print outline: 32, 53, 54, 55, 56. print partial picture: 32, 59. pw : \underline{16}, 24, \underline{32}, \underline{34}, \underline{36}, \underline{38}, \underline{41}, \underline{42}, \underline{46}, \underline{47}, \underline{50},

\underline{52}, \underline{58}, 59, 63, \underline{67}, \underline{70}.

q: \underline{44}, \underline{46}, \underline{47}.

query diagram: 34, \underline{57}.

query domain window : 34, \underline{39}, \underline{41}, 46. query image window : 34, \underline{39}, \underline{42}, 47. query mode: \underline{10}, 36, 38. remove br mode: \underline{10}. remove br square from diagram: 34, \underline{54}. remove highlighted box : 44, 46, 47, 49, 50, 52. remove square: 54, 55. remove tl mode: \underline{10}. remove tl square from diagram: 34, \underline{55}. remove warning highlight : 36, \underline{51}, \underline{52}. removed : \underline{5}, 63, 65, 67. resize inner window : \underline{28}, \underline{29}. root window : 22, 24. scale: \underline{16}, 22, 27, 40, 41, 42, 44, 46, 47, 49, 50, 52. scale entry enter : 23. scale entry expose: 23. scale entry handlers : \underline{23}. scale entry key : 23. scale entry leave: 23. scale entry win: 22. scale expose: 23. scale handlers : \underline{23}. scale press : 23. scale win: 22. scale window: \underline{14}, 16. : \underline{21}, 22. : \underline{21}, 22. scrollbar : 7. sel diag : \underline{16}. sel pict : \underline{16}. set warning hightlight : \underline{51}, \underline{52}, 59. setup new pict : 67. size: \underline{22}, \underline{24}. sprintf : 24, 40, 41, 42, 44, 52, 59. strcpy : 49, 58, 59, 65, 67. string : \underline{41}, \underline{42}, \underline{59}. StructureNotifyMask : 18, 25. t: \underline{24}. title: \underline{5}, 24, 69, 70. type: 32, 34, 36, 38. vert : \underline{7}, 27, 32, 44, 49, 53, 54, 55, 56. visibility : \underline{5}, 63, 65, 67, 69, 70. visible: \underline{5}, 6, 65, 67, 69, 70. w: \underline{26}, \underline{29}, \underline{60}. width: \underline{5}, 20, 24, 26, 27, 29, 65, 67. win: \underline{5}, \underline{7}, \underline{14}, 22, 24, \underline{26}, 27, \underline{29}, 40, 41, 42,

44, 46, 47, 49, 50, 52, 53, 54, 55, 56, 58, 59, 65, 67, 69, 70.

win p: 5, 6, 7, 14, 16, 19, 20, 31, 32, 33, 34,

35, 36, 37, 38. window coordinates : 40, 41, 42, 44, 46, 47,

49, 50, 52. window height : 20. window type: 24, 26, 28, 29, 60, 62, 63. window width: 20, 60, 63, 69, 70. x: \underline{26}, \underline{29}, \underline{40}, \underline{41}, \underline{42}, \underline{44}, \underline{46}, \underline{47}, \underline{49}, \underline{50}, \underline{52}, \underline{53},

\underline{54}, \underline{55}, \underline{56}, \underline{57}, \underline{58}, \underline{60}, \underline{63}. XBell : 59. xbutton: \underline{34}, \underline{36}. XButtonEvent: 33, 34, 35, 36. XClearArea: 69, 70. XClearWindow : 44, 49, 54, 55, 58, 59. xconfig : \underline{20}. XConfigureEvent: 19, 20. xmotion: \underline{38}.

XMotionEvent: 37, 38. XMoveResizeWindow : 29. XMoveWindow : 63. XSetStandardProperties : 22, 24. XSetTransientForHint : 24. XSizeHints: 22, 24. y: \underline{26}, \underline{29}, \underline{40}, \underline{41}, \underline{42}, \underline{44}, \underline{46}, \underline{47}, \underline{49}, \underline{50}, \underline{52}, \underline{53},

\underline{54}, \underline{55}, \underline{56}, \underline{57}, \underline{58}, \underline{60}, \underline{63}.

⟨ Check if adding coordinate to image is valid 59 ⟩ Used in section 58. ⟨ Global constant and macro definitions 4, 10 ⟩ Used in section 3.

⟨ Global function declarations 19, 21, 28, 31, 33, 35, 37, 39, 43, 45, 48, 51, 62, 64, 66, 68 ⟩ Used in section 3. ⟨ Global typedefs 5, 7, 9, 12, 14, 16 ⟩ Used in section 3. ⟨ Global variable definitions 18, 23, 25, 30, 61 ⟩ Used in section 2.

⟨ Initialiser for diagram window 11 ⟩ Used in section 65. ⟨ Initialiser for inner window 8 ⟩ Used in sections 11 and 13. ⟨ Initialiser for main window structure 17 ⟩ Used in section 22. ⟨ Initialiser for outer window 6 ⟩ Used in sections 11 and 13. ⟨ Initialiser for picture window 13 ⟩ Used in section 67. ⟨ Initialiser for scale structure 15 ⟩ Used in section 17. ⟨ Install scroll bars 27 ⟩ Used in section 26.

⟨ Local function definitions 24, 26, 53, 54, 55, 56, 57, 58, 60 ⟩ Used in section 2.

⟨ 3 ⟩

WINDOWS

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 The main window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 5 Diagram and Picture window creation functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7 Auxiliary functions for the inner window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 15 To add a point to the image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 16 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 21