1 /* Copyright Massachusetts Institute of Technology 1985 */
2 /* Copyright (C) 2002, 2003, 2004, 2005,
3 2006 Free Software Foundation, Inc. */
8 * XMenu: MIT Project Athena, X Window system menu package
10 * XMenuCreate - Creates an X window system menu object.
12 * Author: Tony Della Fera, DEC
21 #ifdef EMACS_BITMAP_FILES
22 #include "../src/bitmaps/dimple1.xbm"
23 #include "../src/bitmaps/dimple3.xbm"
24 #include "../src/bitmaps/gray1.xbm"
25 #include "../src/bitmaps/gray3.xbm"
26 #include "../src/bitmaps/crosswv.xbm"
28 #include "../src/bitmaps/leftptr.xbm"
29 #include "../src/bitmaps/leftpmsk.xbm"
30 #include "../src/bitmaps/rtptr.xbm"
31 #include "../src/bitmaps/rtpmsk.xbm"
32 #include "../src/bitmaps/cntrptr.xbm"
33 #include "../src/bitmaps/cntrpmsk.xbm"
34 #include "../src/bitmaps/stipple.xbm"
39 #include <X11/bitmaps/dimple1>
40 #include <X11/bitmaps/dimple3>
41 #include <X11/bitmaps/gray1>
42 #include <X11/bitmaps/gray3>
43 #include <X11/bitmaps/cross_weave>
45 #include <X11/bitmaps/left_ptr>
46 #include <X11/bitmaps/left_ptrmsk>
47 #include <X11/bitmaps/right_ptr>
48 #include <X11/bitmaps/right_ptrmsk>
49 #include <X11/bitmaps/cntr_ptr>
50 #include <X11/bitmaps/cntr_ptrmsk>
51 #include <X11/bitmaps/stipple>
55 #include "[-.src.bitmaps]dimple1.xbm"
56 #include "[-.src.bitmaps]dimple3.xbm"
57 #include "[-.src.bitmaps]gray1.xbm"
58 #include "[-.src.bitmaps]gray3.xbm"
59 #include "[-.src.bitmaps]crosswv.xbm"
61 #include "[-.src.bitmaps]leftptr.xbm"
62 #include "[-.src.bitmaps]leftpmsk.xbm"
63 #include "[-.src.bitmaps]rtptr.xbm"
64 #include "[-.src.bitmaps]rtpmsk.xbm"
65 #include "[-.src.bitmaps]cntrptr.xbm"
66 #include "[-.src.bitmaps]cntrpmsk.xbm"
67 #include "[-.src.bitmaps]stipple.xbm"
70 #endif /* not EMACS_BITMAP_FILES */
74 #define DEF_MENU_STYLE LEFT
75 #define DEF_MENU_MODE BOX
76 #define DEF_INACT_PNUM 3
77 #define MAX_INACT_PNUM 4
79 #define DEF_P_STYLE CENTER
81 #define DEF_P_EVENTS (EnterWindowMask | ExposureMask)
82 #define DEF_P_FNT_NAME "fixed"
83 #define DEF_P_SPREAD 0.5
84 #define DEF_P_BDR_WIDTH 2
86 #define DEF_S_STYLE LEFT
87 #define DEF_S_EVENTS (EnterWindowMask | LeaveWindowMask)
88 #define DEF_S_FNT_NAME "fixed"
89 #define DEF_S_SPREAD 0.10
90 #define DEF_S_BDR_WIDTH 1
92 #define XASSOC_TABLE_SIZE 64
94 #define TILE_BUF_SIZE 5
98 char *x_get_resource_string ();
103 XAllocDisplayColor(display
, map
, colorName
, color
, junk
)
110 return (colorName
!=0 &&
111 XParseColor(display
, map
, colorName
, color
) &&
112 XAllocColor(display
, map
, color
));
117 XMenuCreate(display
, parent
, def_env
)
118 Display
*display
; /* ID of previously opened display */
119 Window parent
; /* Window ID of the menu's parent window. */
120 register char *def_env
; /* X Defaults program environment name. */
122 register int i
; /* Loop counter. */
123 register int j
; /* Loop counter. */
124 register char *def_val
; /* X Default value temp variable. */
126 register XMenu
*menu
; /* Pointer to the new menu. */
127 XMStyle menu_style
; /* Menu display style. */
128 XMMode menu_mode
; /* Menu display mode. */
129 XMPane
*pane
; /* Pane list header. */
130 XAssocTable
*assoc_tab
; /* XAssocTable pointer. */
132 int freeze
; /* Freeze server mode. */
133 int reverse
; /* Reverse video mode. */
135 XMStyle p_style
; /* Pane display style. */
136 char *p_fnt_name
; /* Flag font name. */
137 XFontStruct
*p_fnt_info
; /* Flag font structure */
138 int p_fnt_pad
; /* Flag font padding in pixels. */
139 double p_spread
; /* Pane spread in flag height fractions. */
140 int p_fnt_height
; /* Pane character height. */
141 int p_bdr_width
; /* Pane border width. */
142 int flag_height
; /* Flag window height. */
143 int p_height
; /* Pane window height. */
144 int p_x_off
; /* Pane X offset. */
145 int p_y_off
; /* Pane Y offset. */
146 GC pane_GC
; /* Pane graphics context. */
148 XMStyle s_style
; /* Selection display style. */
149 char *s_fnt_name
; /* Selection font name. */
150 XFontStruct
*s_fnt_info
; /* Selection font structure. */
151 int s_fnt_pad
; /* Selection font padding in pixels. */
152 int s_fnt_height
; /* Selection font character height */
153 double s_spread
; /* Select spread in line height fractions. */
154 int s_bdr_width
; /* Highlight border width. */
155 int s_height
; /* Selection window height. */
156 int s_x_off
; /* Selection window X offset. */
157 int s_y_off
; /* Selection window Y offset. */
158 GC normal_select_GC
; /* GC used for normal video selection. */
159 GC inverse_select_GC
; /* GC used for inverse video selection. */
160 GC inact_GC
; /* GC for inactive pane header and */
162 GC inact_GC_noexpose
;
164 XColor color_def
; /* Temp color definition holder. */
165 XColor screen_def
; /* Temp screen color definition holder */
166 XColor p_bdr_color
; /* Color of border. */
167 XColor s_bdr_color
; /* Color of highlight. */
168 XColor p_frg_color
; /* Color of pane foreground color. */
169 XColor s_frg_color
; /* Color of selection foreground. */
170 XColor bkgnd_color
; /* Color of background.. */
171 XColor mouse_color
; /* Color of mouse cursor. */
172 Cursor mouse_cursor
; /* Mouse cursor. */
173 Pixmap inact_bitmap
; /* Menu inactive pixmap. */
175 int inact_pnum
; /* Inactive background pattern number. */
177 Pixel p_bdr_pixel
; /* Pane border pixel. */
178 Pixel s_bdr_pixel
; /* Selection border pixel. */
179 Pixel p_frg_pixel
; /* Pane foreground pixel. */
180 Pixel s_frg_pixel
; /* Selection foreground pixel. */
181 Pixel bkgnd_pixel
; /* Menu background pixel. */
186 int status
; /* Return code from XReadBitmapFile. */
188 Pixmap cursor
; /* Cursor pixmap holder. */
189 Pixmap cursor_mask
; /* Cursor mask pixmap holder. */
190 Pixmap stipple_pixmap
; /* Stipple mask for half-tone text. */
191 unsigned long valuemask
;
194 Window root
= RootWindow (display
, DefaultScreen (display
));
197 * Calloc the XMenu structure and the initial pane.
199 menu
= (XMenu
*)calloc(1, sizeof(XMenu
));
201 _XMErrorCode
= XME_CALLOC
;
204 pane
= (XMPane
*)calloc(1, sizeof(XMPane
));
206 _XMErrorCode
= XME_CALLOC
;
211 * Create the XAssocTable
213 assoc_tab
= (XAssocTable
*)XCreateAssocTable(XASSOC_TABLE_SIZE
);
214 if(assoc_tab
== NULL
) {
215 _XMErrorCode
= XME_CREATE_ASSOC
;
220 * Set up the default environment name.
222 if (def_env
== NULL
|| *def_env
== '\0') def_env
= "XMenu";
225 * Set up internal fail-safe defaults.
228 reverse
= DEF_REVERSE
;
229 menu_style
= DEF_MENU_STYLE
;
230 menu_mode
= DEF_MENU_MODE
;
231 inact_pnum
= DEF_INACT_PNUM
;
233 p_style
= DEF_P_STYLE
;
234 p_spread
= DEF_P_SPREAD
;
235 p_fnt_name
= DEF_P_FNT_NAME
;
236 p_bdr_width
= DEF_P_BDR_WIDTH
;
238 s_style
= DEF_S_STYLE
;
239 s_spread
= DEF_S_SPREAD
;
240 s_fnt_name
= DEF_S_FNT_NAME
;
241 s_bdr_width
= DEF_S_BDR_WIDTH
;
244 * Get default values from X.
246 def_val
= x_get_resource_string ("menuFreeze", "MenuFreeze");
247 if (def_val
!= NULL
) {
248 if (strcmp(def_val
, "on") == 0) freeze
= 1;
249 else if (strcmp(def_val
, "off") == 0) freeze
= 0;
252 def_val
= x_get_resource_string ("menuReverseVideo", "MenuReverseVideo");
253 if (def_val
!= NULL
) {
254 if (strcmp(def_val
, "on") == 0) reverse
= 1;
255 else if (strcmp(def_val
, "off") == 0) reverse
= 0;
258 def_val
= x_get_resource_string ("menuStyle", "MenuStyle");
259 if (def_val
!= NULL
) {
260 if (strcmp(def_val
, "right_hand") == 0) menu_style
= RIGHT
;
261 else if (strcmp(def_val
, "left_hand") == 0) menu_style
= LEFT
;
262 else if (strcmp(def_val
, "center") == 0) menu_style
= CENTER
;
265 def_val
= x_get_resource_string ("menuMode", "MenuMode");
266 if (def_val
!= NULL
) {
267 if (strcmp(def_val
, "box") == 0) menu_mode
= BOX
;
268 else if (strcmp(def_val
, "invert") == 0) menu_mode
= INVERT
;
271 def_val
= x_get_resource_string ("menuMouse", "MenuMouse");
274 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
275 XAllocDisplayColor(display
,
276 DefaultColormap(display
, DefaultScreen(display
)),
278 &mouse_color
, &color_def
)
281 XAllocDisplayColor(display
,
282 DefaultColormap(display
, DefaultScreen(display
)),
284 &mouse_color
, &color_def
)
287 else if (XAllocDisplayColor(display
,
288 DefaultColormap(display
, DefaultScreen(display
)),
290 &mouse_color
, &color_def
)
295 def_val
= x_get_resource_string ("menuBackground", "MenuBackground");
298 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
299 XAllocDisplayColor(display
,
300 DefaultColormap(display
, DefaultScreen(display
)),
302 &bkgnd_color
, &color_def
)
305 XAllocDisplayColor(display
,
306 DefaultColormap(display
, DefaultScreen(display
)),
308 &bkgnd_color
, &color_def
)
310 else if (XAllocDisplayColor(display
,
311 DefaultColormap(display
, DefaultScreen(display
)),
313 &bkgnd_color
, &color_def
)
317 def_val
= x_get_resource_string ("menuInactivePattern", "MenuInactivePattern");
318 if (def_val
!= NULL
) {
319 if (strcmp(def_val
, "dimple1") == 0) inact_pnum
= 0;
320 else if (strcmp(def_val
, "dimple3") == 0) inact_pnum
= 1;
321 else if (strcmp(def_val
, "gray1") == 0) inact_pnum
= 2;
322 else if (strcmp(def_val
, "gray3") == 0) inact_pnum
= 3;
323 else if (strcmp(def_val
, "cross_weave") == 0) inact_pnum
= 4;
326 def_val
= x_get_resource_string ("paneStyle", "PaneStyle");
327 if (def_val
!= NULL
) {
328 if (strcmp(def_val
, "flush_left") == 0) p_style
= LEFT
;
329 else if (strcmp(def_val
, "flush_right") == 0) p_style
= RIGHT
;
330 else if (strcmp(def_val
, "center") == 0) p_style
= CENTER
;
333 def_val
= x_get_resource_string ("paneFont", "PaneFont");
334 if (def_val
!= NULL
) p_fnt_name
= def_val
;
336 def_val
= x_get_resource_string ("paneForeground", "PaneForeground");
339 DisplayCells(display
, DefaultScreen(display
)) > 2
341 XAllocDisplayColor(display
, DefaultColormap(display
,
342 DefaultScreen(display
)),
344 &p_frg_color
, &color_def
);
346 else if (reverse
) XAllocDisplayColor(display
,
347 DefaultColormap(display
,
348 DefaultScreen(display
)),
350 &p_frg_color
, &color_def
);
351 else XAllocDisplayColor(display
,
352 DefaultColormap(display
, DefaultScreen(display
)),
354 &p_frg_color
, &color_def
);
356 def_val
= x_get_resource_string ("paneBorder", "PaneBorder");
359 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
360 XAllocDisplayColor(display
,
361 DefaultColormap(display
, DefaultScreen(display
)),
363 &p_bdr_color
, &color_def
)
366 XAllocDisplayColor(display
,
367 DefaultColormap(display
, DefaultScreen(display
)),
369 &p_bdr_color
, &color_def
)
371 else XAllocDisplayColor(display
,
372 DefaultColormap(display
, DefaultScreen(display
)),
374 &p_bdr_color
, &color_def
);
376 def_val
= x_get_resource_string ("paneBorderWidth", "PaneBorderWidth");
377 if (def_val
!= NULL
) p_bdr_width
= atoi(def_val
);
379 def_val
= x_get_resource_string ("paneSpread", "PaneSpread");
380 if (def_val
!= NULL
) p_spread
= atof(def_val
);
382 def_val
= x_get_resource_string ("selectionStyle", "SelectionStyle");
383 if (def_val
!= NULL
) {
384 if (strcmp(def_val
, "flush_left") == 0) s_style
= LEFT
;
385 else if (strcmp(def_val
, "flush_right") == 0) s_style
= RIGHT
;
386 else if (strcmp(def_val
, "center") == 0) s_style
= CENTER
;
389 def_val
= x_get_resource_string ("selectionFont", "SelectionFont");
390 if (def_val
!= NULL
) s_fnt_name
= def_val
;
392 def_val
= x_get_resource_string ("selectionForeground", "SelectionForeground");
395 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
396 XAllocDisplayColor(display
,
397 DefaultColormap(display
, DefaultScreen(display
)),
399 &s_frg_color
, &color_def
)
402 XAllocDisplayColor(display
,
403 DefaultColormap(display
, DefaultScreen(display
)),
405 &s_frg_color
, &color_def
)
407 else if (XAllocDisplayColor(display
,
408 DefaultColormap(display
, DefaultScreen(display
)),
410 &s_frg_color
, &color_def
)
415 def_val
= x_get_resource_string ("selectionBorder", "SelectionBorder");
418 DisplayCells(display
, DefaultScreen(display
)) > 2 &&
419 XAllocDisplayColor(display
,
420 DefaultColormap(display
, DefaultScreen(display
)),
422 &s_bdr_color
, &color_def
)
425 XAllocDisplayColor(display
,
426 DefaultColormap(display
, DefaultScreen(display
)),
428 &s_bdr_color
, &color_def
)
430 else if (XAllocDisplayColor(display
,
431 DefaultColormap(display
, DefaultScreen(display
)),
433 &s_bdr_color
, &color_def
)
437 def_val
= x_get_resource_string ("selectionBorderWidth", "SelectionBorderWidth");
438 if (def_val
!= NULL
) s_bdr_width
= atoi(def_val
);
440 def_val
= x_get_resource_string ("selectionSpread", "SelectionSpread");
441 if (def_val
!= NULL
) s_spread
= atof(def_val
);
444 * Create and store the inactive pattern pixmap.
453 data
= (char *)dimple1_bits
;
454 width
= dimple1_width
;
455 height
= dimple1_height
;
459 data
= (char *)dimple3_bits
;
460 width
= dimple3_width
;
461 height
= dimple3_height
;
465 data
= (char *)gray1_bits
;
467 height
= gray1_height
;
471 data
= (char *)gray3_bits
;
473 height
= gray3_height
;
477 data
= (char *)cross_weave_bits
;
478 width
= cross_weave_width
;
479 height
= cross_weave_height
;
485 _XMErrorCode
= XME_STORE_BITMAP
;
490 XCreatePixmapFromBitmapData
491 (display
, root
, data
, width
, height
,
492 p_frg_color
.pixel
, bkgnd_color
.pixel
,
493 DisplayPlanes (display
, DefaultScreen (display
)));
497 * Load the mouse cursor.
500 switch (menu_style
) {
502 cursor
= XCreateBitmapFromData(display
,
507 cursor_mask
= XCreateBitmapFromData(display
,
512 mouse_cursor
= XCreatePixmapCursor(
515 &mouse_color
, &bkgnd_color
,
519 XFreePixmap(display
, cursor
);
520 XFreePixmap(display
, cursor_mask
);
523 cursor
= XCreateBitmapFromData(display
,
528 cursor_mask
= XCreateBitmapFromData(display
,
532 right_ptrmsk_height
);
533 mouse_cursor
= XCreatePixmapCursor(
536 &mouse_color
, &bkgnd_color
,
540 XFreePixmap(display
, cursor
);
541 XFreePixmap(display
, cursor_mask
);
544 cursor
= XCreateBitmapFromData(display
,
549 cursor_mask
= XCreateBitmapFromData(display
,
554 mouse_cursor
= XCreatePixmapCursor(
557 &mouse_color
, &bkgnd_color
,
561 XFreePixmap(display
, cursor
);
562 XFreePixmap(display
, cursor_mask
);
565 /* Error! Invalid style parameter. */
566 _XMErrorCode
= XME_STYLE_PARAM
;
569 if (mouse_cursor
== _X_FAILURE
) {
570 _XMErrorCode
= XME_CREATE_CURSOR
;
575 * Open the pane and selection fonts.
578 p_fnt_info
= XLoadQueryFont(display
, p_fnt_name
);
579 if (p_fnt_info
== NULL
) {
580 _XMErrorCode
= XME_OPEN_FONT
;
585 s_fnt_info
= XLoadQueryFont(display
, s_fnt_name
);
586 if (s_fnt_info
== NULL
) {
587 _XMErrorCode
= XME_OPEN_FONT
;
591 * Calculate the fixed padding value in pixels for each font.
593 p_fnt_height
= p_fnt_info
->max_bounds
.ascent
+ p_fnt_info
->max_bounds
.descent
;
594 s_fnt_height
= s_fnt_info
->max_bounds
.ascent
+ s_fnt_info
->max_bounds
.descent
;
595 p_fnt_pad
= s_spread
* p_fnt_height
;
596 s_fnt_pad
= s_spread
* s_fnt_height
;
599 * Calculate fixed height and offset requirements.
601 flag_height
= p_fnt_height
+ (p_fnt_pad
<< 1);
604 p_y_off
= flag_height
+ p_bdr_width
;
605 p_x_off
= p_y_off
* p_spread
;
607 s_height
= s_fnt_height
+ (s_fnt_pad
<< 1) + (s_bdr_width
<< 1);
612 * Set up the pane list header.
616 pane
->type
= PL_HEADER
;
620 * Initialize the internal pane and selection creation queues.
625 * Create pane, active, and inactive GC's.
627 values
= (XGCValues
*)malloc(sizeof(XGCValues
));
628 valuemask
= (GCForeground
| GCBackground
| GCFont
| GCLineWidth
);
634 values
->foreground
= p_frg_color
.pixel
;
635 values
->background
= bkgnd_color
.pixel
;
636 values
->font
= p_fnt_info
->fid
;
637 values
->line_width
= p_bdr_width
;
645 * Then normal video selection.
648 values
->foreground
= s_frg_color
.pixel
;
649 values
->background
= bkgnd_color
.pixel
;
650 values
->font
= s_fnt_info
->fid
;
651 values
->line_width
= s_bdr_width
;
652 normal_select_GC
= XCreateGC(display
,
657 * Inverse video selection.
660 values
->foreground
= bkgnd_color
.pixel
;
661 values
->background
= s_frg_color
.pixel
;
662 values
->font
= s_fnt_info
->fid
;
663 values
->line_width
= s_bdr_width
;
664 inverse_select_GC
= XCreateGC(display
,
668 stipple_pixmap
= XCreateBitmapFromData(display
,
675 * Finally, inactive pane header and selections
677 valuemask
|= (GCFillStyle
| GCStipple
);
678 values
->foreground
= s_frg_color
.pixel
;
679 values
->background
= bkgnd_color
.pixel
;
680 values
->font
= s_fnt_info
->fid
;
681 values
->line_width
= s_bdr_width
;
682 values
->fill_style
= FillStippled
;
683 values
->stipple
= stipple_pixmap
;
685 inact_GC
= XCreateGC(display
,
690 valuemask
|= (GCGraphicsExposures
);
691 values
->graphics_exposures
= False
;
692 inact_GC_noexpose
= XCreateGC (display
,
698 * Construct the XMenu object.
700 /* -------------------- Menu data -------------------- */
701 menu
->menu_style
= menu_style
;
702 menu
->menu_mode
= menu_mode
;
703 menu
->freeze
= freeze
;
706 menu
->parent
= parent
;
709 menu
->mouse_cursor
= mouse_cursor
;
710 menu
->assoc_tab
= assoc_tab
;
712 /* -------------------- Pane window data -------------------- */
713 menu
->p_style
= p_style
;
714 menu
->p_events
= DEF_P_EVENTS
;
715 menu
->p_fnt_info
= p_fnt_info
;
716 menu
->p_fnt_pad
= p_fnt_pad
;
717 menu
->p_spread
= p_spread
;
718 menu
->p_bdr_width
= p_bdr_width
;
719 menu
->flag_height
= flag_height
;
721 menu
->p_height
= p_height
;
722 menu
->p_x_off
= p_x_off
;
723 menu
->p_y_off
= p_y_off
;
725 menu
->pane_GC
= pane_GC
;
728 /* -------------------- Selection window data -------------------- */
729 menu
->s_style
= s_style
;
730 menu
->s_events
= DEF_S_EVENTS
;
731 menu
->s_fnt_info
= s_fnt_info
;
732 menu
->s_fnt_pad
= s_fnt_pad
;
733 menu
->s_spread
= s_spread
;
734 menu
->s_bdr_width
= s_bdr_width
; /* unnecessary */
736 menu
->s_height
= s_height
;
737 menu
->s_x_off
= s_x_off
;
738 menu
->s_y_off
= s_y_off
;
740 menu
->normal_select_GC
= normal_select_GC
;
741 menu
->inverse_select_GC
= inverse_select_GC
;
742 menu
->inact_GC
= inact_GC
;
743 /* -------------------- Color data -------------------- */
744 menu
->p_bdr_color
= p_bdr_color
.pixel
;
745 menu
->s_bdr_color
= s_bdr_color
.pixel
;
746 menu
->p_frg_color
= p_frg_color
.pixel
;
747 menu
->s_frg_color
= s_frg_color
.pixel
;
748 menu
->bkgnd_color
= bkgnd_color
.pixel
;
749 /* -------------------- Pixmap data -------------------- */
750 menu
->p_bdr_pixmap
= None
;
751 menu
->s_bdr_pixmap
= None
;
752 menu
->p_frg_pixmap
= None
;
753 menu
->s_frg_pixmap
= None
;
754 menu
->bkgnd_pixmap
= None
;
755 menu
->inact_pixmap
= inact_bitmap
;
758 * Return the completed XMenu.
760 _XMErrorCode
= XME_NO_ERROR
;
764 /* arch-tag: 6945b7d2-3b13-40b9-8b6e-56b1b20f3463
765 (do not change this comment) */