3 /* Copyright Massachusetts Institute of Technology 1985 */
6 * XMenu: MIT Project Athena, X Window system menu package
8 * XMenuInternal.c - XMenu internal (not user visible) routines.
10 * Author: Tony Della Fera, DEC
21 #define toggle_color(x) \
22 ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color)
25 * Internal Window creation queue sizes.
27 #define S_QUE_SIZE 300
29 #define BUFFER_SIZE (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE)
33 * XMWinQue - Internal window creation queue datatype.
35 typedef struct _xmwinquedef
{
37 XMSelect
*sq
[S_QUE_SIZE
];
40 XMPane
*pq
[P_QUE_SIZE
];
45 * _XMWinQue - Internal static window creation queue.
47 static Bool _XMWinQueIsInit
= False
;
48 static XMWinQue _XMWinQue
;
51 * _XMErrorCode - Global XMenu error code.
53 int _XMErrorCode
= XME_NO_ERROR
;
55 * _XMErrorList - Global XMenu error code description strings.
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 */
79 * _XMEventHandler - Internal event handler variable.
81 int (*_XMEventHandler
)() = NULL
;
86 * _XMWinQueInit - Internal routine to initialize the window
92 * If the queue is not initialized initialize it.
94 if (!_XMWinQueIsInit
) {
96 * Blank the queue structure.
100 for (i
= 0; i
< S_QUE_SIZE
; i
++)
103 for (i
= 0; i
< P_QUE_SIZE
; i
++)
106 _XMWinQue
.sq_size
= _XMWinQue
.pq_size
= 0;
109 * Initialize the next free location pointers.
111 _XMWinQue
.sq_ptr
= _XMWinQue
.sq
;
112 _XMWinQue
.pq_ptr
= _XMWinQue
.pq
;
119 * _XMWinQueAddPane - Internal routine to add a pane to the pane
123 _XMWinQueAddPane(display
, menu
, p_ptr
)
124 register Display
*display
;
125 register XMenu
*menu
; /* Menu being manipulated. */
126 register XMPane
*p_ptr
; /* XMPane being queued. */
129 * If the queue is currently full then flush it.
131 if (_XMWinQue
.pq_size
== P_QUE_SIZE
) {
132 if (_XMWinQueFlush(display
, menu
, 0, 0) == _FAILURE
) return(_FAILURE
);
136 * Insert the new XMPane pointer and increment the queue pointer
137 * and the queue size.
139 *_XMWinQue
.pq_ptr
= p_ptr
;
144 * All went well, return successfully.
146 _XMErrorCode
= XME_NO_ERROR
;
153 * _XMWinQueAddSelection - Internal routine to add a selection to
154 * the selection window queue.
157 _XMWinQueAddSelection(display
, menu
, s_ptr
)
158 register Display
*display
;
159 register XMenu
*menu
; /* Menu being manipulated. */
160 register XMSelect
*s_ptr
; /* XMSelection being queued. */
163 * If this entry will overflow the queue then flush it.
165 if (_XMWinQue
.sq_size
== S_QUE_SIZE
) {
166 if (_XMWinQueFlush(display
, menu
, 0, 0) == _FAILURE
) return(_FAILURE
);
170 * Insert the new XMSelect pointer and increment the queue pointer
171 * and the queue size.
173 *_XMWinQue
.sq_ptr
= s_ptr
;
178 * All went well, return successfully.
180 _XMErrorCode
= XME_NO_ERROR
;
187 * _XMWinQueFlush - Internal routine to flush the pane and
188 * selection window queues.
191 _XMWinQueFlush(display
, menu
, pane
, select
)
192 register Display
*display
;
193 register XMenu
*menu
; /* Menu being manipulated. */
194 register XMPane
*pane
; /* Current pane. */
196 register int pq_index
; /* Pane queue index. */
197 register int sq_index
; /* Selection queue index. */
198 register XMPane
*p_ptr
; /* XMPane pointer. */
199 register XMSelect
*s_ptr
; /* XMSelect pointer. */
200 unsigned long valuemask
; /* Which attributes to set. */
201 XSetWindowAttributes
*attributes
; /* Attributes to be set. */
204 * If the pane window queue is not empty...
207 if (_XMWinQue
.pq_size
> 0) {
209 * set up attributes for pane window to be created.
211 valuemask
= (CWBackPixmap
| CWBorderPixel
| CWOverrideRedirect
);
212 attributes
= (XSetWindowAttributes
*)malloc(sizeof(XSetWindowAttributes
));
213 attributes
->border_pixel
= menu
->p_bdr_color
;
214 attributes
->background_pixmap
= menu
->inact_pixmap
;
215 attributes
->override_redirect
= True
;
218 * Create all the pending panes in order, so that the
219 * current pane will be on top, with the others
220 * stacked appropriately under it.
222 for (pq_index
= _XMWinQue
.pq_size
- 1;
226 p_ptr
= _XMWinQue
.pq
[pq_index
]; /* Retrieve next pane. */
227 if (p_ptr
== pane
) break;
228 p_ptr
->window
= XCreateWindow(display
,
240 XMakeAssoc(display
, menu
->assoc_tab
, p_ptr
->window
, p_ptr
);
241 XSelectInput(display
, p_ptr
->window
, menu
->p_events
);
244 pq_index
< _XMWinQue
.pq_size
;
247 p_ptr
= _XMWinQue
.pq
[pq_index
]; /* Retrieve next pane. */
248 p_ptr
->window
= XCreateWindow(display
,
260 XMakeAssoc(display
, menu
->assoc_tab
, p_ptr
->window
, p_ptr
);
261 XSelectInput(display
, p_ptr
->window
, menu
->p_events
);
262 if (p_ptr
== pane
) break;
266 * Reset the pane queue pointer and size.
268 _XMWinQue
.pq_size
= 0;
269 _XMWinQue
.pq_ptr
= _XMWinQue
.pq
;
273 * If the selection window queue is not empty...
276 if (_XMWinQue
.sq_size
> 0) {
278 for (sq_index
= 0; sq_index
< _XMWinQue
.sq_size
; sq_index
++) {
280 * Retrieve the XMSelect pointer.
282 s_ptr
= _XMWinQue
.sq
[sq_index
];
283 s_ptr
->window
= XCreateWindow(display
,
284 s_ptr
->parent_p
->window
,
297 * Insert the new window id and its
298 * associated XMSelect structure into the
301 XMakeAssoc(display
, menu
->assoc_tab
, s_ptr
->window
, s_ptr
);
302 XSelectInput(display
, s_ptr
->window
, menu
->s_events
);
306 * Reset the selection queue pointer and size.
308 _XMWinQue
.sq_size
= 0;
309 _XMWinQue
.sq_ptr
= _XMWinQue
.sq
;
313 * Flush X's internal queues.
318 * All went well, return successfully.
320 _XMErrorCode
= XME_NO_ERROR
;
327 * _XMGetPanePtr - Given a menu pointer and a pane index number, return
328 * a pane pointer that points to the indexed pane.
331 _XMGetPanePtr(menu
, p_num
)
332 register XMenu
*menu
; /* Menu to find the pane in. */
333 register int p_num
; /* Index number of pane to find. */
335 register XMPane
*p_ptr
; /* Pane pointer to be returned. */
336 register int i
; /* Loop counter. */
339 * Is the pane number out of range?
341 if ((p_num
< 0) || (p_num
> (menu
->p_count
- 1))) {
342 _XMErrorCode
= XME_P_NOT_FOUND
;
347 * Find the right pane.
349 p_ptr
= menu
->p_list
->next
;
350 for (i
= 0; i
< p_num
; i
++) p_ptr
= p_ptr
->next
;
353 * Return successfully.
355 _XMErrorCode
= XME_NO_ERROR
;
362 * _XMGetSelectionPtr - Given pane pointer and a selection index number,
363 * return a selection pointer that points to the
367 _XMGetSelectionPtr(p_ptr
, s_num
)
368 register XMPane
*p_ptr
; /* Pane to find the selection in. */
369 register int s_num
; /* Index number of the selection to find. */
371 register XMSelect
*s_ptr
; /* Selection pointer to be returned. */
372 register int i
; /* Loop counter. */
375 * Is the selection number out of range?
377 if ((s_num
< 0) || (s_num
> (p_ptr
->s_count
- 1))) {
378 _XMErrorCode
= XME_S_NOT_FOUND
;
383 * Find the right selection.
385 s_ptr
= p_ptr
->s_list
->next
;
386 for (i
= 0; i
< s_num
; i
++) s_ptr
= s_ptr
->next
;
389 * Return successfully.
391 _XMErrorCode
= XME_NO_ERROR
;
398 * _XMRecomputeGlobals - Internal subroutine to recompute menu wide
401 _XMRecomputeGlobals(display
, menu
)
402 register Display
*display
; /*X11 display variable. */
403 register XMenu
*menu
; /* Menu object to compute from. */
405 register XMPane
*p_ptr
; /* Pane pointer. */
406 register XMSelect
*s_ptr
; /* Selection pointer. */
408 register int max_p_label
= 0; /* Maximum pane label width. */
409 register int max_s_label
= 0; /* Maximum selection label width. */
410 register int s_count
= 0; /* Maximum selection count. */
412 int p_s_pad
; /* Pane <-> selection padding. */
413 int p_s_diff
; /* Pane <-> selection separation. */
415 int p_height
; /* Pane window height. */
416 int p_width
; /* Pane window width. */
417 int s_width
; /* Selection window width. */
419 int screen
; /* DefaultScreen holder. */
425 p_ptr
= menu
->p_list
->next
;
426 p_ptr
!= menu
->p_list
;
431 * Recompute maximum pane label width.
433 max_p_label
= max(max_p_label
, p_ptr
->label_width
);
436 * Recompute maximum selection count.
438 s_count
= max(s_count
, p_ptr
->s_count
);
441 * For each selection in the current pane...
444 s_ptr
= p_ptr
->s_list
->next
;
445 s_ptr
!= p_ptr
->s_list
;
450 * Recompute maximum selection label width.
452 max_s_label
= max(max_s_label
, s_ptr
->label_width
);
457 * Recompute pane height.
459 p_height
= (menu
->flag_height
<< 1) + (menu
->s_y_off
* s_count
);
462 * Recompute horizontal padding between the pane window and the
465 p_s_pad
= menu
->p_x_off
<< 1;
468 * Recompute pane and selection window widths.
469 * This is done by first computing the window sizes from the maximum
470 * label widths. If the spacing between the selection window and the
471 * containing pane window is less than the pane selection padding value
472 * (twice the pane X offset) then change the size of the pane to be
473 * the size of the selection window plus the padding. If, however the
474 * spacing between the selection window and the containing pane window
475 * is more than the pane selection padding value increase the size of
476 * the selection to its maximum possible value (the pane width minus
477 * the pane selection padding value).
479 p_width
= max_p_label
+ p_s_pad
;
480 s_width
= max_s_label
+ (menu
->s_fnt_pad
<< 1) + (menu
->s_bdr_width
<< 1);
481 p_s_diff
= p_width
- s_width
;
482 if (p_s_diff
< p_s_pad
) {
483 p_width
= s_width
+ p_s_pad
;
485 else if (p_s_diff
> p_s_pad
) {
486 s_width
= p_width
- p_s_pad
;
490 * Reset menu wide global values.
492 menu
->s_count
= s_count
;
493 menu
->p_height
= p_height
;
494 menu
->p_width
= p_width
;
495 menu
->s_width
= s_width
;
498 * Ensure that the origin of the menu is placed so that
499 * None of the panes ore selections are off the screen.
501 screen
= DefaultScreen(display
);
502 if (menu
->x_pos
+ menu
->width
> DisplayWidth(display
, screen
))
503 menu
->x_pos
= DisplayWidth(display
, screen
) - menu
->width
;
504 else if (menu
->x_pos
< 0) menu
->x_pos
= 0;
505 if(menu
->y_pos
+ menu
->height
> DisplayHeight(display
, screen
))
506 menu
->y_pos
= DisplayHeight(display
, screen
) - menu
->height
;
507 else if (menu
->y_pos
< 0) menu
->y_pos
= 0;
512 * _XMRecomputePane - Internal subroutine to recompute pane
513 * window dependencies.
516 _XMRecomputePane(display
, menu
, p_ptr
, p_num
)
517 register Display
*display
; /* Standard X display variable. */
518 register XMenu
*menu
; /* Menu object being recomputed. */
519 register XMPane
*p_ptr
; /* Pane pointer. */
520 register int p_num
; /* Pane sequence number. */
522 register int window_x
; /* Recomputed window X coordinate. */
523 register int window_y
; /* Recomputed window Y coordinate. */
525 unsigned long change_mask
; /* Value mask to reconfigure window. */
526 XWindowChanges
*changes
; /* Values to use in configure window. */
528 register Bool config_p
= False
; /* Reconfigure pane window? */
531 * Update the pane serial number.
533 p_ptr
->serial
= p_num
;
536 * Recompute window X and Y coordinates.
538 switch (menu
->menu_style
) {
540 window_x
= menu
->p_x_off
* ((menu
->p_count
- 1) - p_num
);
541 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
544 window_x
= menu
->p_x_off
* p_num
;
545 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
549 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
552 /* Error! Invalid style parameter. */
553 _XMErrorCode
= XME_STYLE_PARAM
;
556 window_x
+= menu
->x_pos
;
557 window_y
+= menu
->y_pos
;
560 * If the newly compute pane coordinates differ from the
561 * current coordinates, reset the current coordinates and
562 * reconfigure the pane.
565 (window_x
!= p_ptr
->window_x
) ||
566 (window_y
!= p_ptr
->window_y
)
569 * Reset the coordinates and schedule
570 * the pane for reconfiguration.
572 p_ptr
->window_x
= window_x
;
573 p_ptr
->window_y
= window_y
;
578 * If the local pane width and height differs from the
579 * menu pane width and height, reset the local values.
582 (p_ptr
->window_w
!= menu
->p_width
) ||
583 (p_ptr
->window_h
!= menu
->p_height
)
586 * Reset window width and height and schedule
587 * the pane for reconfiguration.
589 p_ptr
->window_w
= menu
->p_width
;
590 p_ptr
->window_h
= menu
->p_height
;
595 * If we need to reconfigure the pane window do it now.
597 if (config_p
== True
) {
599 * If the pane window has already been created then
600 * reconfigure the existing window, otherwise queue
601 * it for creation with the new configuration.
604 change_mask
= (CWX
| CWY
| CWWidth
| CWHeight
);
605 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
606 changes
->x
= p_ptr
->window_x
;
607 changes
->y
= p_ptr
->window_y
;
608 changes
->width
= p_ptr
->window_w
;
609 changes
->height
= p_ptr
->window_h
;
621 if (_XMWinQueAddPane(display
, menu
, p_ptr
) == _FAILURE
) {
628 * Recompute label X position.
630 switch (menu
->p_style
) {
632 p_ptr
->label_x
= menu
->p_x_off
+ menu
->p_fnt_pad
;
635 p_ptr
->label_x
= menu
->p_width
-
636 (p_ptr
->label_width
+ menu
->p_x_off
+ menu
->p_fnt_pad
);
639 p_ptr
->label_x
= (menu
->p_width
- p_ptr
->label_width
) >> 1;
642 /* Error! Invalid style parameter. */
643 _XMErrorCode
= XME_STYLE_PARAM
;
647 * Recompute label Y positions.
649 p_ptr
->label_uy
= menu
->p_fnt_pad
+ menu
->p_fnt_info
->max_bounds
.ascent
;
650 p_ptr
->label_ly
= (menu
->p_height
- menu
->p_fnt_pad
- menu
->p_fnt_info
->max_bounds
.descent
);
653 * All went well, return successfully.
655 _XMErrorCode
= XME_NO_ERROR
;
662 * _XMRecomputeSelection - Internal subroutine to recompute
663 * selection window dependencies.
666 _XMRecomputeSelection(display
, menu
, s_ptr
, s_num
)
667 register Display
*display
;
668 register XMenu
*menu
; /* Menu object being recomputed. */
669 register XMSelect
*s_ptr
; /* Selection pointer. */
670 register int s_num
; /* Selection sequence number. */
672 register Bool config_s
= False
; /* Reconfigure selection window? */
673 XWindowChanges
*changes
; /* Values to change in configure. */
674 unsigned long change_mask
; /* Value mask for XConfigureWindow. */
677 * If the selection serial numbers are out of order, begin
678 * resequencing selections. Recompute selection window coordinates
681 * When selections are created they are given a serial number of
682 * -1, this causes this routine to give a new selection
683 * its initial coordinates and serial number.
685 if (s_ptr
->serial
!= s_num
) {
687 * Fix the sequence number.
689 s_ptr
->serial
= s_num
;
691 * Recompute window X and Y coordinates.
693 s_ptr
->window_x
= menu
->s_x_off
;
694 s_ptr
->window_y
= menu
->flag_height
+ (menu
->s_y_off
* s_num
);
696 * We must reconfigure the window.
702 * If the local selection width and height differs from the
703 * menu selection width and height, reset the local values.
706 (s_ptr
->window_w
!= menu
->s_width
) ||
707 (s_ptr
->window_h
!= menu
->s_height
)
710 * We must reconfigure the window.
714 * Reset window width and height.
716 s_ptr
->window_w
= menu
->s_width
;
717 s_ptr
->window_h
= menu
->s_height
;
721 * If we need to reconfigure the selection window do it now.
723 if (config_s
== True
) {
725 * If the selection window has already been created then
726 * reconfigure the existing window, otherwise queue it
727 * for creation with the new configuration.
730 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
731 change_mask
= (CWX
| CWY
| CWWidth
| CWHeight
);
732 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
733 changes
->x
= s_ptr
->window_x
;
734 changes
->y
= s_ptr
->window_y
;
735 changes
->width
= s_ptr
->window_w
;
736 changes
->height
= s_ptr
->window_h
;
748 if (_XMWinQueAddSelection(display
, menu
, s_ptr
) == _FAILURE
) {
755 * Recompute label X position.
757 switch (menu
->s_style
) {
759 s_ptr
->label_x
= menu
->s_bdr_width
+ menu
->s_fnt_pad
+ s_ptr
->window_x
;
762 s_ptr
->label_x
= s_ptr
->window_x
+ menu
->s_width
-
763 (s_ptr
->label_width
+ menu
->s_bdr_width
+ menu
->s_fnt_pad
);
766 s_ptr
->label_x
= s_ptr
->window_x
+ ((menu
->s_width
- s_ptr
->label_width
) >> 1);
769 /* Error! Invalid style parameter. */
770 _XMErrorCode
= XME_STYLE_PARAM
;
774 * Recompute label Y position.
776 s_ptr
->label_y
= s_ptr
->window_y
+ menu
->s_fnt_info
->max_bounds
.ascent
+ menu
->s_fnt_pad
+ menu
->s_bdr_width
;
779 * All went well, return successfully.
781 _XMErrorCode
= XME_NO_ERROR
;
788 * _XMTransToOrigin - Internal subroutine to translate the point at
789 * the center of the current pane and selection to the
792 * WARNING! ****** Be certain that all menu dependencies have been
793 * recomputed before calling this routine or
794 * unpredictable results will follow.
796 _XMTransToOrigin(display
, menu
, p_ptr
, s_ptr
, x_pos
, y_pos
, orig_x
, orig_y
)
797 Display
*display
; /* Not used. Included for consistency. */
798 register XMenu
*menu
; /* Menu being computed against. */
799 register XMPane
*p_ptr
; /* Current pane pointer. */
800 register XMSelect
*s_ptr
; /* Current selection pointer. */
801 int x_pos
; /* X coordinate of point to translate. */
802 int y_pos
; /* Y coordinate of point to translate. */
803 int *orig_x
; /* Return value X coord. of the menu origin. */
804 int *orig_y
; /* Return value Y coord. of the menu origin. */
806 register int l_orig_x
; /* Local X coordinate of the menu origin. */
807 register int l_orig_y
; /* Local Y coordinate of the menu origin. */
810 * Translate the menu origin such that the cursor hot point will be in the
811 * center of the desired current selection and pane.
812 * If the current selection pointer is NULL then assume that the hot point
813 * will be in the center of the current pane flag.
818 * Translate from the center of the pane flag to the upper left
819 * of the current pane window.
821 l_orig_x
= x_pos
- (menu
->p_width
>> 1) - menu
->p_bdr_width
;
822 l_orig_y
= y_pos
- (menu
->flag_height
>> 1) - menu
->p_bdr_width
;
826 * First translate from the center of the current selection
827 * to the upper left of the current selection window.
829 l_orig_x
= x_pos
- (menu
->s_width
>> 1);
830 l_orig_y
= y_pos
- (menu
->s_height
>> 1);
833 * Then translate to the upper left of the current pane window.
835 l_orig_x
-= (s_ptr
->window_x
+ menu
->p_bdr_width
);
836 l_orig_y
-= (s_ptr
->window_y
+ menu
->p_bdr_width
);
840 * Finally translate to the upper left of the menu.
842 l_orig_x
-= (p_ptr
->window_x
- menu
->x_pos
);
843 l_orig_y
-= (p_ptr
->window_y
- menu
->y_pos
);
846 * Set the return values.
853 * _XMRefreshPane - Internal subroutine to completely refresh
854 * the contents of a pane.
856 _XMRefreshPane(display
, menu
, pane
)
857 register Display
*display
;
858 register XMenu
*menu
;
859 register XMPane
*pane
;
861 register XMSelect
*s_list
= pane
->s_list
;
862 register XMSelect
*s_ptr
;
865 * First clear the pane.
867 XClearWindow(display
, pane
->window
);
868 if (!pane
->activated
) {
869 XFillRectangle(display
,
871 menu
->inverse_select_GC
,
872 pane
->label_x
- menu
->p_fnt_pad
,
873 pane
->label_uy
- menu
->p_fnt_info
->max_bounds
.ascent
- menu
->p_fnt_pad
,
874 pane
->label_width
+ (menu
->p_fnt_pad
<< 1),
877 XFillRectangle(display
,
879 menu
->inverse_select_GC
,
880 pane
->label_x
- menu
->p_fnt_pad
,
881 pane
->label_ly
- menu
->p_fnt_info
->max_bounds
.ascent
- menu
->p_fnt_pad
,
882 pane
->label_width
+ (menu
->p_fnt_pad
<< 1),
889 pane
->label_x
, pane
->label_uy
,
890 pane
->label
, pane
->label_length
);
894 pane
->label_x
, pane
->label_ly
,
895 pane
->label
, pane
->label_length
);
901 pane
->label_x
, pane
->label_uy
,
902 pane
->label
, pane
->label_length
);
906 pane
->label_x
, pane
->label_ly
,
907 pane
->label
, pane
->label_length
);
910 * Finally refresh each selection if the pane is activated.
912 if (pane
->activated
) {
913 for (s_ptr
= s_list
->next
; s_ptr
!= s_list
; s_ptr
= s_ptr
->next
)
914 _XMRefreshSelection(display
, menu
, s_ptr
);
923 * _XMRefreshSelection - Internal subroutine that refreshes
924 * a single selection window.
926 _XMRefreshSelection(display
, menu
, select
)
927 register Display
*display
;
928 register XMenu
*menu
;
929 register XMSelect
*select
;
931 register int width
= select
->window_w
;
932 register int height
= select
->window_h
;
933 register int bdr_width
= menu
->s_bdr_width
;
935 if (select
->type
== SEPARATOR
) {
937 select
->parent_p
->window
,
938 menu
->normal_select_GC
,
940 select
->window_y
+ height
/ 2,
941 select
->window_x
+ width
,
942 select
->window_y
+ height
/ 2);
944 else if (select
->activated
) {
945 if (menu
->menu_mode
== INVERT
) {
946 XFillRectangle(display
,
947 select
->parent_p
->window
,
948 menu
->normal_select_GC
,
949 select
->window_x
, select
->window_y
,
952 select
->parent_p
->window
,
953 menu
->inverse_select_GC
,
956 select
->label
, select
->label_length
);
961 * Since most drawing routines with arbitrary width lines
962 * are slow compared to raster-ops lets use a raster-op to
966 XDrawRectangle(display
,
967 select
->parent_p
->window
,
968 menu
->normal_select_GC
,
969 select
->window_x
+ (bdr_width
>> 1),
970 select
->window_y
+ (bdr_width
>> 1 ),
974 select
->parent_p
->window
,
975 menu
->normal_select_GC
,
978 select
->label
, select
->label_length
);
983 select
->parent_p
->window
,
984 select
->window_x
, select
->window_y
,
987 if (select
->active
) {
989 select
->parent_p
->window
,
990 menu
->normal_select_GC
,
993 select
->label
, select
->label_length
);
997 select
->parent_p
->window
,
1001 select
->label
, select
->label_length
);
1006 /* arch-tag: 3ac61957-0852-4e72-8b88-7dfab1a5dee9
1007 (do not change this comment) */