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