1 /*
2  * @(#)menu.c	1.2  01/03/85
3  *
4  * Menu subwindow routines for the SUN Gremlin picture editor.
5  *
6  * Mark Opperman (opcode@monet.BERKELEY)
7  *
8  */
9 
10 #include <suntool/tool_hs.h>
11 #include <suntool/menu.h>
12 #include <errno.h>
13 #include "gremlin.h"
14 #include "icondata.h"
15 
16 /* imports from graphics.c */
17 
18 extern GRCurrentSetOn();
19 
20 /*  imports from short.c */
21 
22 extern int adj[];
23 
24 /* imports from text.c */
25 
26 extern TxMsgOK();
27 
28 /* imports from sun.c */
29 
30 extern pw_box();
31 
32 /* imports from main.c */
33 
34 extern Artmode;			/* type of point layed down */
35 extern Adjustment;
36 extern Alignment;
37 extern GravityOn;
38 extern menu_fd;
39 extern struct pixfont *text_pf;
40 extern struct rect menu_size;
41 extern ELT *MEN[];
42 extern SymbolicLines;
43 extern FLASH_READY;
44 
45 extern (*lastcommand)();	/* previous command */
46 extern lasttext;		/* TRUE if previous cmd uses text input */
47 
48 /* forward references */
49 
50 extern align_up();
51 extern align_down();
52 
53 
54 #define M_CLEAR_POINTS (caddr_t) 1
55 #define M_SHOW_POINTS (caddr_t) 2
56 #define M_GRIPE (caddr_t) 3
57 #define M_POINT (caddr_t) 4
58 
59 struct menuitem misc_items[] = {
60     { MENU_IMAGESTRING, "Clear Points", M_CLEAR_POINTS},
61     { MENU_IMAGESTRING, "Show Points", M_SHOW_POINTS},
62     { MENU_IMAGESTRING, "Gripe", M_GRIPE},
63     { MENU_IMAGESTRING, "Point", M_POINT}
64 };
65 
66 struct menu misc_menu = {
67     MENU_IMAGESTRING, "Misc",
68     sizeof(misc_items) / sizeof(struct menuitem), misc_items, 0, 0
69 };
70 
71 struct menu *misc_menu_stack = &misc_menu;
72 
73 #define M_EDIT (caddr_t) 1
74 #define M_PATH (caddr_t) 2
75 #define M_READ (caddr_t) 3
76 #define M_SAVE_SET (caddr_t) 4
77 #define M_WRITE (caddr_t) 5
78 
79 struct menuitem file_items[] = {
80     { MENU_IMAGESTRING, "Edit", M_EDIT},
81     { MENU_IMAGESTRING, "Path", M_PATH},
82     { MENU_IMAGESTRING, "Read", M_READ},
83     { MENU_IMAGESTRING, "Save Set", M_SAVE_SET},
84     { MENU_IMAGESTRING, "Write", M_WRITE}
85 };
86 
87 struct menu file_menu = {
88     MENU_IMAGESTRING, "File",
89     sizeof(file_items) / sizeof(struct menuitem), file_items, 0, 0
90 };
91 
92 struct menu *file_menu_stack = &file_menu;
93 
94 int icon_x, icon_y;	/* location of currently selected menu icon */
95 int icon_last = -1;	/* menu index of currently selected menu icon */
96 int just_x, just_y;	/* location of justify marker within justify icon */
97 int just_last = -1;	/* justify index of currently selected mode */
98 struct pixrect *save_just_pr;
99 
100 #define MNReverseJustify()  pw_write(menu_pw, just_x + 1, just_y, 5, 5, \
101 		     PIX_SRC ^ PIX_DST, &dot_pr, 0, 0)
102 
103 /* imports from main.c */
104 
105 extern struct pixwin *menu_pw;
106 extern struct toolsw *menu_sw;
107 extern CFONT;
108 extern CSIZE;
109 extern CJUST;
110 extern CBRUSH;
111 extern CSTIPPLE;
112 
113 /* imports from help.c */
114 
115 extern justify_help(), help(), horizontal_help(), vertical_help(),
116        size1_help(), size2_help(), size3_help(), size4_help(),
117        roman_help(), italics_help(), bold_help(), special_help(),
118        scale_help(), move_help(), hmirror_help(), vmirror_help(),
119        include_help(), linestyle_help(), align_help(), pan_help(),
120        polygon_help(), bpolygon_help(),
121        get1_help(), get2_help(), get3_help(), get4_help(),
122        put1_help(), put2_help(), put3_help(), put4_help(),
123        brush1_help(), brush2_help(), brush3_help(),
124        brush4_help(), brush5_help(), brush6_help(),
125        stipple1_help(), stipple2_help(), stipple3_help(), stipple4_help(),
126        stipple5_help(), stipple6_help(), stipple7_help(), stipple8_help(),
127        copy_help(), arrow_help(), text_help(), misc_help(), undo_help(),
128        erase_help(), movepoint_help(), rotate_help(), filecabinet_help(),
129        boxinc_help(), manhattan_help(), gravity_help(), arc_help(),
130        curve_help(), vector_help(), box_help(), grid_help(),
131        littlepoint_help(), menusw_help();
132 
133 /* imports from sunlong.c */
134 
135 extern LGBrush1(), LGBrush2(), LGBrush3(),
136        LGBrush4(), LGBrush5(), LGBrush6(),
137        LGClearPoints(), LGPath(), LGEdit(),
138        LGFont1(), LGFont2(), LGFont3(), LGFont4(),
139        LGGet1(), LGGet2(), LGGet3(), LGGet4(),
140        LGGripe(), LGHMirror(),
141        LGHAdjust(), LGIncludeSet(), LGLineStyle(), LGLittlePoint(),
142        LGMBrush1(), LGMBrush2(), LGMBrush3(),
143        LGMBrush4(), LGMBrush5(), LGMBrush6(), LGMCurve(),
144        LGMFont1(), LGMFont2(), LGMFont3(), LGMFont4(),
145        LGMJustify(), LGMPan(),
146        LGMSize1(), LGMSize2(), LGMSize3(), LGMSize4(),
147        LGMStipple1(), LGMStipple2(), LGMStipple3(), LGMStipple4(),
148        LGMStipple5(), LGMStipple6(), LGMStipple7(), LGMStipple8(),
149        LGMText(), LGMPoint(), LGMVector(), nop(), LGPan(),
150        LGPolygon(), LGBPolygon(), LGMPolygon(), LGMBPolygon(),
151        LGOPoint(), LGRead(), LGSave(), LGShowPoints(),
152        LGSize1(), LGSize2(), LGSize3(), LGSize4(),
153        LGStipple1(), LGStipple2(), LGStipple3(), LGStipple4(),
154        LGStipple5(), LGStipple6(), LGStipple7(), LGStipple8(),
155        LGText(), LGUndo(), LGVAdjust(), LGVMirror(), LGWrite();
156 
157 
158 /* imports from short.c */
159 
160 extern SHArrow(), SHBox(), SHCopy(), SHDefineSet(), SHDrawArc(), SHDrawCurve(),
161        SHDrawVector(), SHErase(), SHGravity(), SHGrid(), SHMAdjust(),
162        SHSave1(), SHSave2(), SHSave3(), SHSave4(),
163        SHRotate(), SHScale(), SHSetArea(), SHMSetArea(), SHTranslate();
164 
165 /* imports from suntools */
166 
167 extern struct menuitem *menu_display();
168 
169 /* justify_mark marks the text handle positions for the JUSTIFY icon
170    relative to the icon's upper left corner */
171 
172 struct pr_pos justify_mark[9];
173 
174 /* just_to_indx maps the justification values (TOPLEFT, ..., BOTRIGHT)
175    to the corresponding index in the justify_mark array */
176 
177 int just_to_indx[] = { 6, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 5, 7 };
178 
179 /* indx_to_just maps the internal justification values (0, ..., 8)
180    to the gremlin justification values (TOPLEFT, ..., BOTRIGHT) */
181 
182 int indx_to_just[] = { TOPLEFT, TOPCENT, TOPRIGHT,
183 		       CENTLEFT, CENTCENT, CENTRIGHT,
184 		       BOTLEFT, BOTCENT, BOTRIGHT };
185 
186 struct _menu menu[] = {
187 #define M_SIZE1 0
188     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
189       MENU_TOP +  ICON_BORDER + MENU_Y * 1, &size1_pr,
190       LGSize1, LGMSize1, size1_help },
191 
192 #define M_ROMAN (M_SIZE1+1)
193     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
194       MENU_TOP  + ICON_BORDER + MENU_Y * 2, &roman_pr,
195       LGFont1, LGMFont1, roman_help },
196 
197 #define M_JUSTIFY (M_ROMAN+1)
198     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
199       MENU_TOP  + ICON_BORDER + MENU_Y * 1, &justify_pr,
200       nop, nop, nop },
201 
202 #define M_SCALE (M_JUSTIFY+1)
203     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
204       MENU_TOP  + ICON_BORDER + MENU_Y * 9, &scale_pr,
205       SHScale, nop, scale_help },
206 
207 #define M_TRANSLATE (M_SCALE+1)
208     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
209       MENU_TOP  + ICON_BORDER + MENU_Y * 8, &move_pr,
210       SHTranslate, nop, move_help },
211 
212 #define M_HMIRROR (M_TRANSLATE+1)
213     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
214       MENU_TOP  + ICON_BORDER + MENU_Y * 11, &hmirror_pr,
215       LGHMirror, nop, hmirror_help },
216 
217 #define M_VMIRROR (M_HMIRROR+1)
218     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
219       MENU_TOP  + ICON_BORDER + MENU_Y * 11, &vmirror_pr,
220       LGVMirror, nop, vmirror_help },
221 
222 #define M_DEFINE_SET (M_VMIRROR+1)
223     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
224       MENU_TOP  + ICON_BORDER + MENU_Y * 14, &include_pr,
225       SHDefineSet, LGIncludeSet, include_help },
226 
227 #define M_PUT1 (M_DEFINE_SET+1)
228     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
229       MENU_TOP  + ICON_BORDER + MENU_Y * 15, &put1_pr,
230       SHSave1, nop, put1_help },
231 
232 #define M_PUT3 (M_PUT1+1)
233     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
234       MENU_TOP  + ICON_BORDER + MENU_Y * 16, &put3_pr,
235       SHSave3, nop, put3_help },
236 
237 #define M_HORZ_ADJUST (M_PUT3+1)
238     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
239       MENU_TOP  + ICON_BORDER + MENU_Y * 17, &horizontal_pr,
240       LGHAdjust, nop, horizontal_help },
241 
242 #define M_VERT_ADJUST (M_HORZ_ADJUST+1)
243     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
244       MENU_TOP  + ICON_BORDER + MENU_Y * 18, &vertical_pr,
245       LGVAdjust, nop, vertical_help },
246 
247 #define M_STIPPLE1 (M_VERT_ADJUST+1)
248     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
249       MENU_TOP  + ICON_BORDER + MENU_Y * 3, &white_pr,
250       LGStipple1, LGMStipple1, stipple1_help },
251 
252 #define M_STIPPLE5 (M_STIPPLE1+1)
253     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
254       MENU_TOP  + ICON_BORDER + MENU_Y * 3, &stipple5_pr,
255       LGStipple5, LGMStipple5, stipple5_help },
256 
257 #define M_SIZE2 (M_STIPPLE5+1)
258     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
259       MENU_TOP  + ICON_BORDER + MENU_Y * 1, &size2_pr,
260       LGSize2, LGMSize2, size2_help },
261 
262 #define M_ITALICS (M_SIZE2+1)
263     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
264       MENU_TOP  + ICON_BORDER + MENU_Y * 2, &italics_pr,
265       LGFont2, LGMFont2, italics_help },
266 
267 #define M_COPY (M_ITALICS+1)
268     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
269       MENU_TOP  + ICON_BORDER + MENU_Y * 8, &copy_pr,
270       SHCopy, nop, copy_help },
271 
272 #define M_ERASE (M_COPY+1)
273     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
274       MENU_TOP  + ICON_BORDER + MENU_Y * 9, &erase_pr,
275       SHErase, nop, erase_help },
276 
277 #define M_MOVE_POINT (M_ERASE+1)
278     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
279       MENU_TOP  + ICON_BORDER + MENU_Y * 10, &movepoint_pr,
280       LGMPoint, nop, movepoint_help },
281 
282 #define M_ROTATE (M_MOVE_POINT+1)
283     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
284       MENU_TOP  + ICON_BORDER + MENU_Y * 10, &rotate_pr,
285       SHRotate, nop, rotate_help },
286 
287 #define M_FILE (M_ROTATE+1)
288     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
289       MENU_TOP  + ICON_BORDER + MENU_Y * 13, &filecabinet_pr,
290       nop, nop, filecabinet_help },
291 
292 #define M_PAN (M_FILE+1)
293     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
294       MENU_TOP  + ICON_BORDER + MENU_Y * 14, &pan_pr,
295       LGPan, LGMPan, pan_help },
296 
297 #define M_SET_AREA (M_PAN+1)
298     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
299       MENU_TOP  + ICON_BORDER + MENU_Y * 14, &boxinc_pr,
300       SHSetArea, SHMSetArea, boxinc_help },
301 
302 #define M_PUT2 (M_SET_AREA+1)
303     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
304       MENU_TOP  + ICON_BORDER + MENU_Y * 15, &put2_pr,
305       SHSave2, nop, put2_help },
306 
307 #define M_PUT4 (M_PUT2+1)
308     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
309       MENU_TOP  + ICON_BORDER + MENU_Y * 16, &put4_pr,
310       SHSave4, nop, put4_help },
311 
312 #define M_MANHATTAN_ADJUST (M_PUT4+1)
313     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
314       MENU_TOP  + ICON_BORDER + MENU_Y * 17, &horvert_pr,
315       SHMAdjust, nop, manhattan_help },
316 
317 #define M_GRAVITY (M_MANHATTAN_ADJUST+1)
318     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
319       MENU_TOP  + ICON_BORDER + MENU_Y * 18, &gravity_pr,
320       SHGravity, nop, gravity_help },
321 
322 #define M_STIPPLE6 (M_GRAVITY+1)
323     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
324       MENU_TOP  + ICON_BORDER + MENU_Y * 4, &stipple6_pr,
325       LGStipple6, LGMStipple6, stipple6_help },
326 
327 #define M_STIPPLE2 (M_STIPPLE6+1)
328     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
329       MENU_TOP  + ICON_BORDER + MENU_Y * 4, &gray_pr,
330       LGStipple2, LGMStipple2, stipple2_help },
331 
332 #define M_SIZE3 (M_STIPPLE2+1)
333     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
334       MENU_TOP  + ICON_BORDER + MENU_Y * 2, &size3_pr,
335       LGSize3, LGMSize3, size3_help },
336 
337 #define M_BOLD (M_SIZE3+1)
338     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
339       MENU_TOP  + ICON_BORDER + MENU_Y * 3, &bold_pr,
340       LGFont3, LGMFont3, bold_help },
341 
342 #define M_BRUSH1 (M_BOLD+1)
343     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
344       MENU_TOP  + ICON_BORDER + MENU_Y * 4, &dotted_pr,
345       LGBrush1, LGMBrush1, brush1_help },
346 
347 #define M_BRUSH2 (M_BRUSH1+1)
348     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
349       MENU_TOP  + ICON_BORDER + MENU_Y * 6, &broken_pr,
350       LGBrush2, LGMBrush2, brush2_help },
351 
352 #define M_BRUSH3 (M_BRUSH2+1)
353     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
354       MENU_TOP  + ICON_BORDER + MENU_Y * 6, &thick_pr,
355       LGBrush3, LGMBrush3, brush3_help },
356 
357 #define M_TEXT (M_BRUSH3+1)
358     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
359       MENU_TOP  + ICON_BORDER + MENU_Y * 8, &text_pr,
360       LGText, LGMText, text_help },
361 
362 #define M_BPOLYGON (M_TEXT+1)
363     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
364       MENU_TOP  + ICON_BORDER + MENU_Y * 9, &bpolygon_pr,
365       LGBPolygon, LGMBPolygon, bpolygon_help },
366 
367 #define M_POLYGON (M_BPOLYGON+1)
368     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
369       MENU_TOP  + ICON_BORDER + MENU_Y * 10, &polygon_pr,
370       LGPolygon, LGMPolygon, polygon_help },
371 
372 #define M_ARROW (M_POLYGON+1)
373     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
374       MENU_TOP  + ICON_BORDER + MENU_Y * 11, &arrow_pr,
375       SHArrow, nop, arrow_help },
376 
377 #define M_HELP (M_ARROW+1)
378     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
379       MENU_TOP  + ICON_BORDER + MENU_Y * 13, &question_pr,
380       help, help, help },
381 
382 #define M_MISC (M_HELP+1)
383     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
384       MENU_TOP  + ICON_BORDER + MENU_Y * 14, &misc_pr,
385       nop, nop, misc_help },
386 
387 #define M_GET1 (M_MISC+1)
388     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
389       MENU_TOP  + ICON_BORDER + MENU_Y * 15, &get1_pr,
390       LGGet1, nop, get1_help },
391 
392 #define M_GET3 (M_GET1+1)
393     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
394       MENU_TOP  + ICON_BORDER + MENU_Y * 16, &get3_pr,
395       LGGet3, nop, get3_help },
396 
397 #define M_LINESTYLE (M_GET3+1)
398     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
399       MENU_TOP  + ICON_BORDER + MENU_Y * 13, &linestyle_pr,
400       LGLineStyle, nop, linestyle_help },
401 
402 #define M_ALIGN (M_LINESTYLE+1)
403     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
404       MENU_TOP  + ICON_BORDER + MENU_Y * 17, &align_pr,
405       nop, nop, align_help },
406 
407 #define M_STIPPLE3 (M_ALIGN+1)
408     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
409       MENU_TOP  + ICON_BORDER + MENU_Y * 5, &_50_pr,
410       LGStipple3, LGMStipple3, stipple3_help },
411 
412 #define M_STIPPLE7 (M_STIPPLE3+1)
413     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
414       MENU_TOP  + ICON_BORDER + MENU_Y * 5, &stipple7_pr,
415       LGStipple7, LGMStipple7, stipple7_help },
416 
417 #define M_STIPPLE8 (M_STIPPLE7+1)
418     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
419       MENU_TOP  + ICON_BORDER + MENU_Y * 6, &stipple8_pr,
420       LGStipple8, LGMStipple8, stipple8_help },
421 
422 #define M_STIPPLE4 (M_STIPPLE8+1)
423     { MENU_LEFT + ICON_BORDER + MENU_X * 0,
424       MENU_TOP  + ICON_BORDER + MENU_Y * 6, &black_pr,
425       LGStipple4, LGMStipple4, stipple4_help },
426 
427 #define M_SIZE4 (M_STIPPLE4+1)
428     { MENU_LEFT + ICON_BORDER + MENU_X * 1,
429       MENU_TOP  + ICON_BORDER + MENU_Y * 2, &size4_pr,
430       LGSize4, LGMSize4, size4_help },
431 
432 #define M_SPECIAL (M_SIZE4+1)
433     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
434       MENU_TOP  + ICON_BORDER + MENU_Y * 3, &special_pr,
435       LGFont4 , LGMFont4, special_help },
436 
437 #define M_BRUSH4 (M_SPECIAL+1)
438     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
439       MENU_TOP  + ICON_BORDER + MENU_Y * 5, &dashed_pr,
440       LGBrush4, LGMBrush4, brush4_help },
441 
442 #define M_BRUSH5 (M_BRUSH4+1)
443     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
444       MENU_TOP  + ICON_BORDER + MENU_Y * 4, &narrow_pr,
445       LGBrush5, LGMBrush5, brush5_help },
446 
447 #define M_BRUSH6 (M_BRUSH5+1)
448     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
449       MENU_TOP  + ICON_BORDER + MENU_Y * 5, &medium_pr,
450       LGBrush6, LGMBrush6, brush6_help },
451 
452 #define M_DRAW_ARC (M_BRUSH6+1)
453     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
454       MENU_TOP  + ICON_BORDER + MENU_Y * 8, &arc_pr,
455       SHDrawArc, nop, arc_help },
456 
457 #define M_DRAW_CURVE (M_DRAW_ARC+1)
458     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
459       MENU_TOP  + ICON_BORDER + MENU_Y * 9, &curve_pr,
460       SHDrawCurve, LGMCurve, curve_help },
461 
462 #define M_DRAW_VECTOR (M_DRAW_CURVE+1)
463     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
464       MENU_TOP  + ICON_BORDER + MENU_Y * 10, &vector_pr,
465       SHDrawVector, LGMVector, vector_help },
466 
467 #define M_BOX (M_DRAW_VECTOR+1)
468     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
469       MENU_TOP  + ICON_BORDER + MENU_Y * 11, &box_pr,
470       SHBox, nop, box_help },
471 
472 #define M_UNDO (M_BOX+1)
473     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
474       MENU_TOP  + ICON_BORDER + MENU_Y * 13, &undo_pr,
475       LGUndo, nop, undo_help },
476 
477 #define M_GET2 (M_UNDO+1)
478     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
479       MENU_TOP  + ICON_BORDER + MENU_Y * 15, &get2_pr,
480       LGGet2, nop, get2_help },
481 
482 #define M_GET4 (M_GET2+1)
483     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
484       MENU_TOP  + ICON_BORDER + MENU_Y * 16, &get4_pr,
485       LGGet4, nop, get4_help },
486 
487 #define M_GRID (M_GET4+1)
488     { MENU_LEFT + ICON_BORDER + MENU_X * 3,
489       MENU_TOP  + ICON_BORDER + MENU_Y * 18, &grid_pr,
490       SHGrid, nop, grid_help },
491 
492 #define M_LITTLE_POINT (M_GRID+1)
493     { MENU_LEFT + ICON_BORDER + MENU_X * 2,
494       MENU_TOP  + ICON_BORDER + MENU_Y * 18, &littlepoint_pr,
495       LGLittlePoint, nop, littlepoint_help },
496 
497     { -1, -1, (struct pixrect *)0, (int(*)())0 }
498 };
499 
500 
501 /*
502  * Following is a map of brushes and mode made available to the
503  * outside world for selection of these items for highlighting.
504  * The numbers indicate the items location in the menu.
505  */
506 
507 int HiBuffer[] = { M_PUT1, M_PUT2, M_PUT3, M_PUT4 };	/* user symbols */
508 int HiFont[] = { M_ROMAN, M_ITALICS, M_BOLD, M_SPECIAL };
509 int HiSize[] = { M_SIZE1, M_SIZE2, M_SIZE3, M_SIZE4 };
510 int HiBrush[] = { M_BRUSH1, M_BRUSH2, M_BRUSH3,
511 		   M_BRUSH4, M_BRUSH5, M_BRUSH6 };	/* brushes */
512 int HiMode[] = { M_HORZ_ADJUST, M_VERT_ADJUST, M_MANHATTAN_ADJUST,
513 		  M_GRAVITY };			/* horz, vert, man, grav. */
514 int HiStipple[] = { M_STIPPLE1, M_STIPPLE2, M_STIPPLE3, M_STIPPLE4,
515 		    M_STIPPLE5, M_STIPPLE6, M_STIPPLE7, M_STIPPLE8 };
516 int HiArtMode = M_LITTLE_POINT;
517 int HiLineStyle = M_LINESTYLE;
518 
519 
520 
521 /*
522  * This routine initializatizes the positioning of menu items -
523  * currently only necessary for the justify icon.
524  */
525 MNInitMenu()
526 {
527     int justify_x, justify_y;
528     int i;
529 
530     justify_x = menu[M_JUSTIFY].menu_x;
531     justify_y = menu[M_JUSTIFY].menu_y;
532 
533     for (i=0; i<9; i++) {
534 	switch (i % 3) {
535 	    case 0:		/* left */
536 		justify_mark[i].x = justify_x - 1;
537 		break;
538 	    case 1:		/* center */
539 		justify_mark[i].x = justify_x + 18;
540 		break;
541 	    case 2:		/* right */
542 		justify_mark[i].x = justify_x + 35;
543 		break;
544 	}
545 
546 	switch (i / 3) {
547 	    case 0:		/* top */
548 		justify_mark[i].y = justify_y - 2;
549 		break;
550 	    case 1:		/* center */
551 		justify_mark[i].y = justify_y + 5;
552 		break;
553 	    case 2:		/* bottom */
554 		justify_mark[i].y = justify_y + 12;
555 		break;
556 	}
557     }
558 
559     if ((save_just_pr = mem_create(6, 6, 1)) == NULL) {
560 	printf("cannot create save_just_pr.\n");
561 	exit(1);
562     }
563 }  /* end MNInitMenu */
564 
565 
566 /*
567  * This routine displays the menu defined by initmenu
568  */
569 MNDisplayMenu()
570 {
571     register i;
572     register struct _menu *m;
573     char buf[4];
574 
575     pw_text(menu_pw, 28, menu[M_SIZE1].menu_y - MENU_Y + TEXT_BASELINE,
576 		PIX_SRC | PIX_DST, text_pf, "styles");
577     pw_text(menu_pw, 24, menu[M_DRAW_ARC].menu_y - MENU_Y + TEXT_BASELINE,
578 		PIX_SRC | PIX_DST, text_pf, "drawing");
579     pw_text(menu_pw, 32, menu[M_FILE].menu_y - MENU_Y + TEXT_BASELINE,
580 		PIX_SRC | PIX_DST, text_pf, "other");
581 
582     pw_box(menu_pw, 2, 2,
583 		MENUSW_WIDTH - 3, menu[M_BRUSH2].menu_y + ICON_SIZE + 3,
584 		PIX_SRC | PIX_DST, 1);
585     pw_box(menu_pw, 2, menu[M_DRAW_ARC].menu_y - MENU_Y - 2,
586 		MENUSW_WIDTH - 3, menu[M_BOX].menu_y + ICON_SIZE + 3,
587 		PIX_SRC | PIX_DST, 1);
588     pw_box(menu_pw, 2, menu[M_FILE].menu_y - MENU_Y - 2,
589 		MENUSW_WIDTH - 3, 509
590 		/*menu[M_LITTLE_POINT].menu_y + ICON_SIZE + 3*/,
591 		PIX_SRC | PIX_DST, 1);
592 
593     i = 0;
594     do {
595 	m = &menu[i];
596 	pw_write(menu_pw, m->menu_x, m->menu_y,
597 			m->menu_icon->pr_width, m->menu_icon->pr_height,
598 			PIX_SRC, m->menu_icon, 0, 0);
599 
600 	if (is_stipple(m->menu_icon)) {
601 	    pw_write(menu_pw, m->menu_x, m->menu_y,
602 			openbox_pr.pr_width, openbox_pr.pr_height,
603 			PIX_SRC | PIX_DST, &openbox_pr, 0, 0);
604 	}
605     } while (menu[++i].menu_x != -1);
606 
607     if (Adjustment != NOADJ)
608 	MNHighLt(HiMode[adj[Adjustment]]);
609 
610     if (GravityOn)
611 	MNHighLt(HiMode[3]);
612 
613     if (!SymbolicLines)
614 	MNHighLt(HiLineStyle);
615 
616     if (!Artmode)
617 	MNHighLt(HiArtMode);
618 
619     MNHighLt(HiFont[CFONT-1]);
620     MNHighLt(HiSize[CSIZE-1]);
621     MNHighLt(HiBrush[CBRUSH-1]);
622     MNHighLt(HiStipple[CSTIPPLE-1]);
623 
624     pw_read(save_just_pr, 0, 0, 6, 6, PIX_SRC, menu_pw,
625 			    justify_mark[just_to_indx[CJUST]].x,
626 			    justify_mark[just_to_indx[CJUST]].y);
627 
628     pw_write(menu_pw, justify_mark[just_to_indx[CJUST]].x + 1,
629 			    justify_mark[just_to_indx[CJUST]].y,
630 			    5, 5, PIX_SRC, &dot_pr, 0, 0);
631 
632     for (i = 0; i<NUSER; ++i) {
633 	if (!DBNullelt(MEN[i]))
634 	    MNHighLt(HiBuffer[i]);
635     }
636 
637     sprintf(buf, "%3d", Alignment);
638     pw_text(menu_pw, menu[M_ALIGN].menu_x + 16,
639 		     menu[M_ALIGN].menu_y + 12,
640 		     PIX_SRC ^ PIX_DST, text_pf, buf);
641 }
642 
643 
644 menu_left(ie)
645 register struct inputevent *ie;
646 {
647     register index;
648 
649     TxMsgOK();
650     lasttext = FALSE;
651 
652     if ((index = icon_last) >= 0) {
653 	if (index == M_ALIGN) {
654 	    lastcommand = align_up;
655 	    align_up();
656 	    return;
657 	}
658 
659 	/* current set on, un-highlight icon */
660 	GRCurrentSetOn();
661 	MNReverse(index);
662 	icon_last = -1;
663 
664 	if (index == M_FILE) {
665 	    menu_filer(ie);
666 	    return;
667 	}
668 
669 	if (index == M_MISC) {
670 	    menu_misc(ie);
671 	    return;
672 	}
673 
674 	lastcommand = menu[index].menu_function;
675 	if (index == M_TEXT)
676 	    lasttext = TRUE;
677 	(*lastcommand)();
678 	/* (*(menu[index].menu_function))(); */
679 	FLASH_READY = 0;	/* don't flash; it may have taken a while */
680 	return;
681     }
682 
683     if (just_last >= 0) {	/* in JUSTIFY icon */
684 	/* un-highlight */
685 	MNReverseJustify();
686 
687 	/* update justification mode */
688 	pw_write(menu_pw, justify_mark[just_to_indx[CJUST]].x,
689 			justify_mark[just_to_indx[CJUST]].y,
690 			6, 6, PIX_SRC, save_just_pr, 0, 0);
691 
692 	CJUST = indx_to_just[just_last];
693 
694 	pw_read(save_just_pr, 0, 0, 6, 6, PIX_SRC, menu_pw,
695 			justify_mark[just_to_indx[CJUST]].x,
696 			justify_mark[just_to_indx[CJUST]].y);
697 
698 	pw_write(menu_pw, justify_mark[just_to_indx[CJUST]].x + 1,
699 			justify_mark[just_to_indx[CJUST]].y,
700 			5, 5, PIX_SRC, &dot_pr, 0, 0);
701 	just_last = -1;
702     }
703 }
704 
705 
706 menu_middle(ie)
707 register struct inputevent *ie;
708 {
709     register index;
710 
711     TxMsgOK();
712     lasttext = FALSE;
713 
714     if ((index = icon_last) >= 0) {
715 	if (index == M_ALIGN) {
716 	    lastcommand = align_down;
717 	    align_down();
718 	    return;
719 	}
720 
721 	/* current set on, un-highlight icon */
722 	GRCurrentSetOn();
723 	MNReverse(index);
724 	icon_last = -1;
725 
726 	lastcommand = menu[index].menu_modify;
727 	(*lastcommand)();
728 	if (index == M_TEXT)
729 	    lasttext = TRUE;
730 	/* (*(menu[index].menu_modify))(); */
731 	FLASH_READY = 0;	/* don't flash; it may have taken a while */
732 	return;
733     }
734 
735     if ((index = just_last) >= 0) {
736 	just_last = -1;
737 
738 	/* current set on, un-highlight icon */
739 	GRCurrentSetOn();
740 	MNReverseJustify();
741 
742 	LGMJustify(indx_to_just[index]);
743     }
744 }
745 
746 
747 menu_right(ie)
748 register struct inputevent *ie;
749 {
750     register index;
751 
752     TxMsgOK();
753 
754     if ((index = icon_last) >= 0) {
755 	icon_last = -1;
756 
757 	/* un-highlight icon */
758 	MNReverse(index);
759 
760 	(*(menu[index].menu_help))();
761 	return;
762     }
763 
764     if ((index = just_last) >= 0) {
765 	just_last = -1;
766 
767 	/* un-highlight icon */
768 	MNReverseJustify();
769 
770 	justify_help();
771 	return;
772     }
773 
774     menusw_help();
775 }
776 
777 
778 menu_winexit(ie)
779 register struct inputevent *ie;
780 {
781     if (icon_last >= 0) {
782 	MNReverse(icon_last);
783 	icon_last = -1;
784     }
785     else if (just_last >= 0) {
786 	MNReverseJustify();
787 	just_last = -1;
788     }
789 
790     /* check if leaving left or bottom edge of menu subwindow */
791     if ((ie->ie_locx < 0) || (ie->ie_locy >= menu_size.r_height))
792 	GRCurrentSetOn();
793 }
794 
795 
796 /*
797  * Move align to next higher value.
798  */
799 align_up()
800 {
801     menu_align(TRUE);
802 }
803 
804 
805 /*
806  * Move align to next lower value.
807  */
808 align_down()
809 {
810     menu_align(FALSE);
811 }
812 
813 
814 #define ALIGNMAX 512
815 menu_align(up)
816 int up;
817 {
818     char buf[4];
819 
820 
821     sprintf(buf, "%3d", Alignment);
822     pw_text(menu_pw, menu[M_ALIGN].menu_x + 16,
823 		     menu[M_ALIGN].menu_y + 12,
824 		     PIX_SRC ^ PIX_DST, text_pf, buf);
825 
826     if (up) {
827 	if ((Alignment <<= 1) > ALIGNMAX)
828 	    Alignment = 1;
829     }
830     else {
831 	if ((Alignment >>= 1) == 0)
832 	    Alignment = ALIGNMAX;
833     }
834 
835     sprintf(buf, "%3d", Alignment);
836     pw_text(menu_pw, menu[M_ALIGN].menu_x + 16,
837 		     menu[M_ALIGN].menu_y + 12,
838 		     PIX_SRC ^ PIX_DST, text_pf, buf);
839 }
840 
841 
842 menu_filer(ie)
843 register struct inputevent *ie;
844 {
845     register struct menuitem *item;
846 
847     item = menu_display(&file_menu_stack, ie, menu_fd);
848 
849     if (item == (struct menuitem *) NULL)
850 	return;
851 
852     switch (item->mi_data) {
853 	case M_EDIT:
854 	    lastcommand = LGEdit;
855 	    break;
856 	case M_PATH:
857 	    lastcommand = LGPath;
858 	    break;
859 	case M_READ:
860 	    lastcommand = LGRead;
861 	    break;
862 	case M_SAVE_SET:
863 	    lastcommand = LGSave;
864 	    break;
865 	case M_WRITE:
866 	    lastcommand = LGWrite;
867 	    break;
868 	default:
869 	    return;
870     }
871     (*lastcommand)();
872     lasttext = TRUE;
873 }
874 
875 
876 menu_misc(ie)
877 register struct inputevent *ie;
878 {
879     register struct menuitem *item;
880 
881     item = menu_display(&misc_menu_stack, ie, menu_fd);
882 
883     if (item == (struct menuitem *) NULL)
884 	return;
885 
886     switch (item->mi_data) {
887 	case M_CLEAR_POINTS:
888 	    lastcommand = LGClearPoints;
889 	    break;
890 	case M_SHOW_POINTS:
891 	    lastcommand = LGShowPoints;
892 	    break;
893 	case M_GRIPE:
894 	    lastcommand = LGGripe;
895 	    break;
896 	case M_POINT:
897 	    lastcommand = LGOPoint;
898 	    lasttext = TRUE;
899 	    break;
900 	default:
901 	    return;
902     }
903     (*lastcommand)();
904 }
905 
906 
907 /*
908  *  find justification mode determined by (x, y) screen position
909  *  return -1 if not in justify icon
910  */
911 just_index(x, y)
912 register x;
913 register y;
914 {
915     x -= menu[M_JUSTIFY].menu_x - 1;
916     y -= menu[M_JUSTIFY].menu_y - 2;
917 
918     if ((x > 41) || (x < 0) || (y > 19) || (y < 0))
919 	return(-1);
920     else
921 	return((y / 7) * 3 + (x / 14));
922 }
923 
924 
925 mouse_move(ie)
926 register struct inputevent *ie;
927 {
928     register index, in_icon, in_xy;
929 
930     /* handle justify icon as a special case */
931     if ((index = just_index(ie->ie_locx, ie->ie_locy)) >= 0) {
932 	if (icon_last >= 0) {	/* erase last highlighted icon */
933 	    MNReverse(icon_last);
934 	    icon_last = -1;
935 	}
936 
937 	if (just_last >= 0)	/* erase current justification marker */
938 	    MNReverseJustify();
939 
940 	just_x = justify_mark[index].x;
941 	just_y = justify_mark[index].y;
942 	just_last = index;
943 	MNReverseJustify();
944 	return;
945     }
946 
947 
948     /* ... not currently in justify icon */
949 
950     if (just_last >= 0) {	/* previously in justify icon */
951 	MNReverseJustify();
952 	just_last = -1;
953     }
954 
955     in_xy = ((index = MNFindMenuItem(ie->ie_locx, ie->ie_locy)) >= 0);
956     in_icon = (icon_last >= 0);
957 
958     switch ((in_xy << 1) | in_icon) {
959 	case 0:		/* was outside still outside */
960 	    break;
961 	case 1:		/* was inside now outside */
962 	    MNReverse(icon_last);
963 	    icon_last = -1;
964 	    break;
965 	case 2:		/* was outside now inside */
966 	    icon_x = menu[index].menu_x;
967 	    icon_y = menu[index].menu_y;
968 	    MNReverse(icon_last = index);
969 	    break;
970 	case 3:		/* was inside still inside */
971 	    if ((icon_y != menu[index].menu_y) ||
972 		(icon_x != menu[index].menu_x)) {
973 		MNReverse(icon_last);
974 		icon_x = menu[index].menu_x;
975 		icon_y = menu[index].menu_y;
976 		MNReverse(icon_last = index);
977 	    }
978 	    break;
979     }
980 }
981 
982 
983 /*
984  *  return index into menu[] for icon at (x, y)
985  */
986 MNFindMenuItem(x, y)
987 int x, y;
988 {
989     register struct _menu *m;
990     register mleft, mright, mtop, mbottom;
991     int i;
992 
993     i = 0;
994 
995     do {
996 	m = &menu[i];
997 	mleft = m->menu_x;
998 	mtop = m->menu_y;
999 	mright = mleft + m->menu_icon->pr_width - 1;
1000 	mbottom = mtop + m->menu_icon->pr_height - 1;
1001 
1002 	if ((x <= mright) && (y <= mbottom) && (x >= mleft) && (y >= mtop))
1003 	    return(i);
1004 
1005     } while (menu[++i].menu_x != -1);
1006 
1007     return(-1);		/* not found */
1008 
1009 } /* end MNFindMenuItem */
1010 
1011 
1012 /*
1013  *  Highlight menu item specified by menu array index.
1014  */
1015 MNHighLt(index)
1016 int index;
1017 {
1018     pw_write(menu_pw, menu[index].menu_x-2, menu[index].menu_y-2,
1019 		    bigopenbox_pr.pr_width, bigopenbox_pr.pr_height,
1020 		    PIX_SRC | PIX_DST, &bigopenbox_pr, 0, 0);
1021 }
1022 
1023 
1024 /*
1025  *  Un-highlight menu item specified by menu array index.
1026  */
1027 MNUnHighLt(index)
1028 int index;
1029 {
1030     pw_write(menu_pw, menu[index].menu_x - 2, menu[index].menu_y - 2,
1031 		    bigopenbox_pr.pr_width, bigopenbox_pr.pr_height,
1032 		    PIX_NOT(PIX_SRC) & PIX_DST, &bigopenbox_pr, 0, 0);
1033 }
1034 
1035 
1036 /*
1037  *  Reverse video menu item specified by menu array index.
1038  */
1039 MNReverse(index)
1040 int index;
1041 {
1042     pw_write(menu_pw, menu[index].menu_x - 2, menu[index].menu_y - 2,
1043 		    menu[index].menu_icon->pr_width + 4,
1044 		    menu[index].menu_icon->pr_height + 4,
1045 		    PIX_SRC ^ PIX_DST, &bigblack_pr, 0, 0);
1046 }
1047