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