wmcliphist: Add version 2.0 to repository.
[dockapps.git] / wmcliphist / wmcliphist.c
blobf038251025e89351d3c28b15c78bb8054908d58b
1 /*
2 * (c) 2001 Michal Krause <michal@krause.cz>
3 */
5 #include <wmcliphist.h>
7 #include <icon/ico_60x60_mask.xbm>
8 #include <icon/ico_60x60_black.xpm>
9 #include <icon/ico_60x60_white.xpm>
10 #include <icon/ico_60x60_gray.xpm>
12 #include <icon/ico_40x40_mask.xbm>
13 #include <icon/ico_40x40_black.xpm>
14 #include <icon/ico_40x40_white.xpm>
15 #include <icon/ico_40x40_gray.xpm>
17 #include <icon/ico_30x30_mask.xbm>
18 #include <icon/ico_30x30_black.xpm>
19 #include <icon/ico_30x30_white.xpm>
20 #include <icon/ico_30x30_gray.xpm>
22 #include <icon/ico_16x16_mask.xbm>
23 #include <icon/ico_16x16.xpm>
26 * print some help
28 void
29 print_help()
31 begin_func("print_help");
33 fprintf(stderr, "Usage: wmcliphist [options]\n\n"
34 "wmcliphist is small dock applet for Window Maker which "
35 "keeps X clipboard history\n\n");
36 fprintf(stderr, "-h show this help\n"
37 "-n <num> set number of items to keep (default 10)\n"
38 "-c color set color for locked items (default is red)\n"
39 "-s <size> choose wmcliphist icon size:\n"
40 " 0 = no icon\n"
41 " 16 = tiny 16x16 px icon\n"
42 " 30 = icon suitable for 32px dock/slit\n"
43 " 40 = icon suitable for 48px dock/slit\n"
44 " 60 = icon suitable for 64px dock/slit (default)\n");
45 fprintf(stderr, "-i <num> choose wmcliphist icon antialiasing:\n"
46 " 0 = for mid tones background (default)\n"
47 " 1 = for dark background\n"
48 " 2 = for light background\n");
49 fprintf(stderr, "-d dumps clipboard history to stdout"
50 " in pseudo XML format (no escaping etc.)\n\n");
52 exit(1);
53 return_void();
56 static void
57 wmcliphist_exit(gint code)
59 begin_func("wmcliphist_exit");
60 gtk_exit(code);
61 return_void();
66 * main func
68 int
69 main(int argc, char **argv)
71 gint i = 1, res;
72 gchar *arg;
73 GList *list_node;
74 int icon_number = 0;
75 int icon_size = 60;
76 gchar **icon_data;
77 gboolean dump_only = FALSE;
79 #ifdef FNCALL_DEBUG
80 debug_init_nothreads();
81 #endif
82 begin_func("main");
84 /* load configuration */
85 if ((res = rcconfig_get(rcconfig_get_name("rc"))) != 0) {
86 fprintf(stderr, "~/.wmcliphistrc parse error (%d)\n", res);
87 return_val(1);
90 /* parse command line */
91 while ((arg = argv[i])) {
92 if (*arg == '-') {
93 if (*(arg + 1) == 'h')
94 print_help();
95 else if (*(arg + 1) == 'n') {
96 i++;
97 if (!argv[i]) {
98 fprintf(stderr, "Missing value of -n\n");
99 print_help();
101 num_items_to_keep = atol(argv[i]);
102 } else if (*(arg + 1) == 'c') {
103 i++;
104 if (!argv[i]) {
105 fprintf(stderr, "Missing value of -c\n");
106 print_help();
108 memset(locked_color_str, 0, 32);
109 strncpy(locked_color_str, argv[i], 31);
110 } else if (*(arg + 1) == 'i') {
111 i++;
112 if (!argv[i]) {
113 fprintf(stderr, "Missing value of -i\n");
114 print_help();
116 icon_number = atoi(argv[i]);
117 if (icon_number < 0 || icon_number > 2) {
118 fprintf(stderr, "Invalid value of -i\n");
119 print_help();
121 } else if (*(arg + 1) == 's') {
122 i++;
123 if (!argv[i]) {
124 fprintf(stderr, "Missing value of -s\n");
125 print_help();
127 icon_size = atoi(argv[i]);
128 if (icon_size != 60 && icon_size != 40
129 && icon_size != 30
130 && icon_size != 16
131 && icon_size != 0) {
132 fprintf(stderr, "Invalid value of -s\n");
133 print_help();
135 if (icon_size == 0) {
136 icon_size = 1;
138 } else if (*(arg + 1) == 'd') {
139 dump_only = TRUE;
140 } else {
141 fprintf(stderr, "Invalid option -%c\n", *(arg + 1));
142 print_help();
144 } else {
145 fprintf(stderr, "Invalid option %s\n", arg);
146 print_help();
148 i++;
151 signal(SIGCHLD, SIG_IGN);
153 /* initialize Gtk */
154 gtk_set_locale();
155 gtk_init(&argc, &argv);
158 /* create main window */
159 main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
160 gtk_widget_realize(main_window);
163 /* creat dock icon */
164 dock_app = foo_create_main_icon_window(main_window,
165 icon_size, argc, argv);
167 if (icon_size) {
168 /* create icon_mask */
169 if (icon_size == 60) {
170 /* 60x60 icon */
171 icon_mask = gdk_bitmap_create_from_data(main_window->window,
172 (gchar *) ico_60x60_mask_bits,
173 ico_60x60_mask_width,
174 ico_60x60_mask_height);
175 /* create icon */
176 if (icon_number == 0) {
177 icon_data = ico_60x60_gray_xpm;
178 } else if (icon_number == 1) {
179 icon_data = ico_60x60_black_xpm;
180 } else {
181 icon_data = ico_60x60_white_xpm;
183 } else if (icon_size == 40) {
184 /* 40x40 icon */
185 icon_mask = gdk_bitmap_create_from_data(main_window->window,
186 (gchar *) ico_40x40_mask_bits,
187 ico_40x40_mask_width,
188 ico_40x40_mask_height);
189 /* create icon */
190 if (icon_number == 0) {
191 icon_data = ico_40x40_gray_xpm;
192 } else if (icon_number == 1) {
193 icon_data = ico_40x40_black_xpm;
194 } else {
195 icon_data = ico_40x40_white_xpm;
197 } else if (icon_size == 30) {
198 /* 30x30 icon */
199 icon_mask = gdk_bitmap_create_from_data(main_window->window,
200 (gchar *) ico_30x30_mask_bits,
201 ico_30x30_mask_width,
202 ico_30x30_mask_height);
203 /* create icon */
204 if (icon_number == 0) {
205 icon_data = ico_30x30_gray_xpm;
206 } else if (icon_number == 1) {
207 icon_data = ico_30x30_black_xpm;
208 } else {
209 icon_data = ico_30x30_white_xpm;
211 } else {
212 /* 16x16 icon */
213 icon_mask = gdk_bitmap_create_from_data(main_window->window,
214 (gchar *) ico_16x16_mask_bits,
215 ico_16x16_mask_width,
216 ico_16x16_mask_height);
217 /* create icon */
218 icon_data = ico_16x16_xpm;
221 icon = gdk_pixmap_create_from_xpm_d(main_window->window,
222 NULL, NULL, icon_data);
223 pixmap = gtk_pixmap_new(icon, icon_mask);
224 gtk_widget_show(pixmap);
225 gtk_container_add(GTK_CONTAINER(dock_app), pixmap);
229 /* create clipboard history menu */
230 menu_hist = gtk_menu_new();
231 gtk_menu_set_title(GTK_MENU(menu_hist), "Clipboard history");
232 menu_title = gtk_tearoff_menu_item_new();
233 gtk_menu_append(GTK_MENU(menu_hist), menu_title);
234 gtk_widget_show(menu_title);
235 gtk_widget_show(menu_hist);
238 /* create application menu */
239 menu_app = gtk_menu_new();
241 menu_app_clip_lock = gtk_check_menu_item_new_with_label("Clipboard lock");
242 gtk_menu_append(GTK_MENU(menu_app), menu_app_clip_lock);
244 menu_app_clip_ignore = gtk_check_menu_item_new_with_label("Clipboard ignore");
245 gtk_menu_append(GTK_MENU(menu_app), menu_app_clip_ignore);
247 menu_app_save = gtk_menu_item_new_with_label("Save history");
248 gtk_menu_append(GTK_MENU(menu_app), menu_app_save);
249 gtk_signal_connect(GTK_OBJECT(menu_app_save),
250 "activate",
251 GTK_SIGNAL_FUNC(menu_app_item_click),
252 GINT_TO_POINTER(0));
254 menu_app_exit = gtk_menu_item_new_with_label("Exit");
255 gtk_menu_append(GTK_MENU(menu_app), menu_app_exit);
256 gtk_signal_connect(GTK_OBJECT(menu_app_exit),
257 "activate",
258 GTK_SIGNAL_FUNC(menu_app_item_click),
259 GINT_TO_POINTER(1));
261 gtk_widget_show_all(menu_app);
264 list_node = action_list;
265 while (list_node) {
266 ACTION *action = list_node->data;
268 if (action->action == ACT_SUBMENU &&
269 strcmp(action->command, "-") != 0) {
270 action->menu_item = gtk_menu_item_new_with_label(
271 action->command);
272 gtk_menu_append(GTK_MENU(menu_hist),
273 action->menu_item);
274 action->submenu = gtk_menu_new();
275 gtk_menu_item_set_submenu(
276 GTK_MENU_ITEM(action->menu_item),
277 action->submenu);
278 menu_title = gtk_tearoff_menu_item_new();
279 gtk_menu_append(GTK_MENU(action->submenu), menu_title);
280 gtk_widget_show(menu_title);
281 gtk_widget_show(action->menu_item);
282 gtk_widget_show(action->submenu);
283 submenu_count++;
285 if (action->action == ACT_SUBMENU &&
286 strcmp(action->command, "-") == 0) {
287 printf("'%s'\n", action->command);
288 action->submenu = menu_hist;
290 list_node = list_node->next;
292 if (submenu_count) {
293 GtkWidget *separator;
295 separator = gtk_menu_item_new();
296 gtk_widget_show(separator);
297 gtk_menu_insert(GTK_MENU(menu_hist), separator, 1);
300 /* prepare colors and styles */
301 if (gdk_color_parse(locked_color_str, &locked_color) == 0) {
302 char msg_str[128];
304 sprintf(msg_str, "Invalid color string: '%s'.\n"
305 "Falling back to default (red).",
306 locked_color_str);
307 show_message(msg_str, "Warning", "OK", NULL, NULL);
308 strcpy(locked_color_str, DEF_LOCKED_COLOR);
309 gdk_color_parse(locked_color_str, &locked_color);
311 style_normal = gtk_style_copy(gtk_widget_get_style(menu_hist));
312 style_locked = gtk_style_copy(gtk_widget_get_style(menu_hist));
313 style_locked->fg[GTK_STATE_NORMAL] = locked_color;
314 style_locked->fg[GTK_STATE_PRELIGHT] = locked_color;
317 /* load previously saved history */
318 if (history_load(dump_only) != 0) {
319 if (errno == E_TOO_MUCH) {
320 if (show_message("Number of items to keep (-n switch or "
321 "keep directive in ~/.wmcliphistrc)\n"
322 "is lower than actual number of items "
323 "in history file.\nSome items from "
324 "history will be lost. May I continue?",
325 "Warning", "Yes", "No", NULL) == 1) {
326 rcconfig_free();
327 gtk_exit(1);
329 } else if (errno != E_OPEN) {
330 rcconfig_free();
331 fprintf(stderr, "cannot load history (%d)\n", errno);
332 gtk_exit(1);
335 if (dump_only) {
336 rcconfig_free();
337 gtk_exit(1);
341 if (icon_size) {
342 /* connect signal for menu popup */
343 gtk_signal_connect(GTK_OBJECT(dock_app),
344 "event",
345 GTK_SIGNAL_FUNC(button_press),
346 GTK_OBJECT(menu_hist));
349 /* show icon */
350 gtk_widget_show(dock_app);
351 gtk_widget_show(main_window);
353 /* Set WMHints - after gtk_widget_show() due to changes in GTK+ 2.4 */
354 foo_set_wmhints(main_window, dock_app, argc, argv);
356 gdk_window_shape_combine_mask(main_window->window, icon_mask, 0, 0);
357 gdk_window_shape_combine_mask(dock_app->window, icon_mask, 0, 0);
361 /* run clipboard monitor */
362 gtk_signal_connect(GTK_OBJECT(main_window),
363 "selection_received",
364 GTK_SIGNAL_FUNC(my_get_xselection),
365 NULL);
366 gtk_timeout_add(250, time_conv_select, NULL);
369 /* run autosave timer */
370 if (autosave_period > 0)
371 gtk_timeout_add(autosave_period * 1000, history_autosave, NULL);
374 /* setup everything for supplying selection to other apps */
375 gtk_selection_add_target(dock_app,
376 GDK_SELECTION_PRIMARY,
377 GDK_SELECTION_TYPE_STRING,
380 gtk_signal_connect(GTK_OBJECT(dock_app),
381 "selection_get",
382 GTK_SIGNAL_FUNC(selection_handle),
383 NULL);
385 gtk_signal_connect(GTK_OBJECT(dock_app),
386 "destroy",
387 GTK_SIGNAL_FUNC(wmcliphist_exit),
388 NULL);
391 hotkeys_init();
393 gtk_main();
395 return_val(0);