1 /* Copyright Massachusetts Institute of Technology 1985 */
6 Copyright (C) 1993, 1994, 2001, 2002, 2003, 2004, 2005, 2006,
7 2007 Free Software Foundation, Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to the
21 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA. */
26 * XMenu: MIT Project Athena, X Window system menu package
28 * XMenuCreate - Creates an X window system menu object.
30 * Author: Tony Della Fera, DEC
39 #ifdef EMACS_BITMAP_FILES
40 #include "../src/bitmaps/dimple1.xbm"
41 #include "../src/bitmaps/dimple3.xbm"
42 #include "../src/bitmaps/gray1.xbm"
43 #include "../src/bitmaps/gray3.xbm"
44 #include "../src/bitmaps/crosswv.xbm"
46 #include "../src/bitmaps/leftptr.xbm"
47 #include "../src/bitmaps/leftpmsk.xbm"
48 #include "../src/bitmaps/rtptr.xbm"
49 #include "../src/bitmaps/rtpmsk.xbm"
50 #include "../src/bitmaps/cntrptr.xbm"
51 #include "../src/bitmaps/cntrpmsk.xbm"
52 #include "../src/bitmaps/stipple.xbm"
57 #include <X11/bitmaps/dimple1>
58 #include <X11/bitmaps/dimple3>
59 #include <X11/bitmaps/gray1>
60 #include <X11/bitmaps/gray3>
61 #include <X11/bitmaps/cross_weave>
63 #include <X11/bitmaps/left_ptr>
64 #include <X11/bitmaps/left_ptrmsk>
65 #include <X11/bitmaps/right_ptr>
66 #include <X11/bitmaps/right_ptrmsk>
67 #include <X11/bitmaps/cntr_ptr>
68 #include <X11/bitmaps/cntr_ptrmsk>
69 #include <X11/bitmaps/stipple>
73 #include "[-.src.bitmaps]dimple1.xbm"
74 #include "[-.src.bitmaps]dimple3.xbm"
75 #include "[-.src.bitmaps]gray1.xbm"
76 #include "[-.src.bitmaps]gray3.xbm"
77 #include "[-.src.bitmaps]crosswv.xbm"
79 #include "[-.src.bitmaps]leftptr.xbm"
80 #include "[-.src.bitmaps]leftpmsk.xbm"
81 #include "[-.src.bitmaps]rtptr.xbm"
82 #include "[-.src.bitmaps]rtpmsk.xbm"
83 #include "[-.src.bitmaps]cntrptr.xbm"
84 #include "[-.src.bitmaps]cntrpmsk.xbm"
85 #include "[-.src.bitmaps]stipple.xbm"
88 #endif /* not EMACS_BITMAP_FILES */
92 #define DEF_MENU_STYLE LEFT
93 #define DEF_MENU_MODE BOX
94 #define DEF_INACT_PNUM 3
95 #define MAX_INACT_PNUM 4
97 #define DEF_P_STYLE CENTER
99 #define DEF_P_EVENTS (EnterWindowMask | ExposureMask)
100 #define DEF_P_FNT_NAME "fixed"
101 #define DEF_P_SPREAD 0.5
102 #define DEF_P_BDR_WIDTH 2
104 #define DEF_S_STYLE LEFT
105 #define DEF_S_EVENTS (EnterWindowMask | LeaveWindowMask)
106 #define DEF_S_FNT_NAME "fixed"
107 #define DEF_S_SPREAD 0.10
108 #define DEF_S_BDR_WIDTH 1
110 #define XASSOC_TABLE_SIZE 64
112 #define TILE_BUF_SIZE 5
116 char *x_get_resource_string ();
121 XAllocDisplayColor(display
, map
, colorName
, color
, junk
)
128 return (colorName
!=0 &&
129 XParseColor(display
, map
, colorName
, color
) &&
130 XAllocColor(display
, map
, color
));
135 XMenuCreate(display
, parent
, def_env
)
136 Display
*display
; /* ID of previously opened display */
137 Window parent
; /* Window ID of the menu's parent window. */
138 register char *def_env
; /* X Defaults program environment name. */
140 register int i
; /* Loop counter. */
141 register int j
; /* Loop counter. */
142 register char *def_val
; /* X Default value temp variable. */
144 register XMenu
*menu
; /* Pointer to the new menu. */
145 XMStyle menu_style
; /* Menu display style. */
146 XMMode menu_mode
; /* Menu display mode. */
147 XMPane
*pane
; /* Pane list header. */
148 XAssocTable
*assoc_tab
; /* XAssocTable pointer. */
150 int freeze
; /* Freeze server mode. */
151 int reverse
; /* Reverse video mode. */
153 XMStyle p_style
; /* Pane display style. */
154 char *p_fnt_name
; /* Flag font name. */
155 XFontStruct
*p_fnt_info
; /* Flag font structure */
156 int p_fnt_pad
; /* Flag font padding in pixels. */
157 double p_spread
; /* Pane spread in flag height fractions. */
158 int p_fnt_height
; /* Pane character height. */
159 int p_bdr_width
; /* Pane border width. */
160 int flag_height
; /* Flag window height. */
161 int p_height
; /* Pane window height. */
162 int p_x_off
; /* Pane X offset. */
163 int p_y_off
; /* Pane Y offset. */
164 GC pane_GC
; /* Pane graphics context. */
166 XMStyle s_style
; /* Selection display style. */
167 char *s_fnt_name
; /* Selection font name. */
168 XFontStruct
*s_fnt_info
; /* Selection font structure. */
169 int s_fnt_pad
; /* Selection font padding in pixels. */
170 int s_fnt_height
; /* Selection font character height */
171 double s_spread
; /* Select spread in line height fractions. */
172 int s_bdr_width
; /* Highlight border width. */
173 int s_height
; /* Selection window height. */
174 int s_x_off
; /* Selection window X offset. */
175 int s_y_off
; /* Selection window Y offset. */
176 GC normal_select_GC
; /* GC used for normal video selection. */
177 GC inverse_select_GC
; /* GC used for inverse video selection. */
178 GC inact_GC
; /* GC for inactive pane header and */
180 GC inact_GC_noexpose
;
182 XColor color_def
; /* Temp color definition holder. */
183 XColor screen_def
; /* Temp screen color definition holder */
184 XColor p_bdr_color
; /* Color of border. */
185 XColor s_bdr_color
; /* Color of highlight. */
186 XColor p_frg_color
; /* Color of pane foreground color. */
187 XColor s_frg_color
; /* Color of selection foreground. */
188 XColor bkgnd_color
; /* Color of background.. */
189 XColor mouse_color
; /* Color of mouse cursor. */
190 Cursor mouse_cursor
; /* Mouse cursor. */
191 Pixmap inact_bitmap
; /* Menu inactive pixmap. */
193 int inact_pnum
; /* Inactive background pattern number. */
195 Pixel p_bdr_pixel
; /* Pane border pixel. */
196 Pixel s_bdr_pixel
; /* Selection border pixel. */
197 Pixel p_frg_pixel
; /* Pane foreground pixel. */
198 Pixel s_frg_pixel
; /* Selection foreground pixel. */
199 Pixel bkgnd_pixel
; /* Menu background pixel. */
204 int status
; /* Return code from XReadBitmapFile. */
206 Pixmap cursor
; /* Cursor pixmap holder. */
207 Pixmap cursor_mask
; /* Cursor mask pixmap holder. */
208 Pixmap stipple_pixmap
; /* Stipple mask for half-tone text. */
209 unsigned long valuemask
;
212 Window root
= RootWindow (display
, DefaultScreen (display
));
215 * Calloc the XMenu structure and the initial pane.
217 menu
= (XMenu
*)calloc(1, sizeof(XMenu
));
219 _XMErrorCode
= XME_CALLOC
;
222 pane
= (XMPane
*)calloc(1, sizeof(XMPane
));
224 _XMErrorCode
= XME_CALLOC
;
229 * Create the XAssocTable
231 assoc_tab
= (XAssocTable
*)XCreateAssocTable(XASSOC_TABLE_SIZE
);
232 if(assoc_tab
== NULL
) {
233 _XMErrorCode
= XME_CREATE_ASSOC
;
238 * Set up the default environment name.
240 if (def_env
== NULL
|| *def_env
== '\0') def_env
= "XMenu";
243 * Set up internal fail-safe defaults.
246 reverse
= DEF_REVERSE
;
247 menu_style
= DEF_MENU_STYLE
;
248 menu_mode
= DEF_MENU_MODE
;
249 inact_pnum
= DEF_INACT_PNUM
;
251 p_style
= DEF_P_STYLE
;
252 p_spread
= DEF_P_SPREAD
;
253 p_fnt_name
= DEF_P_FNT_NAME
;
254 p_bdr_width
= DEF_P_BDR_WIDTH
;
256 s_style
= DEF_S_STYLE
;
257 s_spread
= DEF_S_SPREAD
;
258 s_fnt_name
= DEF_S_FNT_NAME
;
259 s_bdr_width
= DEF_S_BDR_WIDTH
;
262 * Get default values from X.
264 def_val
= x_get_resource_string ("menuFreeze", "MenuFreeze");
265 if (def_val
!= NULL
) {
266 if (strcmp(def_val
, "on") == 0) freeze
= 1;
267 else if (strcmp(def_val
, "off") == 0) freeze
= 0;
270 def_val
= x_get_resource_string ("menuReverseVideo", "MenuReverseVideo");
271 if (def_val
!= NULL
) {
272 if (strcmp(def_val
, "on") == 0) reverse
= 1;
273 else if (strcmp(def_val
, "off") == 0) reverse
= 0;
276 def_val
= x_get_resource_string ("menuStyle", "MenuStyle");
277 if (def_val
!= NULL
) {
278 if (strcmp(def_val
, "right_hand") == 0) menu_style
= RIGHT
;
279 else if (strcmp(def_val
, "left_hand") == 0) menu_style
= LEFT
;
280 else if (strcmp(def_val
, "center") == 0) menu_style
= CENTER
;
283 def_val
= x_get_resource_string ("menuMode", "MenuMode");
284 if (def_val
!= NULL
) {
285 if (strcmp(def_val
, "box") == 0) menu_mode
= BOX
;
286 else if (strcmp(def_val
, "invert") == 0) menu_mode
= INVERT
;
289 def_val
= x_get_resource_string ("menuMouse", "MenuMouse");
292 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
293 XAllocDisplayColor(display
,
294 DefaultColormap(display
, DefaultScreen(display
)),
296 &mouse_color
, &color_def
)
299 XAllocDisplayColor(display
,
300 DefaultColormap(display
, DefaultScreen(display
)),
302 &mouse_color
, &color_def
)
305 else if (XAllocDisplayColor(display
,
306 DefaultColormap(display
, DefaultScreen(display
)),
308 &mouse_color
, &color_def
)
313 def_val
= x_get_resource_string ("menuBackground", "MenuBackground");
316 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
317 XAllocDisplayColor(display
,
318 DefaultColormap(display
, DefaultScreen(display
)),
320 &bkgnd_color
, &color_def
)
323 XAllocDisplayColor(display
,
324 DefaultColormap(display
, DefaultScreen(display
)),
326 &bkgnd_color
, &color_def
)
328 else if (XAllocDisplayColor(display
,
329 DefaultColormap(display
, DefaultScreen(display
)),
331 &bkgnd_color
, &color_def
)
335 def_val
= x_get_resource_string ("menuInactivePattern", "MenuInactivePattern");
336 if (def_val
!= NULL
) {
337 if (strcmp(def_val
, "dimple1") == 0) inact_pnum
= 0;
338 else if (strcmp(def_val
, "dimple3") == 0) inact_pnum
= 1;
339 else if (strcmp(def_val
, "gray1") == 0) inact_pnum
= 2;
340 else if (strcmp(def_val
, "gray3") == 0) inact_pnum
= 3;
341 else if (strcmp(def_val
, "cross_weave") == 0) inact_pnum
= 4;
344 def_val
= x_get_resource_string ("paneStyle", "PaneStyle");
345 if (def_val
!= NULL
) {
346 if (strcmp(def_val
, "flush_left") == 0) p_style
= LEFT
;
347 else if (strcmp(def_val
, "flush_right") == 0) p_style
= RIGHT
;
348 else if (strcmp(def_val
, "center") == 0) p_style
= CENTER
;
351 def_val
= x_get_resource_string ("paneFont", "PaneFont");
352 if (def_val
!= NULL
) p_fnt_name
= def_val
;
354 def_val
= x_get_resource_string ("paneForeground", "PaneForeground");
357 DisplayCells(display
, DefaultScreen(display
)) > 2
359 XAllocDisplayColor(display
, DefaultColormap(display
,
360 DefaultScreen(display
)),
362 &p_frg_color
, &color_def
);
364 else if (reverse
) XAllocDisplayColor(display
,
365 DefaultColormap(display
,
366 DefaultScreen(display
)),
368 &p_frg_color
, &color_def
);
369 else XAllocDisplayColor(display
,
370 DefaultColormap(display
, DefaultScreen(display
)),
372 &p_frg_color
, &color_def
);
374 def_val
= x_get_resource_string ("paneBorder", "PaneBorder");
377 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
378 XAllocDisplayColor(display
,
379 DefaultColormap(display
, DefaultScreen(display
)),
381 &p_bdr_color
, &color_def
)
384 XAllocDisplayColor(display
,
385 DefaultColormap(display
, DefaultScreen(display
)),
387 &p_bdr_color
, &color_def
)
389 else XAllocDisplayColor(display
,
390 DefaultColormap(display
, DefaultScreen(display
)),
392 &p_bdr_color
, &color_def
);
394 def_val
= x_get_resource_string ("paneBorderWidth", "PaneBorderWidth");
395 if (def_val
!= NULL
) p_bdr_width
= atoi(def_val
);
397 def_val
= x_get_resource_string ("paneSpread", "PaneSpread");
398 if (def_val
!= NULL
) p_spread
= atof(def_val
);
400 def_val
= x_get_resource_string ("selectionStyle", "SelectionStyle");
401 if (def_val
!= NULL
) {
402 if (strcmp(def_val
, "flush_left") == 0) s_style
= LEFT
;
403 else if (strcmp(def_val
, "flush_right") == 0) s_style
= RIGHT
;
404 else if (strcmp(def_val
, "center") == 0) s_style
= CENTER
;
407 def_val
= x_get_resource_string ("selectionFont", "SelectionFont");
408 if (def_val
!= NULL
) s_fnt_name
= def_val
;
410 def_val
= x_get_resource_string ("selectionForeground", "SelectionForeground");
413 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
414 XAllocDisplayColor(display
,
415 DefaultColormap(display
, DefaultScreen(display
)),
417 &s_frg_color
, &color_def
)
420 XAllocDisplayColor(display
,
421 DefaultColormap(display
, DefaultScreen(display
)),
423 &s_frg_color
, &color_def
)
425 else if (XAllocDisplayColor(display
,
426 DefaultColormap(display
, DefaultScreen(display
)),
428 &s_frg_color
, &color_def
)
433 def_val
= x_get_resource_string ("selectionBorder", "SelectionBorder");
436 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
437 XAllocDisplayColor(display
,
438 DefaultColormap(display
, DefaultScreen(display
)),
440 &s_bdr_color
, &color_def
)
443 XAllocDisplayColor(display
,
444 DefaultColormap(display
, DefaultScreen(display
)),
446 &s_bdr_color
, &color_def
)
448 else if (XAllocDisplayColor(display
,
449 DefaultColormap(display
, DefaultScreen(display
)),
451 &s_bdr_color
, &color_def
)
455 def_val
= x_get_resource_string ("selectionBorderWidth", "SelectionBorderWidth");
456 if (def_val
!= NULL
) s_bdr_width
= atoi(def_val
);
458 def_val
= x_get_resource_string ("selectionSpread", "SelectionSpread");
459 if (def_val
!= NULL
) s_spread
= atof(def_val
);
462 * Create and store the inactive pattern pixmap.
471 data
= (char *)dimple1_bits
;
472 width
= dimple1_width
;
473 height
= dimple1_height
;
477 data
= (char *)dimple3_bits
;
478 width
= dimple3_width
;
479 height
= dimple3_height
;
483 data
= (char *)gray1_bits
;
485 height
= gray1_height
;
489 data
= (char *)gray3_bits
;
491 height
= gray3_height
;
495 data
= (char *)cross_weave_bits
;
496 width
= cross_weave_width
;
497 height
= cross_weave_height
;
503 _XMErrorCode
= XME_STORE_BITMAP
;
508 XCreatePixmapFromBitmapData
509 (display
, root
, data
, width
, height
,
510 p_frg_color
.pixel
, bkgnd_color
.pixel
,
511 DisplayPlanes (display
, DefaultScreen (display
)));
515 * Load the mouse cursor.
518 switch (menu_style
) {
520 cursor
= XCreateBitmapFromData(display
,
525 cursor_mask
= XCreateBitmapFromData(display
,
530 mouse_cursor
= XCreatePixmapCursor(
533 &mouse_color
, &bkgnd_color
,
537 XFreePixmap(display
, cursor
);
538 XFreePixmap(display
, cursor_mask
);
541 cursor
= XCreateBitmapFromData(display
,
546 cursor_mask
= XCreateBitmapFromData(display
,
550 right_ptrmsk_height
);
551 mouse_cursor
= XCreatePixmapCursor(
554 &mouse_color
, &bkgnd_color
,
558 XFreePixmap(display
, cursor
);
559 XFreePixmap(display
, cursor_mask
);
562 cursor
= XCreateBitmapFromData(display
,
567 cursor_mask
= XCreateBitmapFromData(display
,
572 mouse_cursor
= XCreatePixmapCursor(
575 &mouse_color
, &bkgnd_color
,
579 XFreePixmap(display
, cursor
);
580 XFreePixmap(display
, cursor_mask
);
583 /* Error! Invalid style parameter. */
584 _XMErrorCode
= XME_STYLE_PARAM
;
587 if (mouse_cursor
== _X_FAILURE
) {
588 _XMErrorCode
= XME_CREATE_CURSOR
;
593 * Open the pane and selection fonts.
596 p_fnt_info
= XLoadQueryFont(display
, p_fnt_name
);
597 if (p_fnt_info
== NULL
) {
598 _XMErrorCode
= XME_OPEN_FONT
;
603 s_fnt_info
= XLoadQueryFont(display
, s_fnt_name
);
604 if (s_fnt_info
== NULL
) {
605 _XMErrorCode
= XME_OPEN_FONT
;
609 * Calculate the fixed padding value in pixels for each font.
611 p_fnt_height
= p_fnt_info
->max_bounds
.ascent
+ p_fnt_info
->max_bounds
.descent
;
612 s_fnt_height
= s_fnt_info
->max_bounds
.ascent
+ s_fnt_info
->max_bounds
.descent
;
613 p_fnt_pad
= s_spread
* p_fnt_height
;
614 s_fnt_pad
= s_spread
* s_fnt_height
;
617 * Calculate fixed height and offset requirements.
619 flag_height
= p_fnt_height
+ (p_fnt_pad
<< 1);
622 p_y_off
= flag_height
+ p_bdr_width
;
623 p_x_off
= p_y_off
* p_spread
;
625 s_height
= s_fnt_height
+ (s_fnt_pad
<< 1) + (s_bdr_width
<< 1);
630 * Set up the pane list header.
634 pane
->type
= PL_HEADER
;
638 * Initialize the internal pane and selection creation queues.
643 * Create pane, active, and inactive GC's.
645 values
= (XGCValues
*)malloc(sizeof(XGCValues
));
646 valuemask
= (GCForeground
| GCBackground
| GCFont
| GCLineWidth
);
652 values
->foreground
= p_frg_color
.pixel
;
653 values
->background
= bkgnd_color
.pixel
;
654 values
->font
= p_fnt_info
->fid
;
655 values
->line_width
= p_bdr_width
;
663 * Then normal video selection.
666 values
->foreground
= s_frg_color
.pixel
;
667 values
->background
= bkgnd_color
.pixel
;
668 values
->font
= s_fnt_info
->fid
;
669 values
->line_width
= s_bdr_width
;
670 normal_select_GC
= XCreateGC(display
,
675 * Inverse video selection.
678 values
->foreground
= bkgnd_color
.pixel
;
679 values
->background
= s_frg_color
.pixel
;
680 values
->font
= s_fnt_info
->fid
;
681 values
->line_width
= s_bdr_width
;
682 inverse_select_GC
= XCreateGC(display
,
686 stipple_pixmap
= XCreateBitmapFromData(display
,
693 * Finally, inactive pane header and selections
695 valuemask
|= (GCFillStyle
| GCStipple
);
696 values
->foreground
= s_frg_color
.pixel
;
697 values
->background
= bkgnd_color
.pixel
;
698 values
->font
= s_fnt_info
->fid
;
699 values
->line_width
= s_bdr_width
;
700 values
->fill_style
= FillStippled
;
701 values
->stipple
= stipple_pixmap
;
703 inact_GC
= XCreateGC(display
,
708 valuemask
|= (GCGraphicsExposures
);
709 values
->graphics_exposures
= False
;
710 inact_GC_noexpose
= XCreateGC (display
,
716 * Construct the XMenu object.
718 /* -------------------- Menu data -------------------- */
719 menu
->menu_style
= menu_style
;
720 menu
->menu_mode
= menu_mode
;
721 menu
->freeze
= freeze
;
724 menu
->parent
= parent
;
727 menu
->mouse_cursor
= mouse_cursor
;
728 menu
->assoc_tab
= assoc_tab
;
730 /* -------------------- Pane window data -------------------- */
731 menu
->p_style
= p_style
;
732 menu
->p_events
= DEF_P_EVENTS
;
733 menu
->p_fnt_info
= p_fnt_info
;
734 menu
->p_fnt_pad
= p_fnt_pad
;
735 menu
->p_spread
= p_spread
;
736 menu
->p_bdr_width
= p_bdr_width
;
737 menu
->flag_height
= flag_height
;
739 menu
->p_height
= p_height
;
740 menu
->p_x_off
= p_x_off
;
741 menu
->p_y_off
= p_y_off
;
743 menu
->pane_GC
= pane_GC
;
746 /* -------------------- Selection window data -------------------- */
747 menu
->s_style
= s_style
;
748 menu
->s_events
= DEF_S_EVENTS
;
749 menu
->s_fnt_info
= s_fnt_info
;
750 menu
->s_fnt_pad
= s_fnt_pad
;
751 menu
->s_spread
= s_spread
;
752 menu
->s_bdr_width
= s_bdr_width
; /* unnecessary */
754 menu
->s_height
= s_height
;
755 menu
->s_x_off
= s_x_off
;
756 menu
->s_y_off
= s_y_off
;
758 menu
->normal_select_GC
= normal_select_GC
;
759 menu
->inverse_select_GC
= inverse_select_GC
;
760 menu
->inact_GC
= inact_GC
;
761 /* -------------------- Color data -------------------- */
762 menu
->p_bdr_color
= p_bdr_color
.pixel
;
763 menu
->s_bdr_color
= s_bdr_color
.pixel
;
764 menu
->p_frg_color
= p_frg_color
.pixel
;
765 menu
->s_frg_color
= s_frg_color
.pixel
;
766 menu
->bkgnd_color
= bkgnd_color
.pixel
;
767 /* -------------------- Pixmap data -------------------- */
768 menu
->p_bdr_pixmap
= None
;
769 menu
->s_bdr_pixmap
= None
;
770 menu
->p_frg_pixmap
= None
;
771 menu
->s_frg_pixmap
= None
;
772 menu
->bkgnd_pixmap
= None
;
773 menu
->inact_pixmap
= inact_bitmap
;
776 * Return the completed XMenu.
778 _XMErrorCode
= XME_NO_ERROR
;
782 /* arch-tag: 6945b7d2-3b13-40b9-8b6e-56b1b20f3463
783 (do not change this comment) */