Mercurial > hg > xemacs-beta
comparison src/toolbar-msw.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 8de8e3f6228a |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* toolbar implementation -- mswindows interface. | |
2 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
4 Copyright (C) 1995, 1996 Ben Wing. | |
5 Copyright (C) 1996 Chuck Thompson. | |
6 Copyright (C) 1998 Andy Piper. | |
7 | |
8 This file is part of XEmacs. | |
9 | |
10 XEmacs is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
12 Free Software Foundation; either version 2, or (at your option) any | |
13 later version. | |
14 | |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with XEmacs; see the file COPYING. If not, write to | |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
23 Boston, MA 02111-1307, USA. */ | |
24 | |
25 /* This implementation by Andy Piper <andyp@parallax.co.uk>, with bits | |
26 borrowed from toolbar-x.c */ | |
27 | |
28 /* Synched up with: Not in FSF. */ | |
29 | |
30 #include <config.h> | |
31 #include "lisp.h" | |
32 | |
33 #include "faces.h" | |
34 #include "frame.h" | |
35 #include "toolbar.h" | |
36 #include "window.h" | |
37 #include "gui.h" | |
38 #include "elhash.h" | |
39 #include "console-msw.h" | |
40 #include "glyphs-msw.h" | |
41 #include "objects-msw.h" | |
42 | |
43 #define TOOLBAR_ITEM_ID_MIN 0x4000 | |
44 #define TOOLBAR_ITEM_ID_MAX 0x7FFF | |
45 #define TOOLBAR_ITEM_ID_BITS(x) (((x) & 0x3FFF) | 0x4000) | |
46 #define TOOLBAR_ID_BIAS 16 | |
47 #define TOOLBAR_HANDLE(f,p) \ | |
48 GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS + p) | |
49 #ifndef TB_SETIMAGELIST | |
50 #define TB_SETIMAGELIST (WM_USER + 48) | |
51 #define TB_GETIMAGELIST (WM_USER + 49) | |
52 #define TB_SETDISABLEDIMAGELIST (WM_USER + 54) | |
53 #define TB_GETDISABLEDIMAGELIST (WM_USER + 55) | |
54 #endif | |
55 #ifndef TB_SETPADDING | |
56 #define TB_SETPADDING (WM_USER + 87) | |
57 #endif | |
58 #define MSWINDOWS_BUTTON_SHADOW_THICKNESS 2 | |
59 #define MSWINDOWS_BLANK_SIZE 5 | |
60 #define MSWINDOWS_MINIMUM_TOOLBAR_SIZE 8 | |
61 | |
62 static void | |
63 mswindows_move_toolbar (struct frame *f, enum toolbar_pos pos); | |
64 | |
65 #define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \ | |
66 do { \ | |
67 switch (pos) \ | |
68 { \ | |
69 case TOP_TOOLBAR: \ | |
70 (frame)->top_toolbar_was_visible = flag; \ | |
71 break; \ | |
72 case BOTTOM_TOOLBAR: \ | |
73 (frame)->bottom_toolbar_was_visible = flag; \ | |
74 break; \ | |
75 case LEFT_TOOLBAR: \ | |
76 (frame)->left_toolbar_was_visible = flag; \ | |
77 break; \ | |
78 case RIGHT_TOOLBAR: \ | |
79 (frame)->right_toolbar_was_visible = flag; \ | |
80 break; \ | |
81 default: \ | |
82 abort (); \ | |
83 } \ | |
84 } while (0) | |
85 | |
86 static int | |
87 allocate_toolbar_item_id (struct frame* f, struct toolbar_button* button, | |
88 enum toolbar_pos pos) | |
89 { | |
90 /* hmm what do we generate an id based on */ | |
91 int id = TOOLBAR_ITEM_ID_BITS (internal_hash (button->callback, 0)); | |
92 while (!NILP (Fgethash (make_int (id), | |
93 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f), Qnil))) | |
94 { | |
95 id = TOOLBAR_ITEM_ID_BITS (id + 1); | |
96 } | |
97 return id; | |
98 } | |
99 | |
100 static void | |
101 mswindows_clear_toolbar (struct frame *f, enum toolbar_pos pos, | |
102 int thickness_change) | |
103 { | |
104 HIMAGELIST ilist=NULL; | |
105 int i; | |
106 HWND toolbarwnd = TOOLBAR_HANDLE(f, pos); | |
107 if (toolbarwnd) | |
108 { | |
109 TBBUTTON info; | |
110 | |
111 /* Delete the buttons and remove the command from the hash table*/ | |
112 i = SendMessage (toolbarwnd, TB_BUTTONCOUNT, 0, 0); | |
113 for (i--; i >= 0; i--) | |
114 { | |
115 SendMessage (toolbarwnd, TB_GETBUTTON, (WPARAM)i, | |
116 (LPARAM)&info); | |
117 Fremhash(make_int(info.idCommand), | |
118 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f)); | |
119 SendMessage (toolbarwnd, TB_DELETEBUTTON, (WPARAM)i, 0); | |
120 } | |
121 | |
122 /* finally get rid of the image list assuming it clears up its | |
123 bitmaps */ | |
124 SendMessage (toolbarwnd, TB_GETIMAGELIST, 0, (LONG) &ilist); | |
125 if (ilist) | |
126 { | |
127 ImageList_Destroy(ilist); | |
128 } | |
129 SendMessage (toolbarwnd, TB_SETIMAGELIST, 0, (LPARAM)NULL); | |
130 | |
131 ShowWindow(toolbarwnd, SW_HIDE); | |
132 } | |
133 | |
134 FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos)=0; | |
135 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0); | |
136 } | |
137 | |
138 static void | |
139 mswindows_output_toolbar (struct frame *f, enum toolbar_pos pos) | |
140 { | |
141 int x, y, bar_width, bar_height, vert; | |
142 int width=-1, height=-1, bmwidth=0, bmheight=0, maxbmwidth, maxbmheight; | |
143 int style_3d=0; | |
144 int border_width = FRAME_REAL_TOOLBAR_BORDER_WIDTH (f, pos); | |
145 Lisp_Object button, glyph, instance; | |
146 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
147 | |
148 int nbuttons=0; | |
149 int shadow_thickness = 2; /* get this from somewhere else? */ | |
150 int window_frame_width = 3; | |
151 int padding = (border_width + shadow_thickness) * 2; | |
152 unsigned int checksum=0; | |
153 struct window *w = XWINDOW (window); | |
154 TBBUTTON* button_tbl, *tbbutton; | |
155 HIMAGELIST ilist=NULL; | |
156 HWND toolbarwnd=NULL; | |
157 | |
158 get_toolbar_coords (f, pos, &x, &y, &bar_width, &bar_height, &vert, 0); | |
159 | |
160 /* ediff bogusly sets the height to 2 for some obscure X-specific | |
161 reason. This ensures that we only try and output a toolbar for | |
162 sensible sizes */ | |
163 if (bar_width < MSWINDOWS_MINIMUM_TOOLBAR_SIZE | |
164 || | |
165 bar_height < MSWINDOWS_MINIMUM_TOOLBAR_SIZE) | |
166 { | |
167 return; | |
168 } | |
169 | |
170 if (x==1) | |
171 x=0; | |
172 | |
173 toolbarwnd = TOOLBAR_HANDLE (f,pos); | |
174 | |
175 /* set button sizes based on bar size */ | |
176 if (vert) | |
177 { | |
178 if (style_3d) | |
179 { | |
180 width = height = bar_width | |
181 - (window_frame_width + shadow_thickness) * 2; | |
182 } | |
183 else | |
184 width = height = bar_width; | |
185 | |
186 maxbmwidth = maxbmheight = width - padding; | |
187 } | |
188 else | |
189 { | |
190 if (style_3d) | |
191 { | |
192 height = width = bar_height | |
193 - (window_frame_width + shadow_thickness) * 2; | |
194 } | |
195 else | |
196 width = height = bar_height; | |
197 | |
198 maxbmwidth = maxbmheight = width - padding; | |
199 } | |
200 | |
201 button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
202 | |
203 /* First loop over all of the buttons to determine how many there | |
204 are. This loop will also make sure that all instances are | |
205 instantiated so when we actually output them they will come up | |
206 immediately. */ | |
207 while (!NILP (button)) | |
208 { | |
209 | |
210 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
211 checksum = HASH5 (checksum, | |
212 internal_hash (get_toolbar_button_glyph(w, tb), 0), | |
213 internal_hash (tb->callback, 0), | |
214 width, | |
215 LISP_HASH (w->toolbar_buttons_captioned_p)); | |
216 button = tb->next; | |
217 nbuttons++; | |
218 } | |
219 | |
220 /* only rebuild if something has changed */ | |
221 if (!toolbarwnd || FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos)!=checksum) | |
222 { | |
223 /* remove the old one */ | |
224 mswindows_clear_toolbar (f, pos, 0); | |
225 | |
226 FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos)=checksum; | |
227 | |
228 /* build up the data required by win32 fns. */ | |
229 button_tbl = xnew_array_and_zero (TBBUTTON, nbuttons); | |
230 button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
231 tbbutton = button_tbl; | |
232 | |
233 while (!NILP (button)) | |
234 { | |
235 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
236 HBITMAP bitmap=NULL, mask=NULL; | |
237 bitmap=mask=NULL; | |
238 | |
239 if (tb->blank) | |
240 tbbutton->fsStyle = TBSTYLE_SEP; | |
241 else | |
242 { | |
243 tbbutton->idCommand = allocate_toolbar_item_id (f, tb, pos); | |
244 /* currently we output the toolbar again with disabled | |
245 buttons it might be good to use the ms disabled code | |
246 instead but that means another image list, so we'll stick | |
247 with the emacs model. */ | |
248 tbbutton->fsState = tb->enabled ? TBSTATE_ENABLED : | |
249 TBSTATE_INDETERMINATE; | |
250 tbbutton->fsStyle = TBSTYLE_BUTTON; | |
251 tbbutton->dwData=0; | |
252 tbbutton->iString=0; | |
253 | |
254 /* mess with the button image */ | |
255 glyph = get_toolbar_button_glyph (w, tb); | |
256 | |
257 if (GLYPHP (glyph)) | |
258 instance = glyph_image_instance (glyph, window, | |
259 ERROR_ME_NOT, 1); | |
260 else | |
261 instance = Qnil; | |
262 | |
263 if (IMAGE_INSTANCEP (instance)) | |
264 { | |
265 struct Lisp_Image_Instance* p = XIMAGE_INSTANCE (instance); | |
266 | |
267 if (IMAGE_INSTANCE_PIXMAP_TYPE_P (p)) | |
268 { | |
269 /* we are going to honor the toolbar settings | |
270 and resize the bitmaps accordingly if they are | |
271 too big. If they are too small we leave them | |
272 and pad the difference - unless a different size | |
273 crops up in the middle, at which point we *have* | |
274 to resize since the ImageList won't cope.*/ | |
275 | |
276 if ((bmwidth | |
277 && | |
278 IMAGE_INSTANCE_PIXMAP_WIDTH (p) != bmwidth) | |
279 || | |
280 (bmheight | |
281 && | |
282 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) != bmheight) | |
283 || | |
284 IMAGE_INSTANCE_PIXMAP_WIDTH (p) > maxbmwidth | |
285 || | |
286 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > maxbmheight) | |
287 { | |
288 if (!bmheight) | |
289 bmheight = min (maxbmheight, | |
290 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
291 if (!bmwidth) | |
292 bmwidth = min (maxbmwidth, | |
293 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
294 | |
295 if (! (bitmap = mswindows_create_resized_bitmap | |
296 (p, f, bmwidth, bmheight))) | |
297 { | |
298 xfree (button_tbl); | |
299 if (ilist) ImageList_Destroy (ilist); | |
300 signal_simple_error ("Couldn't resize pixmap", | |
301 instance); | |
302 } | |
303 /* we don't care if the mask fails */ | |
304 mask = mswindows_create_resized_mask | |
305 (p, f, bmwidth, bmheight); | |
306 } | |
307 else | |
308 { | |
309 if (!bmwidth) | |
310 bmwidth = IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
311 if (!bmheight) | |
312 bmheight = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
313 } | |
314 | |
315 /* need to build an image list for the bitmaps */ | |
316 if (!ilist && !(ilist = ImageList_Create | |
317 ( bmwidth, bmheight, | |
318 (IMAGE_INSTANCE_MSWINDOWS_MASK (p) | |
319 ? ILC_MASK : 0) | ILC_COLOR24, | |
320 nbuttons, nbuttons * 2 ))) | |
321 { | |
322 xfree (button_tbl); | |
323 signal_simple_error ("Couldn't create image list", | |
324 instance); | |
325 } | |
326 | |
327 /* make the mask actually do something */ | |
328 ImageList_SetBkColor (ilist, CLR_NONE); | |
329 /* add a bitmap to the list */ | |
330 if ((tbbutton->iBitmap = | |
331 ImageList_Add | |
332 (ilist, | |
333 bitmap ? bitmap | |
334 : IMAGE_INSTANCE_MSWINDOWS_BITMAP (p), | |
335 mask ? mask | |
336 : IMAGE_INSTANCE_MSWINDOWS_MASK (p))) < 0) | |
337 { | |
338 xfree (button_tbl); | |
339 if (ilist) ImageList_Destroy (ilist); | |
340 signal_simple_error | |
341 ("couldn't add image to image list", instance); | |
342 } | |
343 /* we're done with these now */ | |
344 DeleteObject (bitmap); | |
345 DeleteObject (mask); | |
346 } | |
347 } | |
348 | |
349 Fputhash (make_int (tbbutton->idCommand), | |
350 button, FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f)); | |
351 } | |
352 | |
353 /* now fix up the button size */ | |
354 tb->x = x; | |
355 tb->y = y; | |
356 tb->vertical = vert; | |
357 tb->border_width = border_width; | |
358 tb->width = width + MSWINDOWS_BUTTON_SHADOW_THICKNESS * 2; | |
359 tb->height = height + MSWINDOWS_BUTTON_SHADOW_THICKNESS * 2; | |
360 | |
361 if (tb->blank) | |
362 { | |
363 if (vert) | |
364 tb->height = MSWINDOWS_BLANK_SIZE; | |
365 else | |
366 tb->width = MSWINDOWS_BLANK_SIZE; | |
367 } | |
368 | |
369 if (vert) | |
370 y += tb->height; | |
371 else | |
372 x += tb->width; | |
373 /* move on to the next button */ | |
374 tbbutton++; | |
375 button = tb->next; | |
376 } | |
377 | |
378 button = FRAME_TOOLBAR_BUTTONS (f, pos); | |
379 | |
380 /* create the toolbar window? */ | |
381 if (!toolbarwnd | |
382 && | |
383 (toolbarwnd = | |
384 CreateWindowEx ( WS_EX_WINDOWEDGE, | |
385 TOOLBARCLASSNAME, | |
386 NULL, | |
387 WS_CHILD | WS_VISIBLE | |
388 | (style_3d ? WS_DLGFRAME : 0) | |
389 | TBSTYLE_TOOLTIPS | CCS_NORESIZE | |
390 | CCS_NOPARENTALIGN | CCS_NODIVIDER, | |
391 x, y, bar_width, bar_height, | |
392 FRAME_MSWINDOWS_HANDLE (f), | |
393 (HMENU)(TOOLBAR_ID_BIAS + pos), | |
394 NULL, | |
395 NULL))==NULL) | |
396 { | |
397 xfree (button_tbl); | |
398 ImageList_Destroy (ilist); | |
399 error ("couldn't create toolbar"); | |
400 } | |
401 | |
402 /* finally populate with images */ | |
403 if (SendMessage (toolbarwnd, TB_BUTTONSTRUCTSIZE, | |
404 (WPARAM)sizeof(TBBUTTON), (LPARAM)0) == -1) | |
405 { | |
406 mswindows_clear_toolbar (f, pos, 0); | |
407 error ("couldn't set button structure size"); | |
408 } | |
409 | |
410 if (vert) | |
411 height = min (bmheight + padding, height); | |
412 else | |
413 width = min (bmwidth + padding, width); | |
414 | |
415 /* pad the buttons */ | |
416 SendMessage (toolbarwnd, TB_SETPADDING, | |
417 0, MAKELPARAM(width - bmwidth, height - bmheight)); | |
418 | |
419 /* set the size of buttons */ | |
420 SendMessage (toolbarwnd, TB_SETBUTTONSIZE, 0, | |
421 (LPARAM)MAKELONG (width, height)); | |
422 | |
423 /* set the size of bitmaps */ | |
424 SendMessage (toolbarwnd, TB_SETBITMAPSIZE, 0, | |
425 (LPARAM)MAKELONG (bmwidth, bmheight)); | |
426 | |
427 /* tell it we've done it */ | |
428 SendMessage (toolbarwnd, TB_AUTOSIZE, 0, 0); | |
429 | |
430 /* finally populate with images */ | |
431 if (!SendMessage (toolbarwnd, TB_ADDBUTTONS, | |
432 (WPARAM)nbuttons, (LPARAM)button_tbl)) | |
433 { | |
434 mswindows_clear_toolbar (f, pos, 0); | |
435 error ("couldn't add button list to toolbar"); | |
436 } | |
437 | |
438 /* vertical toolbars need more rows */ | |
439 if (vert) | |
440 { | |
441 RECT tmp; | |
442 SendMessage (toolbarwnd, TB_SETROWS, | |
443 MAKEWPARAM(nbuttons, FALSE), (LPARAM)&tmp); | |
444 } | |
445 | |
446 else | |
447 { | |
448 RECT tmp; | |
449 SendMessage (toolbarwnd, TB_SETROWS, MAKEWPARAM(1, FALSE), | |
450 (LPARAM)&tmp); | |
451 } | |
452 | |
453 /* finally populate with images */ | |
454 if (SendMessage (toolbarwnd, TB_SETIMAGELIST, 0, | |
455 (LPARAM)ilist) < 0 | |
456 || | |
457 SendMessage (toolbarwnd, TB_SETDISABLEDIMAGELIST, 0, | |
458 (LPARAM)ilist) < 0) | |
459 { | |
460 mswindows_clear_toolbar (f, pos, 0); | |
461 error ("couldn't add image list to toolbar"); | |
462 } | |
463 | |
464 /* now display the window */ | |
465 ShowWindow (toolbarwnd, SW_SHOW); | |
466 /* no idea why this is necessary but initial display will not | |
467 happen otherwise. */ | |
468 mswindows_move_toolbar (f, pos); | |
469 | |
470 if (button_tbl) xfree (button_tbl); | |
471 | |
472 SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1); | |
473 } | |
474 } | |
475 | |
476 static void | |
477 mswindows_move_toolbar (struct frame *f, enum toolbar_pos pos) | |
478 { | |
479 int bar_x, bar_y, bar_width, bar_height, vert; | |
480 HWND toolbarwnd = TOOLBAR_HANDLE(f,pos); | |
481 | |
482 if (toolbarwnd) | |
483 { | |
484 get_toolbar_coords (f, pos, &bar_x, &bar_y, &bar_width, &bar_height, | |
485 &vert, 1); | |
486 | |
487 /* #### This terrible mangling with coordinates perhaps | |
488 arises from different treatment of toolbar positions | |
489 by Windows and by XEmacs. */ | |
490 switch (pos) | |
491 { | |
492 case TOP_TOOLBAR: | |
493 bar_x--; bar_y-=2; | |
494 bar_width+=3; bar_height+=3; | |
495 break; | |
496 case LEFT_TOOLBAR: | |
497 bar_x--; bar_y-=2; | |
498 bar_height++; bar_width++; | |
499 break; | |
500 case BOTTOM_TOOLBAR: | |
501 bar_y-=2; | |
502 bar_width+=4; bar_height+=4; | |
503 break; | |
504 case RIGHT_TOOLBAR: | |
505 bar_y-=2; bar_x++; | |
506 bar_width++; bar_height++; | |
507 break; | |
508 } | |
509 SetWindowPos (toolbarwnd, NULL, bar_x, bar_y, | |
510 bar_width, bar_height, SWP_NOZORDER); | |
511 } | |
512 } | |
513 | |
514 static void | |
515 mswindows_redraw_exposed_toolbars (struct frame *f, int x, int y, int width, | |
516 int height) | |
517 { | |
518 assert (FRAME_MSWINDOWS_P (f)); | |
519 | |
520 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) | |
521 mswindows_move_toolbar (f, TOP_TOOLBAR); | |
522 | |
523 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) | |
524 mswindows_move_toolbar (f, BOTTOM_TOOLBAR); | |
525 | |
526 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) | |
527 mswindows_move_toolbar (f, LEFT_TOOLBAR); | |
528 | |
529 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) | |
530 mswindows_move_toolbar (f, RIGHT_TOOLBAR); | |
531 } | |
532 | |
533 static void | |
534 mswindows_redraw_frame_toolbars (struct frame *f) | |
535 { | |
536 mswindows_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f), | |
537 FRAME_PIXHEIGHT (f)); | |
538 } | |
539 | |
540 static void | |
541 mswindows_initialize_frame_toolbars (struct frame *f) | |
542 { | |
543 | |
544 } | |
545 | |
546 static void | |
547 mswindows_output_frame_toolbars (struct frame *f) | |
548 { | |
549 assert (FRAME_MSWINDOWS_P (f)); | |
550 | |
551 if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f)) | |
552 mswindows_output_toolbar (f, TOP_TOOLBAR); | |
553 else if (f->top_toolbar_was_visible) | |
554 mswindows_clear_toolbar (f, TOP_TOOLBAR, 0); | |
555 | |
556 if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f)) | |
557 mswindows_output_toolbar (f, BOTTOM_TOOLBAR); | |
558 else if (f->bottom_toolbar_was_visible) | |
559 mswindows_clear_toolbar (f, BOTTOM_TOOLBAR, 0); | |
560 | |
561 if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f)) | |
562 mswindows_output_toolbar (f, LEFT_TOOLBAR); | |
563 else if (f->left_toolbar_was_visible) | |
564 mswindows_clear_toolbar (f, LEFT_TOOLBAR, 0); | |
565 | |
566 if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f)) | |
567 mswindows_output_toolbar (f, RIGHT_TOOLBAR); | |
568 else if (f->right_toolbar_was_visible) | |
569 mswindows_clear_toolbar (f, RIGHT_TOOLBAR, 0); | |
570 } | |
571 | |
572 static void | |
573 mswindows_free_frame_toolbars (struct frame *f) | |
574 { | |
575 HWND twnd=NULL; | |
576 #define DELETE_TOOLBAR(pos) \ | |
577 mswindows_clear_toolbar(f, 0, pos); \ | |
578 if ((twnd=GetDlgItem(FRAME_MSWINDOWS_HANDLE(f), TOOLBAR_ID_BIAS + pos))) \ | |
579 DestroyWindow(twnd) | |
580 | |
581 DELETE_TOOLBAR(TOP_TOOLBAR); | |
582 DELETE_TOOLBAR(BOTTOM_TOOLBAR); | |
583 DELETE_TOOLBAR(LEFT_TOOLBAR); | |
584 DELETE_TOOLBAR(RIGHT_TOOLBAR); | |
585 #undef DELETE_TOOLBAR | |
586 } | |
587 | |
588 /* map toolbar hwnd to pos*/ | |
589 int mswindows_find_toolbar_pos(struct frame* f, HWND ctrl) | |
590 { | |
591 int id = GetDlgCtrlID(ctrl); | |
592 return id ? id - TOOLBAR_ID_BIAS : -1; | |
593 } | |
594 | |
595 Lisp_Object | |
596 mswindows_get_toolbar_button_text ( struct frame* f, int command_id ) | |
597 { | |
598 Lisp_Object button = Fgethash (make_int (command_id), | |
599 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f), Qnil); | |
600 | |
601 if (!NILP (button)) | |
602 { | |
603 struct toolbar_button *tb = XTOOLBAR_BUTTON (button); | |
604 return tb->help_string; | |
605 } | |
606 return Qnil; | |
607 } | |
608 | |
609 /* | |
610 * Return value is Qt if we have dispatched the command, | |
611 * or Qnil if id has not been mapped to a callback. | |
612 * Window procedure may try other targets to route the | |
613 * command if we return nil | |
614 */ | |
615 Lisp_Object | |
616 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id) | |
617 { | |
618 /* Try to map the command id through the proper hash table */ | |
619 Lisp_Object button, data, fn, arg, frame; | |
620 | |
621 button = Fgethash (make_int (id), | |
622 FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f), Qnil); | |
623 | |
624 if (NILP (button)) | |
625 return Qnil; | |
626 | |
627 data = XTOOLBAR_BUTTON (button)->callback; | |
628 | |
629 /* #### ? */ | |
630 if (UNBOUNDP (data)) | |
631 return Qnil; | |
632 | |
633 /* Ok, this is our one. Enqueue it. */ | |
634 get_gui_callback (data, &fn, &arg); | |
635 XSETFRAME (frame, f); | |
636 mswindows_enqueue_misc_user_event (frame, fn, arg); | |
637 | |
638 return Qt; | |
639 } | |
640 | |
641 /************************************************************************/ | |
642 /* initialization */ | |
643 /************************************************************************/ | |
644 | |
645 void | |
646 console_type_create_toolbar_mswindows (void) | |
647 { | |
648 CONSOLE_HAS_METHOD (mswindows, output_frame_toolbars); | |
649 CONSOLE_HAS_METHOD (mswindows, initialize_frame_toolbars); | |
650 CONSOLE_HAS_METHOD (mswindows, free_frame_toolbars); | |
651 CONSOLE_HAS_METHOD (mswindows, redraw_exposed_toolbars); | |
652 CONSOLE_HAS_METHOD (mswindows, redraw_frame_toolbars); | |
653 } | |
654 |