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