3 * FvwmGtk - gtk menus and dialogs for fvwm
5 * Copyright (c) 1999 Matthias Clasen <clasen@mathematik.uni-freiburg.de>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #ifdef NEED_GNOMESUPPORT_H
37 #include <gdk_imlib.h>
40 #include "libs/Module.h"
41 #include "libs/fvwmlib.h"
42 #include "fvwm/fvwm.h"
43 #include "libs/vpacket.h"
44 #include "libs/Parse.h"
45 #include "libs/Strings.h"
49 #include "windowlist.h"
52 int fvwm_fd
[2] = { -1, -1 };
53 static ModuleArgs
*module
;
54 char *image_path
= NULL
;
55 GHashTable
*widgets
= NULL
;
56 GtkWidget
*current
= NULL
;
57 GtkWidget
*attach_to_toplevel
= NULL
;
58 unsigned long context
= 0;
61 long current_desk
= 0;
62 GHashTable
*window_list_entries
= NULL
;
67 All widgets (menus and dialogs) are stored in one hash table, widgets.
68 They are built up piecemeal, the widget currently being built up is current.
69 For dialogs, current may also point to a subwidget of the dialog.
71 dialog contain diffent kinds of widgets:
73 * data widgets which return some value these all have a name and store
74 their value as data on the top-level dialog under their name
76 * action widgets like buttons. These have a list of commands which are
77 sent to fvwm or executed by FvwmGtk itself (eg close).
78 The commands are stored as data on the action widget under the name
79 "values", as a NULL-terminated char*-array.
81 A command can contain references to other widgets values in the form
82 $(name). These references are resolved recursively, ie the values can
83 again contain references.
85 The resolution of the references is done by splitting the string into a
86 list of passive strings and variable references and splicing in sublists
87 for the variable references until only passive strings remain.
91 void destroy(int argc
, char **argv
)
95 g_return_if_fail(argc
>= 1);
97 w
= g_hash_table_lookup(widgets
, argv
[0]);
100 if (gtk_widget_get_toplevel(current
) == w
)
105 g_hash_table_remove(widgets
, argv
[0]);
106 gtk_object_unref(GTK_OBJECT(w
));
107 gtk_widget_destroy(w
);
112 void separator(int argc
, char **argv
)
114 if (GTK_IS_MENU(current
))
116 menu_separator(argc
, argv
);
120 dialog_separator(argc
, argv
);
125 void item(int argc
, char **argv
)
127 if (GTK_IS_MENU(current
))
129 menu_item(argc
, argv
);
133 dialog_option_menu_item(argc
, argv
);
138 void parse_rc_file(int argc
, char **argv
)
140 g_return_if_fail(argc
>= 1);
142 gtk_rc_parse(argv
[0]);
146 void icon_size(int argc
, char **argv
)
155 icon_w
= atoi(argv
[0]);
156 icon_h
= atoi(argv
[1]);
194 void (*handler
[])(int, char**) = {
201 dialog_end_something
,
202 dialog_end_something
,
204 dialog_end_option_menu
,
205 dialog_end_radiogroup
,
213 dialog_start_option_menu
,
215 dialog_start_radiogroup
,
227 void parse_arguments(char **line
, int *argc
, char ***argv
)
232 for (i
= 0; i
< 100 ; i
++)
234 *line
= GetNextSimpleOption(*line
, &tmp
[i
]);
239 *argv
= (char **) safemalloc(i
* sizeof(char *));
240 for (i
= 0; i
< *argc
; i
++)
247 void widget_not_found(char *name
)
249 GtkWidget
*dialog
, *box
, *item
;
252 SendText(fvwm_fd
, "Beep", 0);
253 dialog
= gtk_window_new(GTK_WINDOW_DIALOG
);
254 gtk_window_set_title(GTK_WINDOW(dialog
), "Error");
255 gtk_window_set_wmclass(GTK_WINDOW(dialog
), "Error", "FvwmGtk");
257 box
= gtk_vbox_new(FALSE
, 10);
258 gtk_container_add(GTK_CONTAINER(dialog
), box
);
259 gtk_container_border_width(GTK_CONTAINER(dialog
), 30);
260 g_snprintf(buf
, sizeof(buf
), "No such menu or dialog: %s", name
);
261 item
= gtk_label_new(buf
);
262 gtk_box_pack_start(GTK_BOX(box
), item
, FALSE
, FALSE
, 5);
263 item
= gtk_button_new_with_label("OK");
264 gtk_box_pack_start(GTK_BOX(box
), item
, FALSE
, FALSE
, 5);
265 gtk_signal_connect_object(
266 GTK_OBJECT(item
), "clicked",
267 GTK_SIGNAL_FUNC(gtk_widget_destroy
), GTK_OBJECT(dialog
));
268 gtk_widget_show_all(box
);
269 gtk_widget_show(dialog
);
273 void parse_config_line(char *buf
)
280 if (buf
[strlen(buf
)-1] == '\n')
282 buf
[strlen(buf
)-1] = '\0';
286 buf
, CatString3("*",module
->name
,0),
287 module
->namelen
+1) == 0)
289 p
= buf
+ module
->namelen
+1;
290 if ((e
= FindToken(p
, table
, char*)))
293 parse_arguments(&p
, &argc
, &argv
);
294 handler
[e
- (char**)table
](argc
, argv
);
298 fprintf(stderr
, "%s: unknown command: %s\n",
302 else if (strncasecmp(buf
, "ImagePath", 9) == 0)
308 image_path
= stripcpy(buf
+ 9);
313 void parse_options(void)
317 /* only my config lines needed */
318 InitGetConfigLine(fvwm_fd
,CatString3("*",module
->name
,0));
319 while (GetConfigLine(fvwm_fd
, &buf
), buf
!= NULL
)
321 parse_config_line(buf
);
326 void process_message(
327 unsigned long type
, unsigned long timestamp
, unsigned long *body
)
331 window_list_options
*opts
;
338 SendUnlockNotification(fvwm_fd
);
339 context
= body
[0]; /* this is fw */
340 sscanf((char*)(&body
[3]), "%127s %d", name
, &button
);
341 widget
= g_hash_table_lookup(widgets
, name
);
344 widget_not_found(name
);
346 else if (GTK_IS_MENU(widget
))
348 opts
= (window_list_options
*)gtk_object_get_data(
349 GTK_OBJECT(widget
), "window_list");
359 GTK_OBJECT(current
), "window_list",
361 construct_window_list();
365 GTK_MENU(widget
), NULL
, NULL
, NULL
, NULL
,
368 else if (GTK_IS_WINDOW(widget
))
370 gtk_widget_show(GTK_WIDGET(widget
));
374 parse_config_line((char *)(&body
[3]));
377 current_desk
= (long)body
[0];
380 case M_CONFIGURE_WINDOW
:
382 struct ConfigWinPacket
*cfg
= (void *)body
;
383 window_list_entry
*wle
=
384 lookup_window_list_entry(body
[0]);
386 wle
->desk
= cfg
->desk
;
388 wle
->iconified
= IS_ICONIFIED(cfg
);
389 wle
->sticky
= (IS_STICKY_ACROSS_PAGES(cfg
) ||
390 IS_STICKY_ACROSS_DESKS(cfg
));
391 wle
->skip
= DO_SKIP_WINDOW_LIST(cfg
);
392 wle
->x
= cfg
->frame_x
;
393 wle
->y
= cfg
->frame_y
;
394 wle
->width
= cfg
->frame_width
;
395 wle
->height
= cfg
->frame_height
;
398 case M_DESTROY_WINDOW
:
399 g_hash_table_remove(window_list_entries
, &(body
[0]));
403 window_list_entry
*wle
=
404 lookup_window_list_entry(body
[0]);
409 wle
->name
= safestrdup((char *)(&body
[3]));
412 case MX_VISIBLE_ICON_NAME
:
414 window_list_entry
*wle
=
415 lookup_window_list_entry(body
[0]);
418 free(wle
->icon_name
);
420 wle
->icon_name
= safestrdup((char*)(&body
[3]));
426 MiniIconPacket
*mip
= (MiniIconPacket
*)body
;
427 window_list_entry
*wle
=
428 lookup_window_list_entry(mip
->w
);
432 free(wle
->mini_icon
);
434 wle
->mini_icon
= mip
->name
[0] != '\0' ?
435 safestrdup(mip
->name
) : NULL
;
442 void read_fvwm_pipe(gpointer data
, int source
, GdkInputCondition cond
)
444 FvwmPacket
* packet
= ReadFvwmPacket(source
);
451 process_message(packet
->type
, packet
->timestamp
, packet
->body
);
455 int main(int argc
, char **argv
)
457 module
= ParseModuleArgs(argc
,argv
,1);
461 stderr
, "FvwmGtk version %s should only be executed by"
462 " fvwm!\n", VERSION
);
466 fvwm_fd
[0] = module
->to_fvwm
;
467 fvwm_fd
[1] = module
->from_fvwm
;
470 gdk_init(&argc
, &argv
);
472 gtk_widget_push_visual(gdk_imlib_get_visual());
473 gtk_widget_push_colormap(gdk_imlib_get_colormap());
476 #ifdef NEED_GNOMESUPPORT_H
477 gnome_init("FvwmGtk", VERSION
, argc
, argv
);
478 gnome_client_disconnect(gnome_master_client());
480 gtk_init(&argc
, &argv
);
483 widgets
= g_hash_table_new(g_str_hash
, g_str_equal
);
485 attach_to_toplevel
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
486 gtk_widget_realize(attach_to_toplevel
);
488 window_list_entries
= g_hash_table_new(g_int_hash
, g_int_equal
);
492 /* normal messages */
504 /* extended messages */
507 MX_VISIBLE_ICON_NAME
);
509 SendText(fvwm_fd
, "Send_WindowList", 0);
512 fvwm_fd
[1], GDK_INPUT_READ
| GDK_INPUT_EXCEPTION
,
513 read_fvwm_pipe
, NULL
, NULL
, NULL
);
515 /* tell fvwm we're running */
516 SendFinishedStartupNotification(fvwm_fd
);
518 /* tell fvwm we want to be lock on send for M_STRING Messages */
519 SetSyncMask(fvwm_fd
, M_STRING
);