1 /* Copyright Massachusetts Institute of Technology 1985 */
6 Copyright (C) 1993, 1996, 2001-2011 Free Software Foundation, Inc.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 * XMenu: MIT Project Athena, X Window system menu package
25 * XMenuInternal.c - XMenu internal (not user visible) routines.
27 * Author: Tony Della Fera, DEC
38 #define toggle_color(x) \
39 ((x) == menu->bkgnd_color ? menu->s_frg_color : menu->bkgnd_color)
42 * Internal Window creation queue sizes.
44 #define S_QUE_SIZE 300
46 #define BUFFER_SIZE (S_QUE_SIZE >= P_QUE_SIZE ? S_QUE_SIZE : P_QUE_SIZE)
50 * XMWinQue - Internal window creation queue datatype.
52 typedef struct _xmwinquedef
{
54 XMSelect
*sq
[S_QUE_SIZE
];
57 XMPane
*pq
[P_QUE_SIZE
];
62 * _XMWinQue - Internal static window creation queue.
64 static Bool _XMWinQueIsInit
= False
;
65 static XMWinQue _XMWinQue
;
68 * _XMErrorCode - Global XMenu error code.
70 int _XMErrorCode
= XME_NO_ERROR
;
72 * _XMErrorList - Global XMenu error code description strings.
75 _XMErrorList
[XME_CODE_COUNT
] = {
76 "No error", /* XME_NO_ERROR */
77 "Menu not initialized", /* XME_NOT_INIT */
78 "Argument out of bounds", /* XME_ARG_BOUNDS */
79 "Pane not found", /* XME_P_NOT_FOUND */
80 "Selection not found", /* XME_S_NOT_FOUND */
81 "Invalid menu style parameter", /* XME_STYLE_PARAM */
82 "Unable to grab mouse", /* XME_GRAB_MOUSE */
83 "Unable to interpret locator", /* XME_INTERP_LOC */
84 "Unable to calloc memory", /* XME_CALLOC */
85 "Unable to create XAssocTable", /* XME_CREATE_ASSOC */
86 "Unable to store bitmap", /* XME_STORE_BITMAP */
87 "Unable to make tile pixmaps", /* XME_MAKE_TILES */
88 "Unable to make pixmap", /* XME_MAKE_PIXMAP */
89 "Unable to create cursor", /* XME_CREATE_CURSOR */
90 "Unable to open font", /* XME_OPEN_FONT */
91 "Unable to create windows", /* XME_CREATE_WINDOW */
92 "Unable to create transparencies", /* XME_CREATE_TRANSP */
96 * _XMEventHandler - Internal event handler variable.
98 int (*_XMEventHandler
)(XEvent
*) = NULL
;
103 * _XMWinQueInit - Internal routine to initialize the window
109 * If the queue is not initialized initialize it.
111 if (!_XMWinQueIsInit
) {
113 * Blank the queue structure.
117 for (i
= 0; i
< S_QUE_SIZE
; i
++)
120 for (i
= 0; i
< P_QUE_SIZE
; i
++)
123 _XMWinQue
.sq_size
= _XMWinQue
.pq_size
= 0;
126 * Initialize the next free location pointers.
128 _XMWinQue
.sq_ptr
= _XMWinQue
.sq
;
129 _XMWinQue
.pq_ptr
= _XMWinQue
.pq
;
136 * _XMWinQueAddPane - Internal routine to add a pane to the pane
140 _XMWinQueAddPane(register Display
*display
, register XMenu
*menu
, register XMPane
*p_ptr
)
142 /* Menu being manipulated. */
143 /* XMPane being queued. */
146 * If the queue is currently full then flush it.
148 if (_XMWinQue
.pq_size
== P_QUE_SIZE
) {
149 if (_XMWinQueFlush(display
, menu
, 0, 0) == _FAILURE
) return(_FAILURE
);
153 * Insert the new XMPane pointer and increment the queue pointer
154 * and the queue size.
156 *_XMWinQue
.pq_ptr
= p_ptr
;
161 * All went well, return successfully.
163 _XMErrorCode
= XME_NO_ERROR
;
170 * _XMWinQueAddSelection - Internal routine to add a selection to
171 * the selection window queue.
174 _XMWinQueAddSelection(register Display
*display
, register XMenu
*menu
, register XMSelect
*s_ptr
)
176 /* Menu being manipulated. */
177 /* XMSelection being queued. */
180 * If this entry will overflow the queue then flush it.
182 if (_XMWinQue
.sq_size
== S_QUE_SIZE
) {
183 if (_XMWinQueFlush(display
, menu
, 0, 0) == _FAILURE
) return(_FAILURE
);
187 * Insert the new XMSelect pointer and increment the queue pointer
188 * and the queue size.
190 *_XMWinQue
.sq_ptr
= s_ptr
;
195 * All went well, return successfully.
197 _XMErrorCode
= XME_NO_ERROR
;
204 * _XMWinQueFlush - Internal routine to flush the pane and
205 * selection window queues.
208 _XMWinQueFlush(register Display
*display
, register XMenu
*menu
, register XMPane
*pane
, XMSelect
*select
)
210 /* Menu being manipulated. */
213 register int pq_index
; /* Pane queue index. */
214 register int sq_index
; /* Selection queue index. */
215 register XMPane
*p_ptr
; /* XMPane pointer. */
216 register XMSelect
*s_ptr
; /* XMSelect pointer. */
217 unsigned long valuemask
; /* Which attributes to set. */
218 XSetWindowAttributes
*attributes
; /* Attributes to be set. */
221 * If the pane window queue is not empty...
224 if (_XMWinQue
.pq_size
> 0) {
226 * set up attributes for pane window to be created.
228 valuemask
= (CWBackPixmap
| CWBorderPixel
| CWOverrideRedirect
);
229 attributes
= (XSetWindowAttributes
*)malloc(sizeof(XSetWindowAttributes
));
230 attributes
->border_pixel
= menu
->p_bdr_color
;
231 attributes
->background_pixmap
= menu
->inact_pixmap
;
232 attributes
->override_redirect
= True
;
235 * Create all the pending panes in order, so that the
236 * current pane will be on top, with the others
237 * stacked appropriately under it.
239 for (pq_index
= _XMWinQue
.pq_size
- 1;
243 p_ptr
= _XMWinQue
.pq
[pq_index
]; /* Retrieve next pane. */
244 if (p_ptr
== pane
) break;
245 p_ptr
->window
= XCreateWindow(display
,
257 XMakeAssoc(display
, menu
->assoc_tab
, p_ptr
->window
, p_ptr
);
258 XSelectInput(display
, p_ptr
->window
, menu
->p_events
);
261 pq_index
< _XMWinQue
.pq_size
;
264 p_ptr
= _XMWinQue
.pq
[pq_index
]; /* Retrieve next pane. */
265 p_ptr
->window
= XCreateWindow(display
,
277 XMakeAssoc(display
, menu
->assoc_tab
, p_ptr
->window
, p_ptr
);
278 XSelectInput(display
, p_ptr
->window
, menu
->p_events
);
279 if (p_ptr
== pane
) break;
283 * Reset the pane queue pointer and size.
285 _XMWinQue
.pq_size
= 0;
286 _XMWinQue
.pq_ptr
= _XMWinQue
.pq
;
290 * If the selection window queue is not empty...
293 if (_XMWinQue
.sq_size
> 0) {
295 for (sq_index
= 0; sq_index
< _XMWinQue
.sq_size
; sq_index
++) {
297 * Retrieve the XMSelect pointer.
299 s_ptr
= _XMWinQue
.sq
[sq_index
];
300 s_ptr
->window
= XCreateWindow(display
,
301 s_ptr
->parent_p
->window
,
314 * Insert the new window id and its
315 * associated XMSelect structure into the
318 XMakeAssoc(display
, menu
->assoc_tab
, s_ptr
->window
, s_ptr
);
319 XSelectInput(display
, s_ptr
->window
, menu
->s_events
);
323 * Reset the selection queue pointer and size.
325 _XMWinQue
.sq_size
= 0;
326 _XMWinQue
.sq_ptr
= _XMWinQue
.sq
;
330 * Flush X's internal queues.
335 * All went well, return successfully.
337 _XMErrorCode
= XME_NO_ERROR
;
344 * _XMGetPanePtr - Given a menu pointer and a pane index number, return
345 * a pane pointer that points to the indexed pane.
348 _XMGetPanePtr(register XMenu
*menu
, register int p_num
)
349 /* Menu to find the pane in. */
350 /* Index number of pane to find. */
352 register XMPane
*p_ptr
; /* Pane pointer to be returned. */
353 register int i
; /* Loop counter. */
356 * Is the pane number out of range?
358 if ((p_num
< 0) || (p_num
> (menu
->p_count
- 1))) {
359 _XMErrorCode
= XME_P_NOT_FOUND
;
364 * Find the right pane.
366 p_ptr
= menu
->p_list
->next
;
367 for (i
= 0; i
< p_num
; i
++) p_ptr
= p_ptr
->next
;
370 * Return successfully.
372 _XMErrorCode
= XME_NO_ERROR
;
379 * _XMGetSelectionPtr - Given pane pointer and a selection index number,
380 * return a selection pointer that points to the
384 _XMGetSelectionPtr(register XMPane
*p_ptr
, register int s_num
)
385 /* Pane to find the selection in. */
386 /* Index number of the selection to find. */
388 register XMSelect
*s_ptr
; /* Selection pointer to be returned. */
389 register int i
; /* Loop counter. */
392 * Is the selection number out of range?
394 if ((s_num
< 0) || (s_num
> (p_ptr
->s_count
- 1))) {
395 _XMErrorCode
= XME_S_NOT_FOUND
;
400 * Find the right selection.
402 s_ptr
= p_ptr
->s_list
->next
;
403 for (i
= 0; i
< s_num
; i
++) s_ptr
= s_ptr
->next
;
406 * Return successfully.
408 _XMErrorCode
= XME_NO_ERROR
;
415 * _XMRecomputeGlobals - Internal subroutine to recompute menu wide
418 _XMRecomputeGlobals(register Display
*display
, register XMenu
*menu
)
419 /*X11 display variable. */
420 /* Menu object to compute from. */
422 register XMPane
*p_ptr
; /* Pane pointer. */
423 register XMSelect
*s_ptr
; /* Selection pointer. */
425 register int max_p_label
= 0; /* Maximum pane label width. */
426 register int max_s_label
= 0; /* Maximum selection label width. */
427 register int s_count
= 0; /* Maximum selection count. */
429 int p_s_pad
; /* Pane <-> selection padding. */
430 int p_s_diff
; /* Pane <-> selection separation. */
432 int p_height
; /* Pane window height. */
433 int p_width
; /* Pane window width. */
434 int s_width
; /* Selection window width. */
436 int screen
; /* DefaultScreen holder. */
442 p_ptr
= menu
->p_list
->next
;
443 p_ptr
!= menu
->p_list
;
448 * Recompute maximum pane label width.
450 max_p_label
= max(max_p_label
, p_ptr
->label_width
);
453 * Recompute maximum selection count.
455 s_count
= max(s_count
, p_ptr
->s_count
);
458 * For each selection in the current pane...
461 s_ptr
= p_ptr
->s_list
->next
;
462 s_ptr
!= p_ptr
->s_list
;
467 * Recompute maximum selection label width.
469 max_s_label
= max(max_s_label
, s_ptr
->label_width
);
474 * Recompute pane height.
476 p_height
= (menu
->flag_height
<< 1) + (menu
->s_y_off
* s_count
);
479 * Recompute horizontal padding between the pane window and the
482 p_s_pad
= menu
->p_x_off
<< 1;
485 * Recompute pane and selection window widths.
486 * This is done by first computing the window sizes from the maximum
487 * label widths. If the spacing between the selection window and the
488 * containing pane window is less than the pane selection padding value
489 * (twice the pane X offset) then change the size of the pane to be
490 * the size of the selection window plus the padding. If, however the
491 * spacing between the selection window and the containing pane window
492 * is more than the pane selection padding value increase the size of
493 * the selection to its maximum possible value (the pane width minus
494 * the pane selection padding value).
496 p_width
= max_p_label
+ p_s_pad
;
497 s_width
= max_s_label
+ (menu
->s_fnt_pad
<< 1) + (menu
->s_bdr_width
<< 1);
498 p_s_diff
= p_width
- s_width
;
499 if (p_s_diff
< p_s_pad
) {
500 p_width
= s_width
+ p_s_pad
;
502 else if (p_s_diff
> p_s_pad
) {
503 s_width
= p_width
- p_s_pad
;
507 * Reset menu wide global values.
509 menu
->s_count
= s_count
;
510 menu
->p_height
= p_height
;
511 menu
->p_width
= p_width
;
512 menu
->s_width
= s_width
;
515 * Ensure that the origin of the menu is placed so that
516 * None of the panes ore selections are off the screen.
518 screen
= DefaultScreen(display
);
519 if (menu
->x_pos
+ menu
->width
> DisplayWidth(display
, screen
))
520 menu
->x_pos
= DisplayWidth(display
, screen
) - menu
->width
;
521 else if (menu
->x_pos
< 0) menu
->x_pos
= 0;
522 if(menu
->y_pos
+ menu
->height
> DisplayHeight(display
, screen
))
523 menu
->y_pos
= DisplayHeight(display
, screen
) - menu
->height
;
524 else if (menu
->y_pos
< 0) menu
->y_pos
= 0;
529 * _XMRecomputePane - Internal subroutine to recompute pane
530 * window dependencies.
533 _XMRecomputePane(register Display
*display
, register XMenu
*menu
, register XMPane
*p_ptr
, register int p_num
)
534 /* Standard X display variable. */
535 /* Menu object being recomputed. */
537 /* Pane sequence number. */
539 register int window_x
; /* Recomputed window X coordinate. */
540 register int window_y
; /* Recomputed window Y coordinate. */
542 unsigned long change_mask
; /* Value mask to reconfigure window. */
543 XWindowChanges
*changes
; /* Values to use in configure window. */
545 register Bool config_p
= False
; /* Reconfigure pane window? */
548 * Update the pane serial number.
550 p_ptr
->serial
= p_num
;
553 * Recompute window X and Y coordinates.
555 switch (menu
->menu_style
) {
557 window_x
= menu
->p_x_off
* ((menu
->p_count
- 1) - p_num
);
558 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
561 window_x
= menu
->p_x_off
* p_num
;
562 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
566 window_y
= menu
->p_y_off
* ((menu
->p_count
- 1) - p_num
);
569 /* Error! Invalid style parameter. */
570 _XMErrorCode
= XME_STYLE_PARAM
;
573 window_x
+= menu
->x_pos
;
574 window_y
+= menu
->y_pos
;
577 * If the newly compute pane coordinates differ from the
578 * current coordinates, reset the current coordinates and
579 * reconfigure the pane.
582 (window_x
!= p_ptr
->window_x
) ||
583 (window_y
!= p_ptr
->window_y
)
586 * Reset the coordinates and schedule
587 * the pane for reconfiguration.
589 p_ptr
->window_x
= window_x
;
590 p_ptr
->window_y
= window_y
;
595 * If the local pane width and height differs from the
596 * menu pane width and height, reset the local values.
599 (p_ptr
->window_w
!= menu
->p_width
) ||
600 (p_ptr
->window_h
!= menu
->p_height
)
603 * Reset window width and height and schedule
604 * the pane for reconfiguration.
606 p_ptr
->window_w
= menu
->p_width
;
607 p_ptr
->window_h
= menu
->p_height
;
612 * If we need to reconfigure the pane window do it now.
614 if (config_p
== True
) {
616 * If the pane window has already been created then
617 * reconfigure the existing window, otherwise queue
618 * it for creation with the new configuration.
621 change_mask
= (CWX
| CWY
| CWWidth
| CWHeight
);
622 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
623 changes
->x
= p_ptr
->window_x
;
624 changes
->y
= p_ptr
->window_y
;
625 changes
->width
= p_ptr
->window_w
;
626 changes
->height
= p_ptr
->window_h
;
638 if (_XMWinQueAddPane(display
, menu
, p_ptr
) == _FAILURE
) {
645 * Recompute label X position.
647 switch (menu
->p_style
) {
649 p_ptr
->label_x
= menu
->p_x_off
+ menu
->p_fnt_pad
;
652 p_ptr
->label_x
= menu
->p_width
-
653 (p_ptr
->label_width
+ menu
->p_x_off
+ menu
->p_fnt_pad
);
656 p_ptr
->label_x
= (menu
->p_width
- p_ptr
->label_width
) >> 1;
659 /* Error! Invalid style parameter. */
660 _XMErrorCode
= XME_STYLE_PARAM
;
664 * Recompute label Y positions.
666 p_ptr
->label_uy
= menu
->p_fnt_pad
+ menu
->p_fnt_info
->max_bounds
.ascent
;
667 p_ptr
->label_ly
= (menu
->p_height
- menu
->p_fnt_pad
- menu
->p_fnt_info
->max_bounds
.descent
);
670 * All went well, return successfully.
672 _XMErrorCode
= XME_NO_ERROR
;
679 * _XMRecomputeSelection - Internal subroutine to recompute
680 * selection window dependencies.
683 _XMRecomputeSelection(register Display
*display
, register XMenu
*menu
, register XMSelect
*s_ptr
, register int s_num
)
685 /* Menu object being recomputed. */
686 /* Selection pointer. */
687 /* Selection sequence number. */
689 register Bool config_s
= False
; /* Reconfigure selection window? */
690 XWindowChanges
*changes
; /* Values to change in configure. */
691 unsigned long change_mask
; /* Value mask for XConfigureWindow. */
694 * If the selection serial numbers are out of order, begin
695 * resequencing selections. Recompute selection window coordinates
698 * When selections are created they are given a serial number of
699 * -1, this causes this routine to give a new selection
700 * its initial coordinates and serial number.
702 if (s_ptr
->serial
!= s_num
) {
704 * Fix the sequence number.
706 s_ptr
->serial
= s_num
;
708 * Recompute window X and Y coordinates.
710 s_ptr
->window_x
= menu
->s_x_off
;
711 s_ptr
->window_y
= menu
->flag_height
+ (menu
->s_y_off
* s_num
);
713 * We must reconfigure the window.
719 * If the local selection width and height differs from the
720 * menu selection width and height, reset the local values.
723 (s_ptr
->window_w
!= menu
->s_width
) ||
724 (s_ptr
->window_h
!= menu
->s_height
)
727 * We must reconfigure the window.
731 * Reset window width and height.
733 s_ptr
->window_w
= menu
->s_width
;
734 s_ptr
->window_h
= menu
->s_height
;
738 * If we need to reconfigure the selection window do it now.
740 if (config_s
== True
) {
742 * If the selection window has already been created then
743 * reconfigure the existing window, otherwise queue it
744 * for creation with the new configuration.
747 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
748 change_mask
= (CWX
| CWY
| CWWidth
| CWHeight
);
749 changes
= (XWindowChanges
*)malloc(sizeof(XWindowChanges
));
750 changes
->x
= s_ptr
->window_x
;
751 changes
->y
= s_ptr
->window_y
;
752 changes
->width
= s_ptr
->window_w
;
753 changes
->height
= s_ptr
->window_h
;
765 if (_XMWinQueAddSelection(display
, menu
, s_ptr
) == _FAILURE
) {
772 * Recompute label X position.
774 switch (menu
->s_style
) {
776 s_ptr
->label_x
= menu
->s_bdr_width
+ menu
->s_fnt_pad
+ s_ptr
->window_x
;
779 s_ptr
->label_x
= s_ptr
->window_x
+ menu
->s_width
-
780 (s_ptr
->label_width
+ menu
->s_bdr_width
+ menu
->s_fnt_pad
);
783 s_ptr
->label_x
= s_ptr
->window_x
+ ((menu
->s_width
- s_ptr
->label_width
) >> 1);
786 /* Error! Invalid style parameter. */
787 _XMErrorCode
= XME_STYLE_PARAM
;
791 * Recompute label Y position.
793 s_ptr
->label_y
= s_ptr
->window_y
+ menu
->s_fnt_info
->max_bounds
.ascent
+ menu
->s_fnt_pad
+ menu
->s_bdr_width
;
796 * All went well, return successfully.
798 _XMErrorCode
= XME_NO_ERROR
;
805 * _XMTransToOrigin - Internal subroutine to translate the point at
806 * the center of the current pane and selection to the
809 * WARNING! ****** Be certain that all menu dependencies have been
810 * recomputed before calling this routine or
811 * unpredictable results will follow.
813 _XMTransToOrigin(Display
*display
, register XMenu
*menu
, register XMPane
*p_ptr
, register XMSelect
*s_ptr
, int x_pos
, int y_pos
, int *orig_x
, int *orig_y
)
814 /* Not used. Included for consistency. */
815 /* Menu being computed against. */
816 /* Current pane pointer. */
817 /* Current selection pointer. */
818 /* X coordinate of point to translate. */
819 /* Y coordinate of point to translate. */
820 /* Return value X coord. of the menu origin. */
821 /* Return value Y coord. of the menu origin. */
823 register int l_orig_x
; /* Local X coordinate of the menu origin. */
824 register int l_orig_y
; /* Local Y coordinate of the menu origin. */
827 * Translate the menu origin such that the cursor hot point will be in the
828 * center of the desired current selection and pane.
829 * If the current selection pointer is NULL then assume that the hot point
830 * will be in the center of the current pane flag.
835 * Translate from the center of the pane flag to the upper left
836 * of the current pane window.
838 l_orig_x
= x_pos
- (menu
->p_width
>> 1) - menu
->p_bdr_width
;
839 l_orig_y
= y_pos
- (menu
->flag_height
>> 1) - menu
->p_bdr_width
;
843 * First translate from the center of the current selection
844 * to the upper left of the current selection window.
846 l_orig_x
= x_pos
- (menu
->s_width
>> 1);
847 l_orig_y
= y_pos
- (menu
->s_height
>> 1);
850 * Then translate to the upper left of the current pane window.
852 l_orig_x
-= (s_ptr
->window_x
+ menu
->p_bdr_width
);
853 l_orig_y
-= (s_ptr
->window_y
+ menu
->p_bdr_width
);
857 * Finally translate to the upper left of the menu.
859 l_orig_x
-= (p_ptr
->window_x
- menu
->x_pos
);
860 l_orig_y
-= (p_ptr
->window_y
- menu
->y_pos
);
863 * Set the return values.
870 * _XMRefreshPane - Internal subroutine to completely refresh
871 * the contents of a pane.
873 _XMRefreshPane(register Display
*display
, register XMenu
*menu
, register XMPane
*pane
)
875 register XMSelect
*s_list
= pane
->s_list
;
876 register XMSelect
*s_ptr
;
879 * First clear the pane.
881 XClearWindow(display
, pane
->window
);
882 if (!pane
->activated
) {
883 XFillRectangle(display
,
885 menu
->inverse_select_GC
,
886 pane
->label_x
- menu
->p_fnt_pad
,
887 pane
->label_uy
- menu
->p_fnt_info
->max_bounds
.ascent
- menu
->p_fnt_pad
,
888 pane
->label_width
+ (menu
->p_fnt_pad
<< 1),
891 XFillRectangle(display
,
893 menu
->inverse_select_GC
,
894 pane
->label_x
- menu
->p_fnt_pad
,
895 pane
->label_ly
- menu
->p_fnt_info
->max_bounds
.ascent
- menu
->p_fnt_pad
,
896 pane
->label_width
+ (menu
->p_fnt_pad
<< 1),
903 pane
->label_x
, pane
->label_uy
,
904 pane
->label
, pane
->label_length
);
908 pane
->label_x
, pane
->label_ly
,
909 pane
->label
, pane
->label_length
);
915 pane
->label_x
, pane
->label_uy
,
916 pane
->label
, pane
->label_length
);
920 pane
->label_x
, pane
->label_ly
,
921 pane
->label
, pane
->label_length
);
924 * Finally refresh each selection if the pane is activated.
926 if (pane
->activated
) {
927 for (s_ptr
= s_list
->next
; s_ptr
!= s_list
; s_ptr
= s_ptr
->next
)
928 _XMRefreshSelection(display
, menu
, s_ptr
);
937 * _XMRefreshSelection - Internal subroutine that refreshes
938 * a single selection window.
940 _XMRefreshSelection(register Display
*display
, register XMenu
*menu
, register XMSelect
*select
)
942 register int width
= select
->window_w
;
943 register int height
= select
->window_h
;
944 register int bdr_width
= menu
->s_bdr_width
;
946 if (select
->type
== SEPARATOR
) {
948 select
->parent_p
->window
,
949 menu
->normal_select_GC
,
951 select
->window_y
+ height
/ 2,
952 select
->window_x
+ width
,
953 select
->window_y
+ height
/ 2);
955 else if (select
->activated
) {
956 if (menu
->menu_mode
== INVERT
) {
957 XFillRectangle(display
,
958 select
->parent_p
->window
,
959 menu
->normal_select_GC
,
960 select
->window_x
, select
->window_y
,
963 select
->parent_p
->window
,
964 menu
->inverse_select_GC
,
967 select
->label
, select
->label_length
);
972 * Since most drawing routines with arbitrary width lines
973 * are slow compared to raster-ops lets use a raster-op to
977 XDrawRectangle(display
,
978 select
->parent_p
->window
,
979 menu
->normal_select_GC
,
980 select
->window_x
+ (bdr_width
>> 1),
981 select
->window_y
+ (bdr_width
>> 1 ),
985 select
->parent_p
->window
,
986 menu
->normal_select_GC
,
989 select
->label
, select
->label_length
);
994 select
->parent_p
->window
,
995 select
->window_x
, select
->window_y
,
998 if (select
->active
) {
1000 select
->parent_p
->window
,
1001 menu
->normal_select_GC
,
1004 select
->label
, select
->label_length
);
1007 XDrawString(display
,
1008 select
->parent_p
->window
,
1012 select
->label
, select
->label_length
);