2 * (c) 2001 Michal Krause <michal@krause.cz>
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>
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"
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");
57 wmcliphist_exit(gint code
)
59 begin_func("wmcliphist_exit");
69 main(int argc
, char **argv
)
77 gboolean dump_only
= FALSE
;
80 debug_init_nothreads();
84 /* load configuration */
85 if ((res
= rcconfig_get(rcconfig_get_name("rc"))) != 0) {
86 fprintf(stderr
, "~/.wmcliphistrc parse error (%d)\n", res
);
90 /* parse command line */
91 while ((arg
= argv
[i
])) {
93 if (*(arg
+ 1) == 'h')
95 else if (*(arg
+ 1) == 'n') {
98 fprintf(stderr
, "Missing value of -n\n");
101 num_items_to_keep
= atol(argv
[i
]);
102 } else if (*(arg
+ 1) == 'c') {
105 fprintf(stderr
, "Missing value of -c\n");
108 memset(locked_color_str
, 0, 32);
109 strncpy(locked_color_str
, argv
[i
], 31);
110 } else if (*(arg
+ 1) == 'i') {
113 fprintf(stderr
, "Missing value of -i\n");
116 icon_number
= atoi(argv
[i
]);
117 if (icon_number
< 0 || icon_number
> 2) {
118 fprintf(stderr
, "Invalid value of -i\n");
121 } else if (*(arg
+ 1) == 's') {
124 fprintf(stderr
, "Missing value of -s\n");
127 icon_size
= atoi(argv
[i
]);
128 if (icon_size
!= 60 && icon_size
!= 40
132 fprintf(stderr
, "Invalid value of -s\n");
135 if (icon_size
== 0) {
138 } else if (*(arg
+ 1) == 'd') {
141 fprintf(stderr
, "Invalid option -%c\n", *(arg
+ 1));
145 fprintf(stderr
, "Invalid option %s\n", arg
);
151 signal(SIGCHLD
, SIG_IGN
);
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
);
168 /* create icon_mask */
169 if (icon_size
== 60) {
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
);
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
;
181 icon_data
= ico_60x60_white_xpm
;
183 } else if (icon_size
== 40) {
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
);
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
;
195 icon_data
= ico_40x40_white_xpm
;
197 } else if (icon_size
== 30) {
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
);
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
;
209 icon_data
= ico_30x30_white_xpm
;
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
);
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
),
251 GTK_SIGNAL_FUNC(menu_app_item_click
),
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
),
258 GTK_SIGNAL_FUNC(menu_app_item_click
),
261 gtk_widget_show_all(menu_app
);
264 list_node
= action_list
;
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(
272 gtk_menu_append(GTK_MENU(menu_hist
),
274 action
->submenu
= gtk_menu_new();
275 gtk_menu_item_set_submenu(
276 GTK_MENU_ITEM(action
->menu_item
),
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
);
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
;
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) {
304 sprintf(msg_str
, "Invalid color string: '%s'.\n"
305 "Falling back to default (red).",
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) {
329 } else if (errno
!= E_OPEN
) {
331 fprintf(stderr
, "cannot load history (%d)\n", errno
);
342 /* connect signal for menu popup */
343 gtk_signal_connect(GTK_OBJECT(dock_app
),
345 GTK_SIGNAL_FUNC(button_press
),
346 GTK_OBJECT(menu_hist
));
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
),
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
),
382 GTK_SIGNAL_FUNC(selection_handle
),
385 gtk_signal_connect(GTK_OBJECT(dock_app
),
387 GTK_SIGNAL_FUNC(wmcliphist_exit
),