|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* $Header: XMenuInternal.c,v 10.17 86/02/01 16:15:10 tony Rel $ */
4: /* Copyright Massachusetts Institute of Technology 1985 */
5:
6: /*
7: * XMenu: MIT Project Athena, X Window system menu package
8: *
9: * XMenuInternal.c - XMenu internal (not user visable) routines.
10: *
11: * Author: Tony Della Fera, DEC
12: * November, 1985
13: *
14: */
15:
16: #include "XMenuInternal.h"
17:
18: /*
19: * Toggle color macro.
20: */
21: #define toggle_color(x) \
22: ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color)
23:
24: /*
25: * Internal Window creation queue sizes.
26: */
27: #define S_QUE_SIZE 300
28: #define P_QUE_SIZE 20
29: #define BUFFER_SIZE (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE)
30:
31:
32: /*
33: * XMWinQue - Internal window creation queue datatype.
34: */
35: typedef struct _xm_win_que_def {
36: int sq_size;
37: XMSelect *sq[S_QUE_SIZE];
38: XMSelect **sq_ptr;
39: int pq_size;
40: XMPane *pq[P_QUE_SIZE];
41: XMPane **pq_ptr;
42: } XMWinQue;
43:
44: /*
45: * _XMWinQue - Internal static window creation queue.
46: */
47: static XMWinQue _XMWinQue;
48:
49: /*
50: * _XMErrorCode - Global XMenu error code.
51: */
52: int _XMErrorCode = XME_NO_ERROR;
53:
54: /*
55: * _XMErrorList - Global XMenu error code discription strings.
56: */
57: char *
58: _XMErrorList[XME_CODE_COUNT] = {
59: "No error", /* XME_NO_ERROR */
60: "Menu not initialized", /* XME_NOT_INIT */
61: "Argument out of bounds", /* XME_ARG_BOUNDS */
62: "Pane not found", /* XME_P_NOT_FOUND */
63: "Selection not found", /* XME_S_NOT_FOUND */
64: "Invalid menu style parameter", /* XME_STYLE_PARAM */
65: "Unable to grab mouse", /* XME_GRAB_MOUSE */
66: "Unable to interpret locator", /* XME_INTERP_LOC */
67: "Unable to calloc memory", /* XME_CALLOC */
68: "Unable to create XAssocTable", /* XME_CREATE_ASSOC */
69: "Unable to store bitmap", /* XME_STORE_BITMAP */
70: "Unable to make tile pixmaps", /* XME_MAKE_TILES */
71: "Unable to make pixmap", /* XME_MAKE_PIXMAP */
72: "Unable to create cursor", /* XME_CREATE_CURSOR */
73: "Unable to open font", /* XME_OPEN_FONT */
74: "Unable to create windows", /* XME_CREATE_WINDOW */
75: "Unable to create transparencies", /* XME_CREATE_TRANSP */
76: };
77:
78: /*
79: * _XMEventHandler - Internal event handler variable.
80: */
81: int (*_XMEventHandler)() = NULL;
82:
83:
84:
85: /*
86: * _XMWinQueInit - Internal routine to initialize the window
87: * queue.
88: */
89: _XMWinQueInit()
90: {
91: /*
92: * Blank the queue structure.
93: */
94: bzero(&_XMWinQue, sizeof(XMWinQue));
95:
96: /*
97: * Initialize the next free location pointers.
98: */
99: _XMWinQue.sq_ptr = _XMWinQue.sq;
100: _XMWinQue.pq_ptr = _XMWinQue.pq;
101: }
102:
103:
104:
105: /*
106: * _XMWinQueAddPane - Internal routine to add a pane to the pane
107: * window queue.
108: */
109: int
110: _XMWinQueAddPane(menu, p_ptr)
111: register XMenu *menu; /* Menu being manipulated. */
112: register XMPane *p_ptr; /* XMPane being queued. */
113: {
114: /*
115: * If the queue is currently full then flush it.
116: */
117: if (_XMWinQue.pq_size == P_QUE_SIZE) {
118: if (_XMWinQueFlush(menu) == _FAILURE) return(_FAILURE);
119: }
120:
121: /*
122: * Insert the new XMPane pointer and increment the queue pointer
123: * and the queue size.
124: */
125: *_XMWinQue.pq_ptr = p_ptr;
126: _XMWinQue.pq_ptr++;
127: _XMWinQue.pq_size++;
128:
129: /*
130: * All went well, return successfully.
131: */
132: _XMErrorCode = XME_NO_ERROR;
133: return(_SUCCESS);
134: }
135:
136:
137:
138: /*
139: * _XMWinQueAddSelection - Internal routine to add a selection to
140: * the selection window queue.
141: */
142: int
143: _XMWinQueAddSelection(menu, s_ptr)
144: register XMenu *menu; /* Menu being manipulated. */
145: register XMSelect *s_ptr; /* XMSelection being queued. */
146: {
147: /*
148: * If this entry will overflow the queue then flush it.
149: */
150: if (_XMWinQue.sq_size == S_QUE_SIZE) {
151: if (_XMWinQueFlush(menu) == _FAILURE) return(_FAILURE);
152: }
153:
154: /*
155: * Insert the new XMSelect pointer and increment the queue pointer
156: * and the queue size.
157: */
158: *_XMWinQue.sq_ptr = s_ptr;
159: _XMWinQue.sq_ptr++;
160: _XMWinQue.sq_size++;
161:
162: /*
163: * All went well, return successfully.
164: */
165: _XMErrorCode = XME_NO_ERROR;
166: return(_SUCCESS);
167: }
168:
169:
170:
171: /*
172: * _XMWinQueFlush - Internal routine to flush the pane and
173: * selection window queues.
174: */
175: int
176: _XMWinQueFlush(menu)
177: register XMenu *menu; /* Menu being manipulated. */
178: {
179: register int pq_index; /* Pane queue index. */
180: register int sq_index; /* Selection queue index. */
181: register XMPane *p_ptr; /* XMPane pointer. */
182: register XMSelect *s_ptr; /* XMSelect pointer. */
183:
184: int win_count; /* Count of created windows. */
185: Window window; /* Window id temporary variable. */
186: BatchFrame batch_buf[BUFFER_SIZE]; /* Window batch creation buffer. */
187:
188: /*
189: * If the pane window queue is not empty...
190: */
191: if (_XMWinQue.pq_size > 0) {
192: /*
193: * Pack the window batch buffer.
194: */
195: for (pq_index = 0; pq_index < _XMWinQue.pq_size; pq_index++) {
196: /*
197: * Retrieve the an XMPane pointer.
198: */
199: p_ptr = _XMWinQue.pq[pq_index];
200:
201: /*
202: * Pack the next buffer location with the data
203: * associated with the XMPane.
204: */
205: batch_buf[pq_index].type = IsOpaque;
206: batch_buf[pq_index].parent = menu->parent;
207: batch_buf[pq_index].x = p_ptr->window_x;
208: batch_buf[pq_index].y = p_ptr->window_y;
209: batch_buf[pq_index].width = p_ptr->window_w;
210: batch_buf[pq_index].height = p_ptr->window_h;
211: batch_buf[pq_index].bdrwidth = menu->p_bdr_width;
212: batch_buf[pq_index].border = menu->p_bdr_pixmap;
213: batch_buf[pq_index].background = menu->inact_pixmap;
214: }
215:
216: /*
217: * Transmit the pane window buffer.
218: */
219: win_count = XCreateWindowBatch(batch_buf, _XMWinQue.pq_size);
220: if (win_count != _XMWinQue.pq_size) {
221: _XMErrorCode = XME_CREATE_WINDOW;
222: return(_FAILURE);
223: }
224:
225: /*
226: * Retrieve the resulting window id's.
227: */
228: for (pq_index = 0; pq_index < _XMWinQue.pq_size; pq_index++) {
229: window = batch_buf[pq_index].self;
230: /*
231: * Store the window id with its XMPane structure.
232: */
233: p_ptr = _XMWinQue.pq[pq_index];
234: p_ptr->window = window;
235: /*
236: * Insert the new window id and its
237: * associated XMPane structure into the
238: * assoction table.
239: */
240: XMakeAssoc(menu->assoc_tab, window, p_ptr);
241: /*
242: * Select input events on the new window.
243: */
244: XSelectInput(window, menu->p_events);
245: }
246:
247: /*
248: * Reset the pane queue pointer and size.
249: */
250: _XMWinQue.pq_size = 0;
251: _XMWinQue.pq_ptr = _XMWinQue.pq;
252: }
253:
254: /*
255: * If the selection window queue is not empty...
256: */
257: if (_XMWinQue.sq_size > 0) {
258: /*
259: * Pack the selection transparency buffer.
260: */
261: for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
262: /*
263: * Retrieve the an XMSelect pointer.
264: */
265: s_ptr = _XMWinQue.sq[sq_index];
266:
267: /*
268: * Pack the next buffer location with the data
269: * associated with the XMPane.
270: */
271: batch_buf[sq_index].type = IsTransparent;
272: batch_buf[sq_index].parent = s_ptr->parent_p->window;
273: batch_buf[sq_index].x = s_ptr->window_x;
274: batch_buf[sq_index].y = s_ptr->window_y;
275: batch_buf[sq_index].width = s_ptr->window_w;
276: batch_buf[sq_index].height = s_ptr->window_h;
277: }
278:
279: /*
280: * Transmit the selection transparency buffer.
281: */
282: win_count = XCreateWindowBatch(batch_buf, _XMWinQue.sq_size);
283: if (win_count != _XMWinQue.sq_size) {
284: _XMErrorCode = XME_CREATE_TRANSP;
285: return(_FAILURE);
286: }
287:
288: /*
289: * Retrieve the resulting window id's.
290: */
291: for (sq_index = 0; sq_index < _XMWinQue.sq_size; sq_index++) {
292: window = batch_buf[sq_index].self;
293: /*
294: * Store the window id with its XMSelect structure.
295: */
296: s_ptr = _XMWinQue.sq[sq_index];
297: s_ptr->window = window;
298: /*
299: * Insert the new window id and its
300: * associated XMSelect structure into the
301: * assoction table.
302: */
303: XMakeAssoc(menu->assoc_tab, window, s_ptr);
304: /*
305: * Select input events on the new window.
306: */
307: XSelectInput(window, menu->s_events);
308: }
309:
310: /*
311: * Reset the selection queue pointer and size.
312: */
313: _XMWinQue.sq_size = 0;
314: _XMWinQue.sq_ptr = _XMWinQue.sq;
315: }
316:
317: /*
318: * Flush X's internal queues.
319: */
320: XFlush();
321:
322: /*
323: * All went well, return successfully.
324: */
325: _XMErrorCode = XME_NO_ERROR;
326: return(_SUCCESS);
327: }
328:
329:
330:
331: /*
332: * _XMGetPanePtr - Given a menu pointer and a pane index number, return
333: * a pane pointer that points to the indexed pane.
334: */
335: XMPane *
336: _XMGetPanePtr(menu, p_num)
337: register XMenu *menu; /* Menu to find the pane in. */
338: register int p_num; /* Index number of pane to find. */
339: {
340: register XMPane *p_ptr; /* Pane pointer to be returned. */
341: register int i; /* Loop counter. */
342:
343: /*
344: * Is the pane number out of range?
345: */
346: if ((p_num < 0) || (p_num > (menu->p_count - 1))) {
347: _XMErrorCode = XME_P_NOT_FOUND;
348: return(NULL);
349: }
350:
351: /*
352: * Find the right pane.
353: */
354: p_ptr = menu->p_list->next;
355: for (i = 0; i < p_num; i++) p_ptr = p_ptr->next;
356:
357: /*
358: * Return successfully.
359: */
360: _XMErrorCode = XME_NO_ERROR;
361: return(p_ptr);
362: }
363:
364:
365:
366: /*
367: * _XMGetSelectionPtr - Given pane pointer and a selection index number,
368: * return a selection pointer that points to the
369: * indexed selection.
370: */
371: XMSelect *
372: _XMGetSelectionPtr(p_ptr, s_num)
373: register XMPane *p_ptr; /* Pane to find the selection in. */
374: register int s_num; /* Index number of the selection to find. */
375: {
376: register XMSelect *s_ptr; /* Selection pointer to be returned. */
377: register int i; /* Loop counter. *./
378:
379: /*
380: * Is the selection number out of range?
381: */
382: if ((s_num < 0) || (s_num > (p_ptr->s_count - 1))) {
383: _XMErrorCode = XME_S_NOT_FOUND;
384: return(NULL);
385: }
386:
387: /*
388: * Find the right selection.
389: */
390: s_ptr = p_ptr->s_list->next;
391: for (i = 0; i < s_num; i++) s_ptr = s_ptr->next;
392:
393: /*
394: * Return successfully.
395: */
396: _XMErrorCode = XME_NO_ERROR;
397: return(s_ptr);
398: }
399:
400:
401:
402: /*
403: * _XMRecomputeGlobals - Internal subroutine to recompute menu wide
404: * global values.
405: */
406: _XMRecomputeGlobals(menu)
407: register XMenu *menu; /* Menu object to compute from. */
408: {
409: register XMPane *p_ptr; /* Pane pointer. */
410: register XMSelect *s_ptr; /* Selection pointer. */
411:
412: register int max_p_label = 0; /* Maximum pane label width. */
413: register int max_s_label = 0; /* Maximum selection label width. */
414: register int s_count = 0; /* Maximum selection count. */
415:
416: int p_s_pad; /* Pane <-> selection padding. */
417: int p_s_diff; /* Pane <-> selection seperation. */
418:
419: int p_height; /* Pane window height. */
420: int p_width; /* Pane window width. */
421: int s_width; /* Selection window width. */
422:
423: int seperation; /* Pane window, selection window seperation. */
424:
425: /*
426: * For each pane...
427: */
428: for (
429: p_ptr = menu->p_list->next;
430: p_ptr != menu->p_list;
431: p_ptr = p_ptr->next
432: ){
433: /*
434: * Recompute maximum pane label width.
435: */
436: max_p_label = max(max_p_label, p_ptr->label_width);
437:
438: /*
439: * Recompute maximum selection count.
440: */
441: s_count = max(s_count, p_ptr->s_count);
442:
443: /*
444: * For each selection in the current pane...
445: */
446: for (
447: s_ptr = p_ptr->s_list->next;
448: s_ptr != p_ptr->s_list;
449: s_ptr = s_ptr->next
450: ){
451: /*
452: * Recompute maximum selection label width.
453: */
454: max_s_label = max(max_s_label, s_ptr->label_width);
455: }
456: }
457:
458: /*
459: * Recompute pane height.
460: */
461: p_height = (menu->flag_height << 1) + (menu->s_y_off * s_count);
462:
463: /*
464: * Recompute horizontal padding between the pane window and the
465: * selection windows.
466: */
467: p_s_pad = menu->p_x_off << 1;
468:
469: /*
470: * Recompute pane and selection window widths.
471: * This is done by first computing the window sizes from the maximum
472: * label widths. If the spacing between the selection window and the
473: * containing pane window is less than the pane selection padding value
474: * (twice the pane X offset) then change the size of the pane to be
475: * the size of the selection window plus the padding. If, however the
476: * spacing between the selection window and the containing pane window
477: * is more than the pane selection padding value increase the size of
478: * the selection to its maximum possible value (the pane width minus
479: * the pane selection padding value).
480: */
481: p_width = max_p_label + p_s_pad;
482: s_width = max_s_label + (menu->s_fnt_pad << 1) + (menu->s_bdr_width << 1);
483: p_s_diff = p_width - s_width;
484: if (p_s_diff < p_s_pad) {
485: p_width = s_width + p_s_pad;
486: }
487: else if (p_s_diff > p_s_pad) {
488: s_width = p_width - p_s_pad;
489: }
490:
491: /*
492: * Reset menu wide global values.
493: */
494: menu->s_count = s_count;
495: menu->p_height = p_height;
496: menu->p_width = p_width;
497: menu->s_width = s_width;
498: }
499:
500:
501:
502: /*
503: * _XMRecomputePane - Internal subroutine to recompute pane
504: * window dependencies.
505: */
506: int
507: _XMRecomputePane(menu, p_ptr, p_num)
508: register XMenu *menu; /* Menu object being recomputed. */
509: register XMPane *p_ptr; /* Pane pointer. */
510: register int p_num; /* Pane sequence number. */
511: {
512: register int window_x; /* Recomputed window X coordinate. */
513: register int window_y; /* Recomputed window Y coordinate. */
514:
515: register Bool config_p = FALSE; /* Reconfigure pane window? */
516:
517: /*
518: * Update the pane serial number.
519: */
520: p_ptr->serial = p_num;
521:
522: /*
523: * Recompute window X and Y coordinates.
524: */
525: switch (menu->menu_style) {
526: case LEFT:
527: window_x = menu->p_x_off * ((menu->p_count - 1) - p_num);
528: window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
529: break;
530: case RIGHT:
531: window_x = menu->p_x_off * p_num;
532: window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
533: break;
534: case CENTER:
535: window_x = 0;
536: window_y = menu->p_y_off * ((menu->p_count - 1) - p_num);
537: break;
538: default:
539: /* Error! Invalid style parameter. */
540: _XMErrorCode = XME_STYLE_PARAM;
541: return(_FAILURE);
542: }
543:
544: /*
545: * If the newly compute pane coordinates differ from the
546: * current coordinates, reset the current coordinates and
547: * reconfigure the pane.
548: */
549: if (
550: (window_x != p_ptr->window_x) ||
551: (window_y != p_ptr->window_y)
552: ){
553: /*
554: * Reset the coordinates and schedule
555: * the pane for reconfiguration.
556: */
557: p_ptr->window_x = window_x;
558: p_ptr->window_y = window_y;
559: config_p = TRUE;
560: }
561:
562: /*
563: * If the local pane width and height differs from the
564: * menu pane width and height, reset the local values.
565: */
566: if (
567: (p_ptr->window_w != menu->p_width) ||
568: (p_ptr->window_h != menu->p_height)
569: ){
570: /*
571: * Reset window width and height and schedule
572: * the pane for reconfiguration.
573: */
574: p_ptr->window_w = menu->p_width;
575: p_ptr->window_h = menu->p_height;
576: config_p = TRUE;
577: }
578:
579: /*
580: * If we need to reconfigure the pane window do it now.
581: */
582: if (config_p == TRUE) {
583: /*
584: * If the pane window has already been created then
585: * reconfigure the existing window, otherwise queue
586: * it for creation with the new configuration.
587: */
588: if (p_ptr->window) {
589: XConfigureWindow(
590: p_ptr->window,
591: p_ptr->window_x, p_ptr->window_y,
592: p_ptr->window_w, p_ptr->window_h
593: );
594: }
595: else {
596: if (_XMWinQueAddPane(menu, p_ptr) == _FAILURE) {
597: return(_FAILURE);
598: }
599: }
600: }
601:
602: /*
603: * Recompute label X position.
604: */
605: switch (menu->p_style) {
606: case LEFT:
607: p_ptr->label_x = menu->p_x_off + menu->p_fnt_pad;
608: break;
609: case RIGHT:
610: p_ptr->label_x = menu->p_width -
611: (p_ptr->label_width + menu->p_x_off + menu->p_fnt_pad);
612: break;
613: case CENTER:
614: p_ptr->label_x = (menu->p_width - p_ptr->label_width) >> 1;
615: break;
616: default:
617: /* Error! Invalid style parameter. */
618: _XMErrorCode = XME_STYLE_PARAM;
619: return(_FAILURE);
620: }
621: /*
622: * Recompute label Y positions.
623: */
624: p_ptr->label_uy = menu->p_fnt_pad;
625: p_ptr->label_ly = (menu->p_height - menu->flag_height) + menu->p_fnt_pad;
626:
627: /*
628: * All went well, return successfully.
629: */
630: _XMErrorCode = XME_NO_ERROR;
631: return(_SUCCESS);
632: }
633:
634:
635:
636: /*
637: * _XMRecomputeSelection - Internal subroutine to recompute
638: * selection window dependencies.
639: */
640: int
641: _XMRecomputeSelection(menu, s_ptr, s_num)
642: register XMenu *menu; /* Menu object being recomputed. */
643: register XMSelect *s_ptr; /* Selection pointer. */
644: register int s_num; /* Selection sequence number. */
645: {
646: register Bool config_s = FALSE; /* Reconfigure selection window? */
647:
648: /*
649: * If the selection serial numbers are out of order, begin
650: * resequencing selections. Recompute selection window coordinates
651: * and serial number.
652: *
653: * When selections are created they are given a serial number of
654: * -1, this causes this routine to give a new selection
655: * its initial coordinates and serial number.
656: */
657: if (s_ptr->serial != s_num) {
658: /*
659: * Fix the sequence number.
660: */
661: s_ptr->serial = s_num;
662: /*
663: * Recompute window X and Y coordinates.
664: */
665: s_ptr->window_x = menu->s_x_off;
666: s_ptr->window_y = menu->flag_height + (menu->s_y_off * s_num);
667: /*
668: * We must reconfigure the window.
669: */
670: config_s = TRUE;
671: }
672:
673: /*
674: * If the local selection width and height differs from the
675: * menu selection width and height, reset the local values.
676: */
677: if (
678: (s_ptr->window_w != menu->s_width) ||
679: (s_ptr->window_h != menu->s_height)
680: ){
681: /*
682: * We must reconfigure the window.
683: */
684: config_s = TRUE;
685: /*
686: * Reset window width and height.
687: */
688: s_ptr->window_w = menu->s_width;
689: s_ptr->window_h = menu->s_height;
690: }
691:
692: /*
693: * If we need to reconfigure the selection window do it now.
694: */
695: if (config_s == TRUE) {
696: /*
697: * If the selection window has already been created then
698: * reconfigure the existing window, otherwise queue it
699: * for creation with the new configuration.
700: */
701: if (s_ptr->window) {
702: XConfigureWindow(
703: s_ptr->window,
704: s_ptr->window_x, s_ptr->window_y,
705: s_ptr->window_w, s_ptr->window_h
706: );
707: }
708: else {
709: if (_XMWinQueAddSelection(menu, s_ptr) == _FAILURE) {
710: return(_FAILURE);
711: }
712: }
713: }
714:
715: /*
716: * Recompute label X position.
717: */
718: switch (menu->s_style) {
719: case LEFT:
720: s_ptr->label_x = menu->s_bdr_width + menu->s_fnt_pad;
721: break;
722: case RIGHT:
723: s_ptr->label_x = menu->s_width -
724: (s_ptr->label_width + menu->s_bdr_width + menu->s_fnt_pad);
725: break;
726: case CENTER:
727: s_ptr->label_x = (menu->s_width - s_ptr->label_width) >> 1;
728: break;
729: default:
730: /* Error! Invaild style parameter. */
731: _XMErrorCode = XME_STYLE_PARAM;
732: return(_FAILURE);
733: }
734: /*
735: * Recompute label Y position.
736: */
737: s_ptr->label_y = menu->s_fnt_pad + menu->s_bdr_width;
738:
739: /*
740: * All went well, return successfully.
741: */
742: _XMErrorCode = XME_NO_ERROR;
743: return(_SUCCESS);
744: }
745:
746:
747:
748: /*
749: * _XMTransToOrigin - Internal subroutine to translate the point at
750: * the center of the current pane and selection to the
751: * the menu origin.
752: *
753: * WARNING! ****** Be certain that all menu depencies have been
754: * recomputed before calling this routine or
755: * unpredicable results will follow.
756: */
757: _XMTransToOrigin(menu, p_ptr, s_ptr, x_pos, y_pos, orig_x, orig_y)
758: register XMenu *menu; /* Menu being computed against. */
759: register XMPane *p_ptr; /* Current pane pointer. */
760: register XMSelect *s_ptr; /* Current selection pointer. */
761: int x_pos; /* X coordinate of point to translate. */
762: int y_pos; /* Y coordinate of point to translate. */
763: int *orig_x; /* Return value X coord. of the menu origin. */
764: int *orig_y; /* Return value Y coord. of the menu origin. */
765: {
766: register int l_orig_x; /* Local X coordinate of the menu origin. */
767: register int l_orig_y; /* local Y coordinate of the menu origin. */
768:
769: /*
770: * Translate the menu origin such that the cursor hot point will be in the
771: * center of the desired current selection and pane.
772: */
773:
774: /*
775: * First translate to the upper left of the current selection window.
776: */
777: l_orig_x = x_pos - (menu->s_width >> 1);
778: l_orig_y = y_pos - (menu->s_height >> 1);
779:
780: /*
781: * Then translate to the upper left of the current pane window.
782: */
783: l_orig_x -= (s_ptr->window_x + menu->p_bdr_width);
784: l_orig_y -= (s_ptr->window_y + menu->p_bdr_width);
785:
786: /*
787: * Finally translate to the upper left of the menu.
788: */
789: l_orig_x -= p_ptr->window_x;
790: l_orig_y -= p_ptr->window_y;
791:
792: /*
793: * Set the return values.
794: */
795: *orig_x = l_orig_x;
796: *orig_y = l_orig_y;
797: }
798:
799:
800:
801: /*
802: * _XMRefreshPaneLabels - Internal subroutine that refreshes
803: * the labels in a menu pane.
804: */
805: _XMRefreshPaneText(menu, pane)
806: register XMenu *menu;
807: register XMPane *pane;
808: {
809: /*
810: * First clear the pane.
811: */
812: XClear(pane->window);
813: /*
814: * Then redraw the label text.
815: */
816: XTextMask(
817: pane->window,
818: pane->label_x, pane->label_uy,
819: pane->label, pane->label_length,
820: menu->p_fnt_info->id,
821: menu->p_frg_color
822: );
823: XTextMask(
824: pane->window,
825: pane->label_x, pane->label_ly,
826: pane->label, pane->label_length,
827: menu->p_fnt_info->id,
828: menu->p_frg_color
829: );
830: }
831:
832:
833:
834: /*
835: * _XMRefreshPane - Internal subroutine to completely refresh
836: * the contents of a pane.
837: */
838: _XMRefreshPane(menu,pane)
839: register XMenu *menu;
840: register XMPane *pane;
841: {
842: register XMSelect *s_list = pane->s_list;
843: register XMSelect *s_ptr;
844:
845: /*
846: * First clear the pane.
847: */
848: XClear(pane->window);
849: /*
850: * Then redraw the label text.
851: */
852: XTextMask(
853: pane->window,
854: pane->label_x, pane->label_uy,
855: pane->label, pane->label_length,
856: menu->p_fnt_info->id,
857: menu->p_frg_color
858: );
859: XTextMask(
860: pane->window,
861: pane->label_x, pane->label_ly,
862: pane->label, pane->label_length,
863: menu->p_fnt_info->id,
864: menu->p_frg_color
865: );
866: /*
867: * Finally refresh each selection.
868: */
869: for (s_ptr = s_list->next; s_ptr != s_list; s_ptr = s_ptr->next){
870: _XMRefreshSelection(menu, s_ptr);
871: }
872: }
873:
874:
875:
876: /*
877: * _XMRefreshSelection - Internal subroutine that refreshes
878: * a single selection window.
879: */
880: _XMRefreshSelection(menu, select)
881: register XMenu *menu;
882: register XMSelect *select;
883: {
884: register int width = select->window_w;
885: register int height = select->window_h;
886: register int bdr_width = menu->s_bdr_width;
887:
888: if (select->activated) {
889: if (menu->menu_mode == INVERT) {
890: XPixSet(select->window, 0, 0, width, height, menu->s_frg_color);
891: XTextMask(
892: select->window,
893: select->label_x, select->label_y,
894: select->label, select->label_length,
895: menu->s_fnt_info->id,
896: menu->bkgnd_color
897: );
898: }
899: else {
900: /*
901: * Since most drawing routines with arbitrary width lines
902: * are slow compared to raster-ops lets use a raster-op to
903: * draw the boxes.
904: */
905: XPixSet(select->window, 0, 0, width, height, menu->bkgnd_color);
906: XPixSet(
907: select->window,
908: 0, 0,
909: (width - bdr_width), bdr_width,
910: menu->s_bdr_color
911: );
912: XPixSet(
913: select->window,
914: (0 + (width - bdr_width)), 0,
915: bdr_width, (height - bdr_width),
916: menu->s_bdr_color
917: );
918: XPixSet(
919: select->window,
920: (0 + bdr_width), (0 + (height - bdr_width)),
921: (width - bdr_width), bdr_width,
922: menu->s_bdr_color
923: );
924: XPixSet(
925: select->window,
926: 0, (0 + bdr_width),
927: bdr_width, (height - bdr_width),
928: menu->s_bdr_color
929: );
930: XTextMask(
931: select->window,
932: select->label_x, select->label_y,
933: select->label, select->label_length,
934: menu->s_fnt_info->id,
935: menu->s_frg_color
936: );
937: }
938: }
939: else {
940: XClear(select->window);
941: XTextMask(
942: select->window,
943: select->label_x, select->label_y,
944: select->label, select->label_length,
945: menu->s_fnt_info->id,
946: menu->s_frg_color
947: );
948: }
949: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.