Mercurial > vim
annotate src/gui_athena.c @ 7821:81794242a275 v7.4.1207
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jan 30 16:39:25 2016 +0100
patch 7.4.1207
Problem: Using old style function declarations.
Solution: Change to new style function declarations. (script by Hirohito
Higashi)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 30 Jan 2016 16:45:04 +0100 |
parents | a1e71a01dbd6 |
children | 7898da204b98 |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * GUI/Motif support by Robert Webb | |
5 * Athena port by Bill Foster | |
6 * | |
7 * Do ":help uganda" in Vim to read copying and usage conditions. | |
8 * Do ":help credits" in Vim to see a list of people who contributed. | |
9 * See README.txt for an overview of the Vim source code. | |
10 */ | |
11 | |
12 #include <X11/StringDefs.h> | |
13 #include <X11/Intrinsic.h> | |
14 #ifdef FEAT_GUI_NEXTAW | |
15 # include <X11/neXtaw/Form.h> | |
16 # include <X11/neXtaw/SimpleMenu.h> | |
17 # include <X11/neXtaw/MenuButton.h> | |
18 # include <X11/neXtaw/SmeBSB.h> | |
19 # include <X11/neXtaw/SmeLine.h> | |
20 # include <X11/neXtaw/Box.h> | |
21 # include <X11/neXtaw/Dialog.h> | |
22 # include <X11/neXtaw/Text.h> | |
23 # include <X11/neXtaw/AsciiText.h> | |
24 # include <X11/neXtaw/Scrollbar.h> | |
25 #else | |
26 # include <X11/Xaw/Form.h> | |
27 # include <X11/Xaw/SimpleMenu.h> | |
28 # include <X11/Xaw/MenuButton.h> | |
29 # include <X11/Xaw/SmeBSB.h> | |
30 # include <X11/Xaw/SmeLine.h> | |
31 # include <X11/Xaw/Box.h> | |
32 # include <X11/Xaw/Dialog.h> | |
33 # include <X11/Xaw/Text.h> | |
34 # include <X11/Xaw/AsciiText.h> | |
35 #endif /* FEAT_GUI_NEXTAW */ | |
36 | |
37 #include "vim.h" | |
38 #ifndef FEAT_GUI_NEXTAW | |
39 # include "gui_at_sb.h" | |
40 #endif | |
41 | |
42 extern Widget vimShell; | |
43 | |
44 static Widget vimForm = (Widget)0; | |
215 | 45 Widget textArea = (Widget)0; |
7 | 46 #ifdef FEAT_MENU |
47 static Widget menuBar = (Widget)0; | |
48 static XtIntervalId timer = 0; /* 0 = expired, otherwise active */ | |
49 | |
50 /* Used to figure out menu ordering */ | |
51 static vimmenu_T *a_cur_menu = NULL; | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
52 static Cardinal athena_calculate_ins_pos(Widget); |
7 | 53 |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
54 static Pixmap gui_athena_create_pullright_pixmap(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
55 static void gui_athena_menu_timeout(XtPointer, XtIntervalId *); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
56 static void gui_athena_popup_callback(Widget, XtPointer, XtPointer); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
57 static void gui_athena_delayed_arm_action(Widget, XEvent *, String *, |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
58 Cardinal *); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
59 static void gui_athena_popdown_submenus_action(Widget, XEvent *, |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
60 String *, Cardinal *); |
7 | 61 static XtActionsRec pullAction[2] = { |
62 { "menu-delayedpopup", (XtActionProc)gui_athena_delayed_arm_action}, | |
63 { "menu-popdownsubmenus", (XtActionProc)gui_athena_popdown_submenus_action} | |
64 }; | |
65 #endif | |
66 | |
67 #ifdef FEAT_TOOLBAR | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
68 static void gui_mch_reset_focus(void); |
7 | 69 static Widget toolBar = (Widget)0; |
70 #endif | |
71 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
72 static void gui_athena_scroll_cb_jump(Widget, XtPointer, XtPointer); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
73 static void gui_athena_scroll_cb_scroll(Widget, XtPointer, XtPointer); |
7 | 74 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU) |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
75 static void gui_athena_menu_colors(Widget id); |
7 | 76 #endif |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
77 static void gui_athena_scroll_colors(Widget id); |
7 | 78 |
79 #ifdef FEAT_MENU | |
80 static XtTranslations popupTrans, parentTrans, menuTrans, supermenuTrans; | |
81 static Pixmap pullerBitmap = None; | |
82 static int puller_width = 0; | |
83 #endif | |
84 | |
85 /* | |
86 * Scrollbar callback (XtNjumpProc) for when the scrollbar is dragged with the | |
87 * left or middle mouse button. | |
88 */ | |
89 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
90 gui_athena_scroll_cb_jump( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
91 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
92 XtPointer client_data, call_data) |
7 | 93 { |
94 scrollbar_T *sb, *sb_info; | |
95 long value; | |
96 | |
97 sb = gui_find_scrollbar((long)client_data); | |
98 | |
99 if (sb == NULL) | |
100 return; | |
101 else if (sb->wp != NULL) /* Left or right scrollbar */ | |
102 { | |
103 /* | |
104 * Careful: need to get scrollbar info out of first (left) scrollbar | |
105 * for window, but keep real scrollbar too because we must pass it to | |
106 * gui_drag_scrollbar(). | |
107 */ | |
108 sb_info = &sb->wp->w_scrollbars[0]; | |
109 } | |
110 else /* Bottom scrollbar */ | |
111 sb_info = sb; | |
112 | |
113 value = (long)(*((float *)call_data) * (float)(sb_info->max + 1) + 0.001); | |
114 if (value > sb_info->max) | |
115 value = sb_info->max; | |
116 | |
117 gui_drag_scrollbar(sb, value, TRUE); | |
118 } | |
119 | |
120 /* | |
121 * Scrollbar callback (XtNscrollProc) for paging up or down with the left or | |
122 * right mouse buttons. | |
123 */ | |
124 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
125 gui_athena_scroll_cb_scroll( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
126 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
127 XtPointer client_data, call_data) |
7 | 128 { |
129 scrollbar_T *sb, *sb_info; | |
130 long value; | |
131 int data = (int)(long)call_data; | |
132 int page; | |
133 | |
134 sb = gui_find_scrollbar((long)client_data); | |
135 | |
136 if (sb == NULL) | |
137 return; | |
138 if (sb->wp != NULL) /* Left or right scrollbar */ | |
139 { | |
140 /* | |
141 * Careful: need to get scrollbar info out of first (left) scrollbar | |
142 * for window, but keep real scrollbar too because we must pass it to | |
143 * gui_drag_scrollbar(). | |
144 */ | |
145 sb_info = &sb->wp->w_scrollbars[0]; | |
146 | |
147 if (sb_info->size > 5) | |
148 page = sb_info->size - 2; /* use two lines of context */ | |
149 else | |
150 page = sb_info->size; | |
151 #ifdef FEAT_GUI_NEXTAW | |
152 if (data < 0) | |
153 { | |
154 data = (data - gui.char_height + 1) / gui.char_height; | |
155 if (data > -sb_info->size) | |
156 data = -1; | |
157 else | |
158 data = -page; | |
159 } | |
160 else if (data > 0) | |
161 { | |
162 data = (data + gui.char_height - 1) / gui.char_height; | |
163 if (data < sb_info->size) | |
164 data = 1; | |
165 else | |
166 data = page; | |
167 } | |
168 #else | |
169 switch (data) | |
170 { | |
171 case ONE_LINE_DATA: data = 1; break; | |
172 case -ONE_LINE_DATA: data = -1; break; | |
173 case ONE_PAGE_DATA: data = page; break; | |
174 case -ONE_PAGE_DATA: data = -page; break; | |
175 case END_PAGE_DATA: data = sb_info->max; break; | |
176 case -END_PAGE_DATA: data = -sb_info->max; break; | |
177 default: data = 0; break; | |
178 } | |
179 #endif | |
180 } | |
181 else /* Bottom scrollbar */ | |
182 { | |
183 sb_info = sb; | |
184 #ifdef FEAT_GUI_NEXTAW | |
185 if (data < 0) | |
186 { | |
187 data = (data - gui.char_width + 1) / gui.char_width; | |
188 if (data > -sb->size) | |
189 data = -1; | |
190 } | |
191 else if (data > 0) | |
192 { | |
193 data = (data + gui.char_width - 1) / gui.char_width; | |
194 if (data < sb->size) | |
195 data = 1; | |
196 } | |
197 #endif | |
198 if (data < -1) /* page-width left */ | |
199 { | |
200 if (sb->size > 8) | |
201 data = -(sb->size - 5); | |
202 else | |
203 data = -sb->size; | |
204 } | |
205 else if (data > 1) /* page-width right */ | |
206 { | |
207 if (sb->size > 8) | |
208 data = (sb->size - 5); | |
209 else | |
210 data = sb->size; | |
211 } | |
212 } | |
213 | |
214 value = sb_info->value + data; | |
215 if (value > sb_info->max) | |
216 value = sb_info->max; | |
217 else if (value < 0) | |
218 value = 0; | |
219 | |
220 /* Update the bottom scrollbar an extra time (why is this needed?? */ | |
221 if (sb->wp == NULL) /* Bottom scrollbar */ | |
222 gui_mch_set_scrollbar_thumb(sb, value, sb->size, sb->max); | |
223 | |
224 gui_drag_scrollbar(sb, value, FALSE); | |
225 } | |
226 | |
227 /* | |
228 * Create all the Athena widgets necessary. | |
229 */ | |
230 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
231 gui_x11_create_widgets(void) |
7 | 232 { |
233 /* | |
234 * We don't have any borders handled internally by the textArea to worry | |
235 * about so only skip over the configured border width. | |
236 */ | |
237 gui.border_offset = gui.border_width; | |
238 | |
239 /* The form containing all the other widgets */ | |
240 vimForm = XtVaCreateManagedWidget("vimForm", | |
241 formWidgetClass, vimShell, | |
242 XtNborderWidth, 0, | |
243 NULL); | |
244 gui_athena_scroll_colors(vimForm); | |
245 | |
246 #ifdef FEAT_MENU | |
247 /* The top menu bar */ | |
248 menuBar = XtVaCreateManagedWidget("menuBar", | |
249 boxWidgetClass, vimForm, | |
250 XtNresizable, True, | |
251 XtNtop, XtChainTop, | |
252 XtNbottom, XtChainTop, | |
253 XtNleft, XtChainLeft, | |
254 XtNright, XtChainRight, | |
255 XtNinsertPosition, athena_calculate_ins_pos, | |
256 NULL); | |
257 gui_athena_menu_colors(menuBar); | |
258 if (gui.menu_fg_pixel != INVALCOLOR) | |
259 XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL); | |
260 #endif | |
261 | |
262 #ifdef FEAT_TOOLBAR | |
263 /* Don't create it Managed, it will be managed when creating the first | |
264 * item. Otherwise an empty toolbar shows up. */ | |
265 toolBar = XtVaCreateWidget("toolBar", | |
266 boxWidgetClass, vimForm, | |
267 XtNresizable, True, | |
268 XtNtop, XtChainTop, | |
269 XtNbottom, XtChainTop, | |
270 XtNleft, XtChainLeft, | |
271 XtNright, XtChainRight, | |
272 XtNorientation, XtorientHorizontal, | |
273 XtNhSpace, 1, | |
274 XtNvSpace, 3, | |
275 XtNinsertPosition, athena_calculate_ins_pos, | |
276 NULL); | |
277 gui_athena_menu_colors(toolBar); | |
278 #endif | |
279 | |
280 /* The text area. */ | |
281 textArea = XtVaCreateManagedWidget("textArea", | |
282 coreWidgetClass, vimForm, | |
283 XtNresizable, True, | |
284 XtNtop, XtChainTop, | |
285 XtNbottom, XtChainTop, | |
286 XtNleft, XtChainLeft, | |
287 XtNright, XtChainLeft, | |
288 XtNbackground, gui.back_pixel, | |
289 XtNborderWidth, 0, | |
290 NULL); | |
291 | |
292 /* | |
293 * Install the callbacks. | |
294 */ | |
295 gui_x11_callbacks(textArea, vimForm); | |
296 | |
297 #ifdef FEAT_MENU | |
298 popupTrans = XtParseTranslationTable( | |
299 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
300 "<LeaveWindow>: unhighlight()\n" | |
301 "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n" | |
302 "<Motion>: highlight() menu-delayedpopup()"); | |
303 parentTrans = XtParseTranslationTable("<LeaveWindow>: unhighlight()"); | |
304 menuTrans = XtParseTranslationTable( | |
305 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
306 "<LeaveWindow>: menu-popdownsubmenus() XtMenuPopdown() unhighlight()\n" | |
307 "<BtnUp>: notify() unhighlight()\n" | |
308 "<BtnMotion>: highlight() menu-delayedpopup()"); | |
309 supermenuTrans = XtParseTranslationTable( | |
310 "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n" | |
311 "<LeaveWindow>: unhighlight()\n" | |
312 "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n" | |
313 "<BtnMotion>: highlight() menu-delayedpopup()"); | |
314 | |
315 XtAppAddActions(XtWidgetToApplicationContext(vimForm), pullAction, | |
316 XtNumber(pullAction)); | |
317 #endif | |
318 | |
319 /* Pretend we don't have input focus, we will get an event if we do. */ | |
320 gui.in_focus = FALSE; | |
321 } | |
322 | |
323 #ifdef FEAT_MENU | |
324 /* | |
325 * Calculates the Pixmap based on the size of the current menu font. | |
326 */ | |
327 static Pixmap | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
328 gui_athena_create_pullright_pixmap(Widget w) |
7 | 329 { |
330 Pixmap retval; | |
331 #ifdef FONTSET_ALWAYS | |
332 XFontSet font = None; | |
333 #else | |
334 XFontStruct *font = NULL; | |
335 #endif | |
336 | |
337 #ifdef FONTSET_ALWAYS | |
338 if (gui.menu_fontset == NOFONTSET) | |
339 #else | |
340 if (gui.menu_font == NOFONT) | |
341 #endif | |
342 { | |
343 XrmValue from, to; | |
344 WidgetList children; | |
345 Cardinal num_children; | |
346 | |
347 #ifdef FONTSET_ALWAYS | |
348 from.size = strlen(from.addr = XtDefaultFontSet); | |
349 to.addr = (XtPointer)&font; | |
350 to.size = sizeof(XFontSet); | |
351 #else | |
352 from.size = strlen(from.addr = XtDefaultFont); | |
353 to.addr = (XtPointer)&font; | |
354 to.size = sizeof(XFontStruct *); | |
355 #endif | |
356 /* Assumption: The menuBar children will use the same font as the | |
357 * pulldown menu items AND they will all be of type | |
358 * XtNfont. | |
359 */ | |
360 XtVaGetValues(menuBar, XtNchildren, &children, | |
361 XtNnumChildren, &num_children, | |
362 NULL); | |
363 if (XtConvertAndStore(w ? w : | |
364 (num_children > 0) ? children[0] : menuBar, | |
365 XtRString, &from, | |
366 #ifdef FONTSET_ALWAYS | |
367 XtRFontSet, &to | |
368 #else | |
369 XtRFontStruct, &to | |
370 #endif | |
371 ) == False) | |
372 return None; | |
373 /* "font" should now contain data */ | |
374 } | |
375 else | |
376 #ifdef FONTSET_ALWAYS | |
377 font = (XFontSet)gui.menu_fontset; | |
378 #else | |
379 font = (XFontStruct *)gui.menu_font; | |
380 #endif | |
381 | |
382 { | |
383 int width, height; | |
384 GC draw_gc, undraw_gc; | |
385 XGCValues gc_values; | |
386 XPoint points[3]; | |
387 | |
388 #ifdef FONTSET_ALWAYS | |
389 height = fontset_height2(font); | |
390 #else | |
391 height = font->max_bounds.ascent + font->max_bounds.descent; | |
392 #endif | |
393 width = height - 2; | |
394 puller_width = width + 4; | |
395 retval = XCreatePixmap(gui.dpy,DefaultRootWindow(gui.dpy),width, | |
396 height, 1); | |
397 gc_values.foreground = 1; | |
398 gc_values.background = 0; | |
399 draw_gc = XCreateGC(gui.dpy, retval, | |
400 GCForeground | GCBackground, | |
401 &gc_values); | |
402 gc_values.foreground = 0; | |
403 gc_values.background = 1; | |
404 undraw_gc = XCreateGC(gui.dpy, retval, | |
405 GCForeground | GCBackground, | |
406 &gc_values); | |
407 points[0].x = 0; | |
408 points[0].y = 0; | |
409 points[1].x = width - 1; | |
410 points[1].y = (height - 1) / 2; | |
411 points[2].x = 0; | |
412 points[2].y = height - 1; | |
413 XFillRectangle(gui.dpy, retval, undraw_gc, 0, 0, height, height); | |
414 XFillPolygon(gui.dpy, retval, draw_gc, points, XtNumber(points), | |
415 Convex, CoordModeOrigin); | |
416 XFreeGC(gui.dpy, draw_gc); | |
417 XFreeGC(gui.dpy, undraw_gc); | |
418 } | |
419 return retval; | |
420 } | |
421 #endif | |
422 | |
423 /* | |
424 * Called when the GUI is not going to start after all. | |
425 */ | |
426 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
427 gui_x11_destroy_widgets(void) |
7 | 428 { |
429 textArea = NULL; | |
430 #ifdef FEAT_MENU | |
431 menuBar = NULL; | |
432 #endif | |
433 #ifdef FEAT_TOOLBAR | |
434 toolBar = NULL; | |
435 #endif | |
436 } | |
437 | |
438 #if defined(FEAT_TOOLBAR) || defined(PROTO) | |
47 | 439 # include "gui_x11_pm.h" |
440 # ifdef HAVE_X11_XPM_H | |
441 # include <X11/xpm.h> | |
442 # endif | |
443 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
444 static void createXpmImages(char_u *path, char **xpm, Pixmap *sen); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
445 static void get_toolbar_pixmap(vimmenu_T *menu, Pixmap *sen); |
47 | 446 |
447 /* | |
448 * Allocated a pixmap for toolbar menu "menu". | |
449 * Return in "sen". | |
450 */ | |
451 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
452 get_toolbar_pixmap(vimmenu_T *menu, Pixmap *sen) |
47 | 453 { |
454 char_u buf[MAXPATHL]; /* buffer storing expanded pathname */ | |
455 char **xpm = NULL; /* xpm array */ | |
456 | |
457 buf[0] = NUL; /* start with NULL path */ | |
458 | |
459 if (menu->iconfile != NULL) | |
460 { | |
461 /* Use the "icon=" argument. */ | |
462 gui_find_iconfile(menu->iconfile, buf, "xpm"); | |
463 createXpmImages(buf, NULL, sen); | |
464 | |
465 /* If it failed, try using the menu name. */ | |
466 if (*sen == (Pixmap)0 && gui_find_bitmap(menu->name, buf, "xpm") == OK) | |
467 createXpmImages(buf, NULL, sen); | |
468 if (*sen != (Pixmap)0) | |
469 return; | |
470 } | |
471 | |
472 if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL) | |
473 { | |
474 if (menu->iconidx >= 0 && menu->iconidx | |
1887 | 475 < (int)(sizeof(built_in_pixmaps) / sizeof(built_in_pixmaps[0]))) |
47 | 476 xpm = built_in_pixmaps[menu->iconidx]; |
477 else | |
478 xpm = tb_blank_xpm; | |
479 } | |
480 | |
481 if (xpm != NULL || buf[0] != NUL) | |
482 createXpmImages(buf, xpm, sen); | |
483 } | |
484 | |
485 /* | |
486 * Read an Xpm file, doing color substitutions for the foreground and | |
487 * background colors. If there is an error reading a color xpm file, | |
488 * drop back and read the monochrome file. If successful, create the | |
489 * insensitive Pixmap too. | |
490 */ | |
491 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
492 createXpmImages(char_u *path, char **xpm, Pixmap *sen) |
47 | 493 { |
494 Window rootWindow; | |
495 XpmAttributes attrs; | |
496 XpmColorSymbol color[5] = | |
497 { | |
498 {"none", "none", 0}, | |
499 {"iconColor1", NULL, 0}, | |
500 {"bottomShadowColor", NULL, 0}, | |
501 {"topShadowColor", NULL, 0}, | |
502 {"selectColor", NULL, 0} | |
503 }; | |
504 int screenNum; | |
505 int status; | |
506 Pixmap mask; | |
507 Pixmap map; | |
508 | |
509 gui_mch_get_toolbar_colors( | |
510 &color[BACKGROUND].pixel, | |
511 &color[FOREGROUND].pixel, | |
512 &color[BOTTOM_SHADOW].pixel, | |
513 &color[TOP_SHADOW].pixel, | |
514 &color[HIGHLIGHT].pixel); | |
515 | |
4352 | 516 /* Setup the color substitution table */ |
47 | 517 attrs.valuemask = XpmColorSymbols; |
518 attrs.colorsymbols = color; | |
519 attrs.numsymbols = 5; | |
520 | |
521 screenNum = DefaultScreen(gui.dpy); | |
522 rootWindow = RootWindow(gui.dpy, screenNum); | |
523 | |
524 /* Create the "sensitive" pixmap */ | |
525 if (xpm != NULL) | |
526 status = XpmCreatePixmapFromData(gui.dpy, rootWindow, xpm, | |
527 &map, &mask, &attrs); | |
528 else | |
529 status = XpmReadFileToPixmap(gui.dpy, rootWindow, (char *)path, | |
530 &map, &mask, &attrs); | |
531 if (status == XpmSuccess && map != 0) | |
532 { | |
533 XGCValues gcvalues; | |
534 GC back_gc; | |
535 GC mask_gc; | |
536 | |
537 /* Need to create new Pixmaps with the mask applied. */ | |
538 gcvalues.foreground = color[BACKGROUND].pixel; | |
539 back_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues); | |
540 mask_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues); | |
541 XSetClipMask(gui.dpy, mask_gc, mask); | |
542 | |
543 /* Create the "sensitive" pixmap. */ | |
544 *sen = XCreatePixmap(gui.dpy, rootWindow, | |
545 attrs.width, attrs.height, | |
546 DefaultDepth(gui.dpy, screenNum)); | |
547 XFillRectangle(gui.dpy, *sen, back_gc, 0, 0, | |
548 attrs.width, attrs.height); | |
549 XCopyArea(gui.dpy, map, *sen, mask_gc, 0, 0, | |
550 attrs.width, attrs.height, 0, 0); | |
551 | |
552 XFreeGC(gui.dpy, back_gc); | |
553 XFreeGC(gui.dpy, mask_gc); | |
554 XFreePixmap(gui.dpy, map); | |
555 } | |
556 else | |
557 *sen = 0; | |
558 | |
559 XpmFreeAttributes(&attrs); | |
560 } | |
561 | |
7 | 562 void |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
563 gui_mch_set_toolbar_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
564 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
565 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
566 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
567 int h) |
7 | 568 { |
569 Dimension border; | |
570 int height; | |
571 | |
572 if (!XtIsManaged(toolBar)) /* nothing to do */ | |
573 return; | |
574 XtUnmanageChild(toolBar); | |
575 XtVaGetValues(toolBar, | |
576 XtNborderWidth, &border, | |
577 NULL); | |
578 height = h - 2 * border; | |
579 if (height < 0) | |
580 height = 1; | |
581 XtVaSetValues(toolBar, | |
582 XtNhorizDistance, x, | |
583 XtNvertDistance, y, | |
584 XtNwidth, w - 2 * border, | |
585 XtNheight, height, | |
586 NULL); | |
587 XtManageChild(toolBar); | |
588 } | |
589 #endif | |
590 | |
591 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
592 gui_mch_set_text_area_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
593 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
594 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
595 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
596 int h) |
7 | 597 { |
598 XtUnmanageChild(textArea); | |
599 XtVaSetValues(textArea, | |
600 XtNhorizDistance, x, | |
601 XtNvertDistance, y, | |
602 XtNwidth, w, | |
603 XtNheight, h, | |
604 NULL); | |
605 XtManageChild(textArea); | |
606 #ifdef FEAT_TOOLBAR | |
607 /* Give keyboard focus to the textArea instead of the toolbar. */ | |
608 gui_mch_reset_focus(); | |
609 #endif | |
610 } | |
611 | |
612 #ifdef FEAT_TOOLBAR | |
613 /* | |
614 * A toolbar button has been pushed; now reset the input focus | |
615 * such that the user can type page up/down etc. and have the | |
616 * input go to the editor window, not the button | |
617 */ | |
618 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
619 gui_mch_reset_focus(void) |
7 | 620 { |
621 XtSetKeyboardFocus(vimForm, textArea); | |
622 } | |
623 #endif | |
624 | |
625 | |
626 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
627 gui_x11_set_back_color(void) |
7 | 628 { |
629 if (textArea != NULL) | |
630 XtVaSetValues(textArea, | |
631 XtNbackground, gui.back_pixel, | |
632 NULL); | |
633 } | |
634 | |
635 #if defined(FEAT_MENU) || defined(PROTO) | |
636 /* | |
637 * Menu stuff. | |
638 */ | |
639 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
640 static char_u *make_pull_name(char_u * name); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
641 static Widget get_popup_entry(Widget w); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
642 static Widget submenu_widget(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
643 static Boolean has_submenu(Widget); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
644 static void gui_mch_submenu_change(vimmenu_T *mp, int colors); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
645 static void gui_athena_menu_font(Widget id); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
646 static Boolean gui_athena_menu_has_submenus(Widget, Widget); |
7 | 647 |
648 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
649 gui_mch_enable_menu(int flag) |
7 | 650 { |
651 if (flag) | |
652 { | |
653 XtManageChild(menuBar); | |
654 # ifdef FEAT_TOOLBAR | |
655 if (XtIsManaged(toolBar)) | |
656 { | |
657 XtVaSetValues(toolBar, | |
658 XtNvertDistance, gui.menu_height, | |
659 NULL); | |
660 XtVaSetValues(textArea, | |
661 XtNvertDistance, gui.menu_height + gui.toolbar_height, | |
662 NULL); | |
663 } | |
664 # endif | |
665 } | |
666 else | |
667 { | |
668 XtUnmanageChild(menuBar); | |
669 # ifdef FEAT_TOOLBAR | |
670 if (XtIsManaged(toolBar)) | |
671 { | |
672 XtVaSetValues(toolBar, | |
673 XtNvertDistance, 0, | |
674 NULL); | |
675 } | |
676 # endif | |
677 } | |
678 } | |
679 | |
680 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
681 gui_mch_set_menu_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
682 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
683 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
684 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
685 int h) |
7 | 686 { |
687 Dimension border; | |
688 int height; | |
689 | |
690 XtUnmanageChild(menuBar); | |
691 XtVaGetValues(menuBar, XtNborderWidth, &border, NULL); | |
692 /* avoid trouble when there are no menu items, and h is 1 */ | |
693 height = h - 2 * border; | |
694 if (height < 0) | |
695 height = 1; | |
696 XtVaSetValues(menuBar, | |
697 XtNhorizDistance, x, | |
698 XtNvertDistance, y, | |
699 XtNwidth, w - 2 * border, | |
700 XtNheight, height, | |
701 NULL); | |
702 XtManageChild(menuBar); | |
703 } | |
704 | |
705 /* | |
706 * Used to calculate the insertion position of a widget with respect to its | |
707 * neighbors. | |
708 * | |
709 * Valid range of return values is: 0 (beginning of children) to | |
710 * numChildren (end of children). | |
711 */ | |
712 static Cardinal | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
713 athena_calculate_ins_pos(Widget widget) |
7 | 714 { |
715 /* Assume that if the parent of the vimmenu_T is NULL, then we can get | |
716 * to this menu by traversing "next", starting at "root_menu". | |
717 * | |
718 * This holds true for popup menus, toolbar, and toplevel menu items. | |
719 */ | |
720 | |
721 /* Popup menus: "id" is NULL. Only submenu_id is valid */ | |
722 | |
723 /* Menus that are not toplevel: "parent" will be non-NULL, "id" & | |
724 * "submenu_id" will be non-NULL. | |
725 */ | |
726 | |
727 /* Toplevel menus: "parent" is NULL, id is the widget of the menu item */ | |
728 | |
729 WidgetList children; | |
730 Cardinal num_children = 0; | |
731 int retval; | |
732 Arg args[2]; | |
733 int n = 0; | |
734 int i; | |
735 | |
736 XtSetArg(args[n], XtNchildren, &children); n++; | |
737 XtSetArg(args[n], XtNnumChildren, &num_children); n++; | |
738 XtGetValues(XtParent(widget), args, n); | |
739 | |
740 retval = num_children; | |
1887 | 741 for (i = 0; i < (int)num_children; ++i) |
7 | 742 { |
743 Widget current = children[i]; | |
744 vimmenu_T *menu = NULL; | |
745 | |
746 for (menu = (a_cur_menu->parent == NULL) | |
747 ? root_menu : a_cur_menu->parent->children; | |
748 menu != NULL; | |
749 menu = menu->next) | |
750 if (current == menu->id | |
751 && a_cur_menu->priority < menu->priority | |
752 && i < retval) | |
753 retval = i; | |
754 } | |
755 return retval; | |
756 } | |
757 | |
758 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
759 gui_mch_add_menu(vimmenu_T *menu, int idx UNUSED) |
7 | 760 { |
761 char_u *pullright_name; | |
762 Dimension height, space, border; | |
763 vimmenu_T *parent = menu->parent; | |
764 | |
765 a_cur_menu = menu; | |
766 if (parent == NULL) | |
767 { | |
768 if (menu_is_popup(menu->dname)) | |
769 { | |
770 menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname, | |
771 simpleMenuWidgetClass, vimShell, | |
772 XtNinsertPosition, athena_calculate_ins_pos, | |
773 XtNtranslations, popupTrans, | |
774 NULL); | |
775 gui_athena_menu_colors(menu->submenu_id); | |
776 } | |
777 else if (menu_is_menubar(menu->dname)) | |
778 { | |
779 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
780 menuButtonWidgetClass, menuBar, | |
781 XtNmenuName, menu->dname, | |
782 #ifdef FONTSET_ALWAYS | |
783 XtNinternational, True, | |
784 #endif | |
785 NULL); | |
786 if (menu->id == (Widget)0) | |
787 return; | |
788 gui_athena_menu_colors(menu->id); | |
789 gui_athena_menu_font(menu->id); | |
790 | |
791 menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname, | |
792 simpleMenuWidgetClass, menu->id, | |
793 XtNinsertPosition, athena_calculate_ins_pos, | |
794 XtNtranslations, supermenuTrans, | |
795 NULL); | |
796 gui_athena_menu_colors(menu->submenu_id); | |
797 gui_athena_menu_font(menu->submenu_id); | |
798 | |
799 /* Don't update the menu height when it was set at a fixed value */ | |
800 if (!gui.menu_height_fixed) | |
801 { | |
802 /* | |
803 * When we add a top-level item to the menu bar, we can figure | |
804 * out how high the menu bar should be. | |
805 */ | |
806 XtVaGetValues(menuBar, | |
807 XtNvSpace, &space, | |
808 XtNborderWidth, &border, | |
809 NULL); | |
810 XtVaGetValues(menu->id, | |
811 XtNheight, &height, | |
812 NULL); | |
813 gui.menu_height = height + 2 * (space + border); | |
814 } | |
815 } | |
816 } | |
817 else if (parent->submenu_id != (Widget)0) | |
818 { | |
819 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
820 smeBSBObjectClass, parent->submenu_id, | |
821 XtNlabel, menu->dname, | |
822 #ifdef FONTSET_ALWAYS | |
823 XtNinternational, True, | |
824 #endif | |
825 NULL); | |
826 if (menu->id == (Widget)0) | |
827 return; | |
828 if (pullerBitmap == None) | |
829 pullerBitmap = gui_athena_create_pullright_pixmap(menu->id); | |
830 | |
831 XtVaSetValues(menu->id, XtNrightBitmap, pullerBitmap, | |
832 NULL); | |
833 /* If there are other menu items that are not pulldown menus, | |
834 * we need to adjust the right margins of those, too. | |
835 */ | |
836 { | |
837 WidgetList children; | |
838 Cardinal num_children; | |
839 int i; | |
840 | |
841 XtVaGetValues(parent->submenu_id, XtNchildren, &children, | |
842 XtNnumChildren, &num_children, | |
843 NULL); | |
1887 | 844 for (i = 0; i < (int)num_children; ++i) |
7 | 845 { |
846 XtVaSetValues(children[i], | |
847 XtNrightMargin, puller_width, | |
848 NULL); | |
849 } | |
850 } | |
851 gui_athena_menu_colors(menu->id); | |
852 gui_athena_menu_font(menu->id); | |
853 | |
854 pullright_name = make_pull_name(menu->dname); | |
855 menu->submenu_id = XtVaCreatePopupShell((char *)pullright_name, | |
856 simpleMenuWidgetClass, parent->submenu_id, | |
857 XtNtranslations, menuTrans, | |
858 NULL); | |
859 gui_athena_menu_colors(menu->submenu_id); | |
860 gui_athena_menu_font(menu->submenu_id); | |
861 vim_free(pullright_name); | |
862 XtAddCallback(menu->submenu_id, XtNpopupCallback, | |
863 gui_athena_popup_callback, (XtPointer)menu); | |
864 | |
865 if (parent->parent != NULL) | |
866 XtOverrideTranslations(parent->submenu_id, parentTrans); | |
867 } | |
868 a_cur_menu = NULL; | |
869 } | |
870 | |
871 /* Used to determine whether a SimpleMenu has pulldown entries. | |
872 * | |
873 * "id" is the parent of the menu items. | |
874 * Ignore widget "ignore" in the pane. | |
875 */ | |
876 static Boolean | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
877 gui_athena_menu_has_submenus(Widget id, Widget ignore) |
7 | 878 { |
879 WidgetList children; | |
880 Cardinal num_children; | |
881 int i; | |
882 | |
883 XtVaGetValues(id, XtNchildren, &children, | |
884 XtNnumChildren, &num_children, | |
885 NULL); | |
1887 | 886 for (i = 0; i < (int)num_children; ++i) |
7 | 887 { |
888 if (children[i] == ignore) | |
889 continue; | |
890 if (has_submenu(children[i])) | |
891 return True; | |
892 } | |
893 return False; | |
894 } | |
895 | |
896 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
897 gui_athena_menu_font(Widget id) |
7 | 898 { |
899 #ifdef FONTSET_ALWAYS | |
900 if (gui.menu_fontset != NOFONTSET) | |
901 { | |
902 if (XtIsManaged(id)) | |
903 { | |
904 XtUnmanageChild(id); | |
905 XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL); | |
906 /* We should force the widget to recalculate it's | |
907 * geometry now. */ | |
908 XtManageChild(id); | |
909 } | |
910 else | |
911 XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL); | |
912 if (has_submenu(id)) | |
913 XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL); | |
914 } | |
915 #else | |
916 int managed = FALSE; | |
917 | |
918 if (gui.menu_font != NOFONT) | |
919 { | |
920 if (XtIsManaged(id)) | |
921 { | |
922 XtUnmanageChild(id); | |
923 managed = TRUE; | |
924 } | |
925 | |
926 # ifdef FEAT_XFONTSET | |
927 if (gui.fontset != NOFONTSET) | |
928 XtVaSetValues(id, XtNfontSet, gui.menu_font, NULL); | |
929 else | |
930 # endif | |
931 XtVaSetValues(id, XtNfont, gui.menu_font, NULL); | |
932 if (has_submenu(id)) | |
933 XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL); | |
934 | |
935 /* Force the widget to recalculate it's geometry now. */ | |
936 if (managed) | |
937 XtManageChild(id); | |
938 } | |
939 #endif | |
940 } | |
941 | |
942 | |
943 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
944 gui_mch_new_menu_font(void) |
7 | 945 { |
946 Pixmap oldpuller = None; | |
947 | |
948 if (menuBar == (Widget)0) | |
949 return; | |
950 | |
951 if (pullerBitmap != None) | |
952 { | |
953 oldpuller = pullerBitmap; | |
954 pullerBitmap = gui_athena_create_pullright_pixmap(NULL); | |
955 } | |
956 gui_mch_submenu_change(root_menu, FALSE); | |
957 | |
958 { | |
959 /* Iterate through the menubar menu items and get the height of | |
960 * each one. The menu bar height is set to the maximum of all | |
961 * the heights. | |
962 */ | |
963 vimmenu_T *mp; | |
964 int max_height = 9999; | |
965 | |
966 for (mp = root_menu; mp != NULL; mp = mp->next) | |
967 { | |
968 if (menu_is_menubar(mp->dname)) | |
969 { | |
970 Dimension height; | |
971 | |
972 XtVaGetValues(mp->id, | |
125 | 973 XtNheight, &height, |
7 | 974 NULL); |
975 if (height < max_height) | |
976 max_height = height; | |
977 } | |
978 } | |
979 if (max_height != 9999) | |
980 { | |
981 /* Don't update the menu height when it was set at a fixed value */ | |
982 if (!gui.menu_height_fixed) | |
983 { | |
984 Dimension space, border; | |
985 | |
986 XtVaGetValues(menuBar, | |
987 XtNvSpace, &space, | |
988 XtNborderWidth, &border, | |
989 NULL); | |
990 gui.menu_height = max_height + 2 * (space + border); | |
991 } | |
992 } | |
993 } | |
994 /* Now, to simulate the window being resized. Only, this | |
995 * will resize the window to it's current state. | |
996 * | |
997 * There has to be a better way, but I do not see one at this time. | |
998 * (David Harrison) | |
999 */ | |
1000 { | |
1001 Position w, h; | |
1002 | |
1003 XtVaGetValues(vimShell, | |
1004 XtNwidth, &w, | |
1005 XtNheight, &h, | |
1006 NULL); | |
1007 gui_resize_shell(w, h | |
1008 #ifdef FEAT_XIM | |
1009 - xim_get_status_area_height() | |
1010 #endif | |
1011 ); | |
1012 } | |
811 | 1013 gui_set_shellsize(FALSE, TRUE, RESIZE_VERT); |
7 | 1014 ui_new_shellsize(); |
1015 if (oldpuller != None) | |
1016 XFreePixmap(gui.dpy, oldpuller); | |
1017 } | |
1018 | |
1019 #if defined(FEAT_BEVAL) || defined(PROTO) | |
1020 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1021 gui_mch_new_tooltip_font(void) |
7 | 1022 { |
1023 # ifdef FEAT_TOOLBAR | |
1024 vimmenu_T *menu; | |
1025 | |
1026 if (toolBar == (Widget)0) | |
1027 return; | |
1028 | |
1029 menu = gui_find_menu((char_u *)"ToolBar"); | |
1030 if (menu != NULL) | |
1031 gui_mch_submenu_change(menu, FALSE); | |
1032 # endif | |
1033 } | |
1034 | |
1035 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1036 gui_mch_new_tooltip_colors(void) |
7 | 1037 { |
1038 # ifdef FEAT_TOOLBAR | |
1039 vimmenu_T *menu; | |
1040 | |
1041 if (toolBar == (Widget)0) | |
1042 return; | |
1043 | |
1044 menu = gui_find_menu((char_u *)"ToolBar"); | |
1045 if (menu != NULL) | |
1046 gui_mch_submenu_change(menu, TRUE); | |
1047 # endif | |
1048 } | |
1049 #endif | |
1050 | |
1051 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1052 gui_mch_submenu_change( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1053 vimmenu_T *menu, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1054 int colors) /* TRUE for colors, FALSE for font */ |
7 | 1055 { |
1056 vimmenu_T *mp; | |
1057 | |
1058 for (mp = menu; mp != NULL; mp = mp->next) | |
1059 { | |
1060 if (mp->id != (Widget)0) | |
1061 { | |
1062 if (colors) | |
1063 { | |
1064 gui_athena_menu_colors(mp->id); | |
1065 #ifdef FEAT_TOOLBAR | |
1066 /* For a toolbar item: Free the pixmap and allocate a new one, | |
1067 * so that the background color is right. */ | |
1068 if (mp->image != (Pixmap)0) | |
1069 { | |
1070 XFreePixmap(gui.dpy, mp->image); | |
47 | 1071 get_toolbar_pixmap(mp, &mp->image); |
7 | 1072 if (mp->image != (Pixmap)0) |
1073 XtVaSetValues(mp->id, XtNbitmap, mp->image, NULL); | |
1074 } | |
1075 | |
1076 # ifdef FEAT_BEVAL | |
1077 /* If we have a tooltip, then we need to change it's colors */ | |
1078 if (mp->tip != NULL) | |
1079 { | |
1080 Arg args[2]; | |
1081 | |
1082 args[0].name = XtNbackground; | |
1083 args[0].value = gui.tooltip_bg_pixel; | |
1084 args[1].name = XtNforeground; | |
1085 args[1].value = gui.tooltip_fg_pixel; | |
1086 XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args)); | |
1087 } | |
1088 # endif | |
1089 #endif | |
1090 } | |
1091 else | |
1092 { | |
1093 gui_athena_menu_font(mp->id); | |
1094 #ifdef FEAT_BEVAL | |
1095 /* If we have a tooltip, then we need to change it's font */ | |
1096 /* Assume XtNinternational == True (in createBalloonEvalWindow) | |
1097 */ | |
1098 if (mp->tip != NULL) | |
1099 { | |
1100 Arg args[1]; | |
1101 | |
1102 args[0].name = XtNfontSet; | |
1103 args[0].value = (XtArgVal)gui.tooltip_fontset; | |
1104 XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args)); | |
1105 } | |
1106 #endif | |
1107 } | |
1108 } | |
1109 | |
1110 if (mp->children != NULL) | |
1111 { | |
1112 /* Set the colors/font for the tear off widget */ | |
1113 if (mp->submenu_id != (Widget)0) | |
1114 { | |
1115 if (colors) | |
1116 gui_athena_menu_colors(mp->submenu_id); | |
1117 else | |
1118 gui_athena_menu_font(mp->submenu_id); | |
1119 } | |
1120 /* Set the colors for the children */ | |
1121 gui_mch_submenu_change(mp->children, colors); | |
1122 } | |
1123 } | |
1124 } | |
1125 | |
1126 /* | |
1127 * Make a submenu name into a pullright name. | |
1128 * Replace '.' by '_', can't include '.' in the submenu name. | |
1129 */ | |
1130 static char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1131 make_pull_name(char_u * name) |
7 | 1132 { |
1133 char_u *pname; | |
1134 char_u *p; | |
1135 | |
1136 pname = vim_strnsave(name, STRLEN(name) + strlen("-pullright")); | |
1137 if (pname != NULL) | |
1138 { | |
1139 strcat((char *)pname, "-pullright"); | |
1140 while ((p = vim_strchr(pname, '.')) != NULL) | |
1141 *p = '_'; | |
1142 } | |
1143 return pname; | |
1144 } | |
1145 | |
1146 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1147 gui_mch_add_menu_item(vimmenu_T *menu, int idx UNUSED) |
7 | 1148 { |
1149 vimmenu_T *parent = menu->parent; | |
1150 | |
1151 a_cur_menu = menu; | |
1152 # ifdef FEAT_TOOLBAR | |
1153 if (menu_is_toolbar(parent->name)) | |
1154 { | |
1155 WidgetClass type; | |
1156 int n; | |
1157 Arg args[21]; | |
1158 | |
1159 n = 0; | |
1160 if (menu_is_separator(menu->name)) | |
1161 { | |
1162 XtSetArg(args[n], XtNlabel, ""); n++; | |
1163 XtSetArg(args[n], XtNborderWidth, 0); n++; | |
1164 } | |
1165 else | |
1166 { | |
47 | 1167 get_toolbar_pixmap(menu, &menu->image); |
7 | 1168 XtSetArg(args[n], XtNlabel, menu->dname); n++; |
1169 XtSetArg(args[n], XtNinternalHeight, 1); n++; | |
1170 XtSetArg(args[n], XtNinternalWidth, 1); n++; | |
1171 XtSetArg(args[n], XtNborderWidth, 1); n++; | |
1172 if (menu->image != 0) | |
1173 XtSetArg(args[n], XtNbitmap, menu->image); n++; | |
1174 } | |
1175 XtSetArg(args[n], XtNhighlightThickness, 0); n++; | |
1176 type = commandWidgetClass; | |
1177 /* TODO: figure out the position in the toolbar? | |
1178 * This currently works fine for the default toolbar, but | |
1179 * what if we add/remove items during later runtime? | |
1180 */ | |
1181 | |
1182 /* NOTE: "idx" isn't used here. The position is calculated by | |
1183 * athena_calculate_ins_pos(). The position it calculates | |
1184 * should be equal to "idx". | |
1185 */ | |
1186 /* TODO: Could we just store "idx" and use that as the child | |
1187 * placement? | |
1188 */ | |
1189 | |
1190 if (menu->id == NULL) | |
1191 { | |
1192 menu->id = XtCreateManagedWidget((char *)menu->dname, | |
1193 type, toolBar, args, n); | |
1194 XtAddCallback(menu->id, | |
1195 XtNcallback, gui_x11_menu_cb, menu); | |
1196 } | |
1197 else | |
1198 XtSetValues(menu->id, args, n); | |
1199 gui_athena_menu_colors(menu->id); | |
1200 | |
1201 #ifdef FEAT_BEVAL | |
1202 gui_mch_menu_set_tip(menu); | |
1203 #endif | |
1204 | |
1205 menu->parent = parent; | |
1206 menu->submenu_id = NULL; | |
1207 if (!XtIsManaged(toolBar) | |
1208 && vim_strchr(p_go, GO_TOOLBAR) != NULL) | |
1209 gui_mch_show_toolbar(TRUE); | |
1210 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1211 return; | |
1212 } /* toolbar menu item */ | |
1213 # endif | |
1214 | |
1215 /* Add menu separator */ | |
1216 if (menu_is_separator(menu->name)) | |
1217 { | |
1218 menu->submenu_id = (Widget)0; | |
1219 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
1220 smeLineObjectClass, parent->submenu_id, | |
1221 NULL); | |
1222 if (menu->id == (Widget)0) | |
1223 return; | |
1224 gui_athena_menu_colors(menu->id); | |
1225 } | |
1226 else | |
1227 { | |
1228 if (parent != NULL && parent->submenu_id != (Widget)0) | |
1229 { | |
1230 menu->submenu_id = (Widget)0; | |
1231 menu->id = XtVaCreateManagedWidget((char *)menu->dname, | |
1232 smeBSBObjectClass, parent->submenu_id, | |
1233 XtNlabel, menu->dname, | |
1234 #ifdef FONTSET_ALWAYS | |
1235 XtNinternational, True, | |
1236 #endif | |
1237 NULL); | |
1238 if (menu->id == (Widget)0) | |
1239 return; | |
1240 | |
1241 /* If there are other "pulldown" items in this pane, then adjust | |
2255 | 1242 * the right margin to accommodate the arrow pixmap, otherwise |
7 | 1243 * the right margin will be the same as the left margin. |
1244 */ | |
1245 { | |
1246 Dimension left_margin; | |
1247 | |
1248 XtVaGetValues(menu->id, XtNleftMargin, &left_margin, NULL); | |
1249 XtVaSetValues(menu->id, XtNrightMargin, | |
1250 gui_athena_menu_has_submenus(parent->submenu_id, NULL) ? | |
1251 puller_width : | |
1252 left_margin, | |
1253 NULL); | |
1254 } | |
1255 | |
1256 gui_athena_menu_colors(menu->id); | |
1257 gui_athena_menu_font(menu->id); | |
1258 XtAddCallback(menu->id, XtNcallback, gui_x11_menu_cb, | |
1259 (XtPointer)menu); | |
1260 } | |
1261 } | |
1262 a_cur_menu = NULL; | |
1263 } | |
1264 | |
1265 #if defined(FEAT_TOOLBAR) || defined(PROTO) | |
1266 void | |
1267 gui_mch_show_toolbar(int showit) | |
1268 { | |
1269 Cardinal numChildren; /* how many children toolBar has */ | |
1270 | |
1271 if (toolBar == (Widget)0) | |
1272 return; | |
1273 XtVaGetValues(toolBar, XtNnumChildren, &numChildren, NULL); | |
1274 if (showit && numChildren > 0) | |
1275 { | |
1276 /* Assume that we want to show the toolbar if p_toolbar contains valid | |
1277 * option settings, therefore p_toolbar must not be NULL. | |
1278 */ | |
1279 WidgetList children; | |
1280 | |
1281 XtVaGetValues(toolBar, XtNchildren, &children, NULL); | |
1282 { | |
1283 void (*action)(BalloonEval *); | |
1284 int text = 0; | |
1285 | |
1286 if (strstr((const char *)p_toolbar, "tooltips")) | |
1287 action = &gui_mch_enable_beval_area; | |
1288 else | |
1289 action = &gui_mch_disable_beval_area; | |
1290 if (strstr((const char *)p_toolbar, "text")) | |
1291 text = 1; | |
1292 else if (strstr((const char *)p_toolbar, "icons")) | |
1293 text = -1; | |
1294 if (text != 0) | |
1295 { | |
1296 vimmenu_T *toolbar; | |
1297 vimmenu_T *cur; | |
1298 | |
1299 for (toolbar = root_menu; toolbar; toolbar = toolbar->next) | |
1300 if (menu_is_toolbar(toolbar->dname)) | |
1301 break; | |
1302 /* Assumption: toolbar is NULL if there is no toolbar, | |
1303 * otherwise it contains the toolbar menu structure. | |
1304 * | |
1305 * Assumption: "numChildren" == the number of items in the list | |
1306 * of items beginning with toolbar->children. | |
1307 */ | |
1308 if (toolbar) | |
1309 { | |
1310 for (cur = toolbar->children; cur; cur = cur->next) | |
1311 { | |
1312 Arg args[2]; | |
1313 int n = 0; | |
1314 | |
1315 /* Enable/Disable tooltip (OK to enable while currently | |
1316 * enabled) | |
1317 */ | |
1318 if (cur->tip != NULL) | |
1319 (*action)(cur->tip); | |
1320 if (text == 1) | |
1321 { | |
1322 XtSetArg(args[n], XtNbitmap, None); | |
1323 n++; | |
1324 XtSetArg(args[n], XtNlabel, | |
1325 menu_is_separator(cur->name) ? "" : | |
1326 (char *)cur->dname); | |
1327 n++; | |
1328 } | |
1329 else | |
1330 { | |
1331 XtSetArg(args[n], XtNbitmap, cur->image); | |
1332 n++; | |
1333 XtSetArg(args[n], XtNlabel, (cur->image == None) ? | |
1334 menu_is_separator(cur->name) ? | |
1335 "" : | |
1336 (char *)cur->dname | |
1337 : | |
1338 (char *)None); | |
1339 n++; | |
1340 } | |
1341 if (cur->id != NULL) | |
1342 { | |
1343 XtUnmanageChild(cur->id); | |
1344 XtSetValues(cur->id, args, n); | |
1345 XtManageChild(cur->id); | |
1346 } | |
1347 } | |
1348 } | |
1349 } | |
1350 } | |
1351 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1352 XtManageChild(toolBar); | |
1353 if (XtIsManaged(menuBar)) | |
1354 { | |
1355 XtVaSetValues(textArea, | |
1356 XtNvertDistance, gui.toolbar_height + gui.menu_height, | |
1357 NULL); | |
1358 XtVaSetValues(toolBar, | |
1359 XtNvertDistance, gui.menu_height, | |
1360 NULL); | |
1361 } | |
1362 else | |
1363 { | |
1364 XtVaSetValues(textArea, | |
1365 XtNvertDistance, gui.toolbar_height, | |
1366 NULL); | |
1367 XtVaSetValues(toolBar, | |
1368 XtNvertDistance, 0, | |
1369 NULL); | |
1370 } | |
1371 } | |
1372 else | |
1373 { | |
1374 gui.toolbar_height = 0; | |
1375 if (XtIsManaged(menuBar)) | |
1376 XtVaSetValues(textArea, | |
1377 XtNvertDistance, gui.menu_height, | |
1378 NULL); | |
1379 else | |
1380 XtVaSetValues(textArea, | |
1381 XtNvertDistance, 0, | |
1382 NULL); | |
1383 | |
1384 XtUnmanageChild(toolBar); | |
1385 } | |
811 | 1386 gui_set_shellsize(FALSE, FALSE, RESIZE_VERT); |
7 | 1387 } |
1388 | |
1389 | |
1390 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1391 gui_mch_compute_toolbar_height(void) |
7 | 1392 { |
1393 Dimension height; /* total Toolbar height */ | |
1394 Dimension whgt; /* height of each widget */ | |
1395 Dimension marginHeight; /* XmNmarginHeight of toolBar */ | |
1396 Dimension shadowThickness; /* thickness of Xtparent(toolBar) */ | |
1397 WidgetList children; /* list of toolBar's children */ | |
1398 Cardinal numChildren; /* how many children toolBar has */ | |
1399 int i; | |
1400 | |
1401 height = 0; | |
1402 shadowThickness = 0; | |
1403 marginHeight = 0; | |
1404 if (toolBar != (Widget)0) | |
1405 { | |
1406 XtVaGetValues(toolBar, | |
1407 XtNborderWidth, &shadowThickness, | |
1408 XtNvSpace, &marginHeight, | |
1409 XtNchildren, &children, | |
1410 XtNnumChildren, &numChildren, | |
1411 NULL); | |
1887 | 1412 for (i = 0; i < (int)numChildren; i++) |
7 | 1413 { |
1414 whgt = 0; | |
1415 | |
1416 XtVaGetValues(children[i], XtNheight, &whgt, NULL); | |
1417 if (height < whgt) | |
1418 height = whgt; | |
1419 } | |
1420 } | |
1421 | |
1422 return (int)(height + (marginHeight << 1) + (shadowThickness << 1)); | |
1423 } | |
1424 | |
1425 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1426 gui_mch_get_toolbar_colors( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1427 Pixel *bgp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1428 Pixel *fgp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1429 Pixel *bsp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1430 Pixel *tsp, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1431 Pixel *hsp) |
7 | 1432 { |
1433 XtVaGetValues(toolBar, XtNbackground, bgp, XtNborderColor, fgp, NULL); | |
1434 *bsp = *bgp; | |
1435 *tsp = *fgp; | |
1436 *hsp = *tsp; | |
1437 } | |
1438 #endif | |
1439 | |
1440 | |
1441 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1442 gui_mch_toggle_tearoffs(int enable UNUSED) |
7 | 1443 { |
1444 /* no tearoff menus */ | |
1445 } | |
1446 | |
1447 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1448 gui_mch_new_menu_colors(void) |
7 | 1449 { |
1450 if (menuBar == (Widget)0) | |
1451 return; | |
1452 if (gui.menu_fg_pixel != INVALCOLOR) | |
1453 XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL); | |
1454 gui_athena_menu_colors(menuBar); | |
1455 #ifdef FEAT_TOOLBAR | |
1456 gui_athena_menu_colors(toolBar); | |
1457 #endif | |
1458 | |
1459 gui_mch_submenu_change(root_menu, TRUE); | |
1460 } | |
1461 | |
1462 /* | |
1463 * Destroy the machine specific menu widget. | |
1464 */ | |
1465 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1466 gui_mch_destroy_menu(vimmenu_T *menu) |
7 | 1467 { |
1468 Widget parent; | |
1469 | |
1470 /* There is no item for the toolbar. */ | |
1471 if (menu->id == (Widget)0) | |
1472 return; | |
1473 | |
1474 parent = XtParent(menu->id); | |
1475 | |
1476 /* When removing the last "pulldown" menu item from a pane, adjust the | |
1477 * right margins of the remaining widgets. | |
1478 */ | |
1479 if (menu->submenu_id != (Widget)0) | |
1480 { | |
1481 /* Go through the menu items in the parent of this item and | |
1482 * adjust their margins, if necessary. | |
1483 * This takes care of the case when we delete the last menu item in a | |
1484 * pane that has a submenu. In this case, there will be no arrow | |
1485 * pixmaps shown anymore. | |
1486 */ | |
1487 { | |
1488 WidgetList children; | |
1489 Cardinal num_children; | |
1490 int i; | |
1491 Dimension right_margin = 0; | |
1492 Boolean get_left_margin = False; | |
1493 | |
1494 XtVaGetValues(parent, XtNchildren, &children, | |
1495 XtNnumChildren, &num_children, | |
1496 NULL); | |
1497 if (gui_athena_menu_has_submenus(parent, menu->id)) | |
1498 right_margin = puller_width; | |
1499 else | |
1500 get_left_margin = True; | |
1501 | |
1887 | 1502 for (i = 0; i < (int)num_children; ++i) |
7 | 1503 { |
1504 if (children[i] == menu->id) | |
1505 continue; | |
1506 if (get_left_margin == True) | |
1507 { | |
1508 Dimension left_margin; | |
1509 | |
1510 XtVaGetValues(children[i], XtNleftMargin, &left_margin, | |
1511 NULL); | |
1512 XtVaSetValues(children[i], XtNrightMargin, left_margin, | |
1513 NULL); | |
1514 } | |
1515 else | |
1516 XtVaSetValues(children[i], XtNrightMargin, right_margin, | |
1517 NULL); | |
1518 } | |
1519 } | |
1520 } | |
1521 /* Please be sure to destroy the parent widget first (i.e. menu->id). | |
1522 * | |
1523 * This code should be basically identical to that in the file gui_motif.c | |
1524 * because they are both Xt based. | |
1525 */ | |
1526 if (menu->id != (Widget)0) | |
1527 { | |
1528 Cardinal num_children; | |
1529 Dimension height, space, border; | |
1530 | |
1531 XtVaGetValues(menuBar, | |
1532 XtNvSpace, &space, | |
1533 XtNborderWidth, &border, | |
1534 NULL); | |
1535 XtVaGetValues(menu->id, | |
1536 XtNheight, &height, | |
1537 NULL); | |
1538 #if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL) | |
1539 if (parent == toolBar && menu->tip != NULL) | |
1540 { | |
1541 /* We try to destroy this before the actual menu, because there are | |
1542 * callbacks, etc. that will be unregistered during the tooltip | |
1543 * destruction. | |
1544 * | |
1545 * If you call "gui_mch_destroy_beval_area()" after destroying | |
1546 * menu->id, then the tooltip's window will have already been | |
1547 * deallocated by Xt, and unknown behaviour will ensue (probably | |
1548 * a core dump). | |
1549 */ | |
1550 gui_mch_destroy_beval_area(menu->tip); | |
1551 menu->tip = NULL; | |
1552 } | |
1553 #endif | |
1554 /* | |
1555 * This is a hack to stop the Athena simpleMenuWidget from getting a | |
1556 * BadValue error when a menu's last child is destroyed. We check to | |
1557 * see if this is the last child and if so, don't delete it. The parent | |
1558 * will be deleted soon anyway, and it will delete it's children like | |
1559 * all good widgets do. | |
1560 */ | |
1561 /* NOTE: The cause of the BadValue X Protocol Error is because when the | |
1562 * last child is destroyed, it is first unmanaged, thus causing a | |
1563 * geometry resize request from the parent Shell widget. | |
1564 * Since the Shell widget has no more children, it is resized to have | |
1565 * width/height of 0. XConfigureWindow() is then called with the | |
1566 * width/height of 0, which generates the BadValue. | |
1567 * | |
1568 * This happens in phase two of the widget destruction process. | |
1569 */ | |
1570 { | |
1571 if (parent != menuBar | |
1572 #ifdef FEAT_TOOLBAR | |
1573 && parent != toolBar | |
1574 #endif | |
1575 ) | |
1576 { | |
1577 XtVaGetValues(parent, XtNnumChildren, &num_children, NULL); | |
1578 if (num_children > 1) | |
1579 XtDestroyWidget(menu->id); | |
1580 } | |
1581 else | |
1582 XtDestroyWidget(menu->id); | |
1583 menu->id = (Widget)0; | |
1584 } | |
1585 | |
1586 if (parent == menuBar) | |
1587 { | |
1588 if (!gui.menu_height_fixed) | |
1589 gui.menu_height = height + 2 * (space + border); | |
1590 } | |
1591 #ifdef FEAT_TOOLBAR | |
1592 else if (parent == toolBar) | |
1593 { | |
1594 /* When removing last toolbar item, don't display the toolbar. */ | |
1595 XtVaGetValues(toolBar, XtNnumChildren, &num_children, NULL); | |
1596 if (num_children == 0) | |
1597 gui_mch_show_toolbar(FALSE); | |
1598 else | |
1599 gui.toolbar_height = gui_mch_compute_toolbar_height(); | |
1600 } | |
1601 #endif | |
1602 } | |
1603 if (menu->submenu_id != (Widget)0) | |
1604 { | |
1605 XtDestroyWidget(menu->submenu_id); | |
1606 menu->submenu_id = (Widget)0; | |
1607 } | |
1608 } | |
1609 | |
1610 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1611 gui_athena_menu_timeout( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1612 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1613 XtIntervalId *id UNUSED) |
7 | 1614 { |
1615 Widget w = (Widget)client_data; | |
1616 Widget popup; | |
1617 | |
1618 timer = 0; | |
1619 if (XtIsSubclass(w,smeBSBObjectClass)) | |
1620 { | |
1621 Pixmap p; | |
1622 | |
1623 XtVaGetValues(w, XtNrightBitmap, &p, NULL); | |
1624 if ((p != None) && (p != XtUnspecifiedPixmap)) | |
1625 { | |
1626 /* We are dealing with an item that has a submenu */ | |
1627 popup = get_popup_entry(XtParent(w)); | |
1628 if (popup == (Widget)0) | |
1629 return; | |
1630 XtPopup(popup, XtGrabNonexclusive); | |
1631 } | |
1632 } | |
1633 } | |
1634 | |
1635 /* This routine is used to calculate the position (in screen coordinates) | |
1636 * where a submenu should appear relative to the menu entry that popped it | |
1637 * up. It should appear even with and just slightly to the left of the | |
1638 * rightmost end of the menu entry that caused the popup. | |
1639 * | |
1640 * This is called when XtPopup() is called. | |
1641 */ | |
1642 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1643 gui_athena_popup_callback( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1644 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1645 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1646 XtPointer call_data UNUSED) |
7 | 1647 { |
1648 /* Assumption: XtIsSubclass(XtParent(w),simpleMenuWidgetClass) */ | |
1649 vimmenu_T *menu = (vimmenu_T *)client_data; | |
1650 Dimension width; | |
1651 Position root_x, root_y; | |
1652 | |
1653 /* First, popdown any siblings that may have menus popped up */ | |
1654 { | |
1655 vimmenu_T *i; | |
1656 | |
1657 for (i = menu->parent->children; i != NULL; i = i->next) | |
1658 { | |
1659 if (i->submenu_id != NULL && XtIsManaged(i->submenu_id)) | |
1660 XtPopdown(i->submenu_id); | |
1661 } | |
1662 } | |
1663 XtVaGetValues(XtParent(w), | |
1664 XtNwidth, &width, | |
1665 NULL); | |
1666 /* Assumption: XawSimpleMenuGetActiveEntry(XtParent(w)) == menu->id */ | |
1667 /* i.e. This IS the active entry */ | |
1668 XtTranslateCoords(menu->id,width - 5, 0, &root_x, &root_y); | |
1669 XtVaSetValues(w, XtNx, root_x, | |
1670 XtNy, root_y, | |
1671 NULL); | |
1672 } | |
1673 | |
1674 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1675 gui_athena_popdown_submenus_action( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1676 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1677 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1678 String *args, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1679 Cardinal *nargs) |
7 | 1680 { |
1681 WidgetList children; | |
1682 Cardinal num_children; | |
1683 | |
1684 XtVaGetValues(w, XtNchildren, &children, | |
1685 XtNnumChildren, &num_children, | |
1686 NULL); | |
1687 for (; num_children > 0; --num_children) | |
1688 { | |
1689 Widget child = children[num_children - 1]; | |
1690 | |
1691 if (has_submenu(child)) | |
1692 { | |
1693 Widget temp_w; | |
1694 | |
1695 temp_w = submenu_widget(child); | |
1696 gui_athena_popdown_submenus_action(temp_w,event,args,nargs); | |
1697 XtPopdown(temp_w); | |
1698 } | |
1699 } | |
1700 } | |
1701 | |
1702 /* Used to determine if the given widget has a submenu that can be popped up. */ | |
1703 static Boolean | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1704 has_submenu(Widget widget) |
7 | 1705 { |
1706 if ((widget != NULL) && XtIsSubclass(widget,smeBSBObjectClass)) | |
1707 { | |
1708 Pixmap p; | |
1709 | |
1710 XtVaGetValues(widget, XtNrightBitmap, &p, NULL); | |
1711 if ((p != None) && (p != XtUnspecifiedPixmap)) | |
1712 return True; | |
1713 } | |
1714 return False; | |
1715 } | |
1716 | |
1717 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1718 gui_athena_delayed_arm_action( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1719 Widget w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1720 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1721 String *args, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1722 Cardinal *nargs) |
7 | 1723 { |
1724 Dimension width, height; | |
1725 | |
1726 if (event->type != MotionNotify) | |
1727 return; | |
1728 | |
1729 XtVaGetValues(w, | |
1730 XtNwidth, &width, | |
1731 XtNheight, &height, | |
1732 NULL); | |
1733 | |
1734 if (event->xmotion.x >= (int)width || event->xmotion.y >= (int)height) | |
1735 return; | |
1736 | |
1737 { | |
1738 static Widget previous_active_widget = NULL; | |
1739 Widget current; | |
1740 | |
1741 current = XawSimpleMenuGetActiveEntry(w); | |
1742 if (current != previous_active_widget) | |
1743 { | |
1744 if (timer) | |
1745 { | |
1746 /* If the timeout hasn't been triggered, remove it */ | |
1747 XtRemoveTimeOut(timer); | |
1748 } | |
1749 gui_athena_popdown_submenus_action(w,event,args,nargs); | |
1750 if (has_submenu(current)) | |
1751 { | |
1752 XtAppAddTimeOut(XtWidgetToApplicationContext(w), 600L, | |
1753 gui_athena_menu_timeout, | |
1754 (XtPointer)current); | |
1755 } | |
1756 previous_active_widget = current; | |
1757 } | |
1758 } | |
1759 } | |
1760 | |
1761 static Widget | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1762 get_popup_entry(Widget w) |
7 | 1763 { |
1764 Widget menuw; | |
1765 | |
1766 /* Get the active entry for the current menu */ | |
1767 if ((menuw = XawSimpleMenuGetActiveEntry(w)) == (Widget)0) | |
1768 return NULL; | |
1769 | |
1770 return submenu_widget(menuw); | |
1771 } | |
1772 | |
1773 /* Given the widget that has been determined to have a submenu, return the submenu widget | |
1774 * that is to be popped up. | |
1775 */ | |
1776 static Widget | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1777 submenu_widget(Widget widget) |
7 | 1778 { |
1779 /* Precondition: has_submenu(widget) == True | |
1780 * XtIsSubclass(XtParent(widget),simpleMenuWidgetClass) == True | |
1781 */ | |
1782 | |
1783 char_u *pullright_name; | |
1784 Widget popup; | |
1785 | |
1786 pullright_name = make_pull_name((char_u *)XtName(widget)); | |
1787 popup = XtNameToWidget(XtParent(widget), (char *)pullright_name); | |
1788 vim_free(pullright_name); | |
1789 | |
1790 return popup; | |
1791 /* Postcondition: (popup != NULL) implies | |
1792 * (XtIsSubclass(popup,simpleMenuWidgetClass) == True) */ | |
1793 } | |
1794 | |
1795 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1796 gui_mch_show_popupmenu(vimmenu_T *menu) |
7 | 1797 { |
1798 int rootx, rooty, winx, winy; | |
1799 Window root, child; | |
1800 unsigned int mask; | |
1801 | |
1802 if (menu->submenu_id == (Widget)0) | |
1803 return; | |
1804 | |
1805 /* Position the popup menu at the pointer */ | |
1806 if (XQueryPointer(gui.dpy, XtWindow(vimShell), &root, &child, | |
1807 &rootx, &rooty, &winx, &winy, &mask)) | |
1808 { | |
1809 rootx -= 30; | |
1810 if (rootx < 0) | |
1811 rootx = 0; | |
1812 rooty -= 5; | |
1813 if (rooty < 0) | |
1814 rooty = 0; | |
1815 XtVaSetValues(menu->submenu_id, | |
1816 XtNx, rootx, | |
1817 XtNy, rooty, | |
1818 NULL); | |
1819 } | |
1820 | |
1821 XtOverrideTranslations(menu->submenu_id, popupTrans); | |
1822 XtPopupSpringLoaded(menu->submenu_id); | |
1823 } | |
1824 | |
1825 #endif /* FEAT_MENU */ | |
1826 | |
1827 /* | |
1828 * Set the menu and scrollbar colors to their default values. | |
1829 */ | |
1830 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1831 gui_mch_def_colors(void) |
7 | 1832 { |
1833 /* | |
1834 * Get the colors ourselves. Using the automatic conversion doesn't | |
1835 * handle looking for approximate colors. | |
1836 */ | |
1837 if (gui.in_use) | |
1838 { | |
1839 gui.menu_fg_pixel = gui_get_color((char_u *)gui.rsrc_menu_fg_name); | |
1840 gui.menu_bg_pixel = gui_get_color((char_u *)gui.rsrc_menu_bg_name); | |
1841 gui.scroll_fg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_fg_name); | |
1842 gui.scroll_bg_pixel = gui_get_color((char_u *)gui.rsrc_scroll_bg_name); | |
1843 #ifdef FEAT_BEVAL | |
1844 gui.tooltip_fg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_fg_name); | |
1845 gui.tooltip_bg_pixel = gui_get_color((char_u *)gui.rsrc_tooltip_bg_name); | |
1846 #endif | |
1847 } | |
1848 } | |
1849 | |
1850 | |
1851 /* | |
1852 * Scrollbar stuff. | |
1853 */ | |
1854 | |
1855 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1856 gui_mch_set_scrollbar_thumb( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1857 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1858 long val, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1859 long size, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1860 long max) |
7 | 1861 { |
1862 double v, s; | |
1863 | |
1864 if (sb->id == (Widget)0) | |
1865 return; | |
1866 | |
1867 /* | |
1868 * Athena scrollbar must go from 0.0 to 1.0. | |
1869 */ | |
1870 if (max == 0) | |
1871 { | |
1872 /* So you can't scroll it at all (normally it scrolls past end) */ | |
1873 #ifdef FEAT_GUI_NEXTAW | |
1874 XawScrollbarSetThumb(sb->id, 0.0, 1.0); | |
1875 #else | |
1876 vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0); | |
1877 #endif | |
1878 } | |
1879 else | |
1880 { | |
1881 v = (double)val / (double)(max + 1); | |
1882 s = (double)size / (double)(max + 1); | |
1883 #ifdef FEAT_GUI_NEXTAW | |
1884 XawScrollbarSetThumb(sb->id, v, s); | |
1885 #else | |
1886 vim_XawScrollbarSetThumb(sb->id, v, s, 1.0); | |
1887 #endif | |
1888 } | |
1889 } | |
1890 | |
1891 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1892 gui_mch_set_scrollbar_pos( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1893 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1894 int x, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1895 int y, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1896 int w, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1897 int h) |
7 | 1898 { |
1899 if (sb->id == (Widget)0) | |
1900 return; | |
1901 | |
1902 XtUnmanageChild(sb->id); | |
1903 XtVaSetValues(sb->id, | |
1904 XtNhorizDistance, x, | |
1905 XtNvertDistance, y, | |
1906 XtNwidth, w, | |
1907 XtNheight, h, | |
1908 NULL); | |
1909 XtManageChild(sb->id); | |
1910 } | |
1911 | |
1912 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1913 gui_mch_enable_scrollbar(scrollbar_T *sb, int flag) |
7 | 1914 { |
1915 if (sb->id != (Widget)0) | |
1916 { | |
1917 if (flag) | |
1918 XtManageChild(sb->id); | |
1919 else | |
1920 XtUnmanageChild(sb->id); | |
1921 } | |
1922 } | |
1923 | |
1924 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1925 gui_mch_create_scrollbar( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1926 scrollbar_T *sb, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1927 int orient) /* SBAR_VERT or SBAR_HORIZ */ |
7 | 1928 { |
1929 sb->id = XtVaCreateWidget("scrollBar", | |
1930 #ifdef FEAT_GUI_NEXTAW | |
1931 scrollbarWidgetClass, vimForm, | |
1932 #else | |
1933 vim_scrollbarWidgetClass, vimForm, | |
1934 #endif | |
1935 XtNresizable, True, | |
1936 XtNtop, XtChainTop, | |
1937 XtNbottom, XtChainTop, | |
1938 XtNleft, XtChainLeft, | |
1939 XtNright, XtChainLeft, | |
1940 XtNborderWidth, 0, | |
1941 XtNorientation, (orient == SBAR_VERT) ? XtorientVertical | |
1942 : XtorientHorizontal, | |
1943 XtNforeground, gui.scroll_fg_pixel, | |
1944 XtNbackground, gui.scroll_bg_pixel, | |
1945 NULL); | |
1946 if (sb->id == (Widget)0) | |
1947 return; | |
1948 | |
1949 XtAddCallback(sb->id, XtNjumpProc, | |
1950 gui_athena_scroll_cb_jump, (XtPointer)sb->ident); | |
1951 XtAddCallback(sb->id, XtNscrollProc, | |
1952 gui_athena_scroll_cb_scroll, (XtPointer)sb->ident); | |
1953 | |
1954 #ifdef FEAT_GUI_NEXTAW | |
1955 XawScrollbarSetThumb(sb->id, 0.0, 1.0); | |
1956 #else | |
1957 vim_XawScrollbarSetThumb(sb->id, 0.0, 1.0, 0.0); | |
1958 #endif | |
1959 } | |
1960 | |
1961 #if defined(FEAT_WINDOWS) || defined(PROTO) | |
1962 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1963 gui_mch_destroy_scrollbar(scrollbar_T *sb) |
7 | 1964 { |
1965 if (sb->id != (Widget)0) | |
1966 XtDestroyWidget(sb->id); | |
1967 } | |
1968 #endif | |
1969 | |
1970 void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1971 gui_mch_set_scrollbar_colors(scrollbar_T *sb) |
7 | 1972 { |
1973 if (sb->id != (Widget)0) | |
1974 XtVaSetValues(sb->id, | |
1975 XtNforeground, gui.scroll_fg_pixel, | |
1976 XtNbackground, gui.scroll_bg_pixel, | |
1977 NULL); | |
1978 | |
1979 /* This is needed for the rectangle below the vertical scrollbars. */ | |
1980 if (sb == &gui.bottom_sbar && vimForm != (Widget)0) | |
1981 gui_athena_scroll_colors(vimForm); | |
1982 } | |
1983 | |
1984 /* | |
1985 * Miscellaneous stuff: | |
1986 */ | |
1987 Window | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1988 gui_x11_get_wid(void) |
7 | 1989 { |
1990 return XtWindow(textArea); | |
1991 } | |
1992 | |
1993 #if defined(FEAT_BROWSE) || defined(PROTO) | |
1994 /* | |
1995 * Put up a file requester. | |
1996 * Returns the selected name in allocated memory, or NULL for Cancel. | |
1997 */ | |
1998 char_u * | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1999 gui_mch_browse( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2000 int saving UNUSED, /* select file to write */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2001 char_u *title, /* title for the window */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2002 char_u *dflt, /* default name */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2003 char_u *ext UNUSED, /* extension added */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2004 char_u *initdir, /* initial directory, NULL for current dir */ |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2005 char_u *filter UNUSED) /* file name filter */ |
7 | 2006 { |
2007 Position x, y; | |
2008 char_u dirbuf[MAXPATHL]; | |
2009 | |
2010 /* Concatenate "initdir" and "dflt". */ | |
2011 if (initdir == NULL || *initdir == NUL) | |
2012 mch_dirname(dirbuf, MAXPATHL); | |
2013 else if (STRLEN(initdir) + 2 < MAXPATHL) | |
2014 STRCPY(dirbuf, initdir); | |
2015 else | |
2016 dirbuf[0] = NUL; | |
2017 if (dflt != NULL && *dflt != NUL | |
2018 && STRLEN(dirbuf) + 2 + STRLEN(dflt) < MAXPATHL) | |
2019 { | |
2020 add_pathsep(dirbuf); | |
2021 STRCAT(dirbuf, dflt); | |
2022 } | |
2023 | |
2024 /* Position the file selector just below the menubar */ | |
2025 XtTranslateCoords(vimShell, (Position)0, (Position) | |
2026 #ifdef FEAT_MENU | |
2027 gui.menu_height | |
2028 #else | |
2029 0 | |
2030 #endif | |
2031 , &x, &y); | |
2032 return (char_u *)vim_SelFile(vimShell, (char *)title, (char *)dirbuf, | |
2033 NULL, (int)x, (int)y, gui.menu_fg_pixel, gui.menu_bg_pixel, | |
2034 gui.scroll_fg_pixel, gui.scroll_bg_pixel); | |
2035 } | |
2036 #endif | |
2037 | |
2038 #if defined(FEAT_GUI_DIALOG) || defined(PROTO) | |
2039 | |
2040 static int dialogStatus; | |
2041 static Atom dialogatom; | |
2042 | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2043 static void keyhit_callback(Widget w, XtPointer client_data, XEvent *event, Boolean *cont); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2044 static void butproc(Widget w, XtPointer client_data, XtPointer call_data); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
4352
diff
changeset
|
2045 static void dialog_wm_handler(Widget w, XtPointer client_data, XEvent *event, Boolean *dum); |
7 | 2046 |
2047 /* | |
2048 * Callback function for the textfield. When CR is hit this works like | |
2049 * hitting the "OK" button, ESC like "Cancel". | |
2050 */ | |
2051 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2052 keyhit_callback( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2053 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2054 XtPointer client_data UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2055 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2056 Boolean *cont UNUSED) |
7 | 2057 { |
2058 char buf[2]; | |
2059 | |
2060 if (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) | |
2061 { | |
2062 if (*buf == CAR) | |
2063 dialogStatus = 1; | |
2064 else if (*buf == ESC) | |
2065 dialogStatus = 0; | |
2066 } | |
2067 } | |
2068 | |
2069 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2070 butproc( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2071 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2072 XtPointer client_data, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2073 XtPointer call_data UNUSED) |
7 | 2074 { |
2075 dialogStatus = (int)(long)client_data + 1; | |
2076 } | |
2077 | |
2078 /* | |
2079 * Function called when dialog window closed. | |
2080 */ | |
2081 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2082 dialog_wm_handler( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2083 Widget w UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2084 XtPointer client_data UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2085 XEvent *event, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2086 Boolean *dum UNUSED) |
7 | 2087 { |
2088 if (event->type == ClientMessage | |
1887 | 2089 && (Atom)((XClientMessageEvent *)event)->data.l[0] == dialogatom) |
7 | 2090 dialogStatus = 0; |
2091 } | |
2092 | |
2093 int | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2094 gui_mch_dialog( |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2095 int type UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2096 char_u *title, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2097 char_u *message, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2098 char_u *buttons, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2099 int dfltbutton UNUSED, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2100 char_u *textfield, |
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2101 int ex_cmd UNUSED) |
7 | 2102 { |
2103 char_u *buts; | |
2104 char_u *p, *next; | |
2105 XtAppContext app; | |
2106 XEvent event; | |
2107 Position wd, hd; | |
2108 Position wv, hv; | |
2109 Position x, y; | |
2110 Widget dialog; | |
2111 Widget dialogshell; | |
2112 Widget dialogmessage; | |
2113 Widget dialogtextfield = 0; | |
2114 Widget dialogButton; | |
2115 Widget prev_dialogButton = NULL; | |
2116 int butcount; | |
2117 int vertical; | |
2118 | |
2119 if (title == NULL) | |
2120 title = (char_u *)_("Vim dialog"); | |
2121 dialogStatus = -1; | |
2122 | |
2123 /* if our pointer is currently hidden, then we should show it. */ | |
2124 gui_mch_mousehide(FALSE); | |
2125 | |
2126 /* Check 'v' flag in 'guioptions': vertical button placement. */ | |
2127 vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL); | |
2128 | |
2129 /* The shell is created each time, to make sure it is resized properly */ | |
2130 dialogshell = XtVaCreatePopupShell("dialogShell", | |
2131 transientShellWidgetClass, vimShell, | |
2132 XtNtitle, title, | |
2133 NULL); | |
2134 if (dialogshell == (Widget)0) | |
2135 goto error; | |
2136 | |
2137 dialog = XtVaCreateManagedWidget("dialog", | |
2138 formWidgetClass, dialogshell, | |
2139 XtNdefaultDistance, 20, | |
2140 NULL); | |
2141 if (dialog == (Widget)0) | |
2142 goto error; | |
2143 gui_athena_menu_colors(dialog); | |
2144 dialogmessage = XtVaCreateManagedWidget("dialogMessage", | |
2145 labelWidgetClass, dialog, | |
2146 XtNlabel, message, | |
2147 XtNtop, XtChainTop, | |
2148 XtNbottom, XtChainTop, | |
2149 XtNleft, XtChainLeft, | |
2150 XtNright, XtChainLeft, | |
2151 XtNresizable, True, | |
2152 XtNborderWidth, 0, | |
2153 NULL); | |
2154 gui_athena_menu_colors(dialogmessage); | |
2155 | |
2156 if (textfield != NULL) | |
2157 { | |
2158 dialogtextfield = XtVaCreateManagedWidget("textfield", | |
2159 asciiTextWidgetClass, dialog, | |
2160 XtNwidth, 400, | |
2161 XtNtop, XtChainTop, | |
2162 XtNbottom, XtChainTop, | |
2163 XtNleft, XtChainLeft, | |
2164 XtNright, XtChainRight, | |
2165 XtNfromVert, dialogmessage, | |
2166 XtNresizable, True, | |
2167 XtNstring, textfield, | |
2168 XtNlength, IOSIZE, | |
2169 XtNuseStringInPlace, True, | |
2170 XtNeditType, XawtextEdit, | |
2171 XtNwrap, XawtextWrapNever, | |
2172 XtNresize, XawtextResizeHeight, | |
2173 NULL); | |
2174 XtManageChild(dialogtextfield); | |
2175 XtAddEventHandler(dialogtextfield, KeyPressMask, False, | |
2176 (XtEventHandler)keyhit_callback, (XtPointer)NULL); | |
2177 XawTextSetInsertionPoint(dialogtextfield, | |
2178 (XawTextPosition)STRLEN(textfield)); | |
2179 XtSetKeyboardFocus(dialog, dialogtextfield); | |
2180 } | |
2181 | |
2182 /* make a copy, so that we can insert NULs */ | |
2183 buts = vim_strsave(buttons); | |
2184 if (buts == NULL) | |
2185 return -1; | |
2186 | |
2187 p = buts; | |
2188 for (butcount = 0; *p; ++butcount) | |
2189 { | |
2190 for (next = p; *next; ++next) | |
2191 { | |
2192 if (*next == DLG_HOTKEY_CHAR) | |
1620 | 2193 STRMOVE(next, next + 1); |
7 | 2194 if (*next == DLG_BUTTON_SEP) |
2195 { | |
2196 *next++ = NUL; | |
2197 break; | |
2198 } | |
2199 } | |
2200 dialogButton = XtVaCreateManagedWidget("button", | |
2201 commandWidgetClass, dialog, | |
2202 XtNlabel, p, | |
2203 XtNtop, XtChainBottom, | |
2204 XtNbottom, XtChainBottom, | |
2205 XtNleft, XtChainLeft, | |
2206 XtNright, XtChainLeft, | |
2207 XtNfromVert, textfield == NULL ? dialogmessage : dialogtextfield, | |
2208 XtNvertDistance, vertical ? 4 : 20, | |
2209 XtNresizable, False, | |
2210 NULL); | |
2211 gui_athena_menu_colors(dialogButton); | |
2212 if (butcount > 0) | |
2213 XtVaSetValues(dialogButton, | |
2214 vertical ? XtNfromVert : XtNfromHoriz, prev_dialogButton, | |
2215 NULL); | |
2216 | |
2255 | 2217 XtAddCallback(dialogButton, XtNcallback, butproc, (XtPointer)(long_u)butcount); |
7 | 2218 p = next; |
2219 prev_dialogButton = dialogButton; | |
2220 } | |
2221 vim_free(buts); | |
2222 | |
2223 XtRealizeWidget(dialogshell); | |
2224 | |
2225 /* Setup for catching the close-window event, don't let it close Vim! */ | |
2226 dialogatom = XInternAtom(gui.dpy, "WM_DELETE_WINDOW", False); | |
2227 XSetWMProtocols(gui.dpy, XtWindow(dialogshell), &dialogatom, 1); | |
2228 XtAddEventHandler(dialogshell, NoEventMask, True, dialog_wm_handler, NULL); | |
2229 | |
2230 XtVaGetValues(dialogshell, | |
2231 XtNwidth, &wd, | |
2232 XtNheight, &hd, | |
2233 NULL); | |
2234 XtVaGetValues(vimShell, | |
2235 XtNwidth, &wv, | |
2236 XtNheight, &hv, | |
2237 NULL); | |
2238 XtTranslateCoords(vimShell, | |
2239 (Position)((wv - wd) / 2), | |
2240 (Position)((hv - hd) / 2), | |
2241 &x, &y); | |
2242 if (x < 0) | |
2243 x = 0; | |
2244 if (y < 0) | |
2245 y = 0; | |
2246 XtVaSetValues(dialogshell, XtNx, x, XtNy, y, NULL); | |
2247 | |
2248 /* Position the mouse pointer in the dialog, required for when focus | |
2249 * follows mouse. */ | |
2250 XWarpPointer(gui.dpy, (Window)0, XtWindow(dialogshell), 0, 0, 0, 0, 20, 40); | |
2251 | |
2252 | |
2253 app = XtWidgetToApplicationContext(dialogshell); | |
2254 | |
2255 XtPopup(dialogshell, XtGrabNonexclusive); | |
2256 | |
405 | 2257 for (;;) |
7 | 2258 { |
2259 XtAppNextEvent(app, &event); | |
2260 XtDispatchEvent(&event); | |
2261 if (dialogStatus >= 0) | |
2262 break; | |
2263 } | |
2264 | |
2265 XtPopdown(dialogshell); | |
2266 | |
2267 if (textfield != NULL && dialogStatus < 0) | |
2268 *textfield = NUL; | |
2269 | |
2270 error: | |
2271 XtDestroyWidget(dialogshell); | |
2272 | |
2273 return dialogStatus; | |
2274 } | |
2275 #endif | |
2276 | |
2277 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU) | |
2278 /* | |
2279 * Set the colors of Widget "id" to the menu colors. | |
2280 */ | |
2281 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2282 gui_athena_menu_colors(Widget id) |
7 | 2283 { |
2284 if (gui.menu_bg_pixel != INVALCOLOR) | |
2285 XtVaSetValues(id, XtNbackground, gui.menu_bg_pixel, NULL); | |
2286 if (gui.menu_fg_pixel != INVALCOLOR) | |
2287 XtVaSetValues(id, XtNforeground, gui.menu_fg_pixel, NULL); | |
2288 } | |
2289 #endif | |
2290 | |
2291 /* | |
2292 * Set the colors of Widget "id" to the scroll colors. | |
2293 */ | |
2294 static void | |
7821
81794242a275
commit https://github.com/vim/vim/commit/66f948e928d5e0cd3123af902aa8ac1613534c94
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2295 gui_athena_scroll_colors(Widget id) |
7 | 2296 { |
2297 if (gui.scroll_bg_pixel != INVALCOLOR) | |
2298 XtVaSetValues(id, XtNbackground, gui.scroll_bg_pixel, NULL); | |
2299 if (gui.scroll_fg_pixel != INVALCOLOR) | |
2300 XtVaSetValues(id, XtNforeground, gui.scroll_fg_pixel, NULL); | |
2301 } |