4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU Library General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
* Jochen Baier, 2004, 2005, 2006 (email@Jochen-Baier.de)
31
* steal-xwin.c (acano@systec.com)
32
* xswallow (Caolan McNamara ?)
33
* kdocker (Girish Ramakrishnan)
34
* libwnck (Havoc Pennington <hp@redhat.com>)
35
* eggtrayicon (Anders Carlsson <andersca@gnu.org>)
36
* dsimple.c ("The Open Group")
37
* xfwm4 (Olivier Fourdan <fourdan@xfce.org>)
38
* .....lot more, THANX !!!
48
#include <X11/cursorfont.h>
52
GtkWidget *hint_label;
53
GtkWidget *cancel_label;
55
Window get_kwin_window (Window target)
60
Window root_return=None;
65
XClassHint class_hints;
67
Window kwin_window=None;
69
our= one_under_root (GDK_DISPLAY(), target);
71
gdk_error_trap_push();
72
if (!XQueryTree (GDK_DISPLAY (), our, &root_return, &parent, &our_kids, (unsigned int *) &our_nkids))
77
for (i=0; i < our_nkids; i++) {
79
if (debug) printf ("our kid %d: %d\n", i, (gint) our_kids[i]);
81
gdk_error_trap_push();
82
result=XGetClassHint(GDK_DISPLAY(), our_kids[i], &class_hints);
83
err=gdk_error_trap_pop();
85
if (err || result==0 ) {
86
printf ("ERROR get class hints\n");
90
if (debug) printf ("our_kids: res_class: %s res_name %s \n",
91
class_hints.res_class, class_hints.res_name);
93
if (!strcmp (class_hints.res_class, "Kwin")) {
95
kwin_window = our_kids[i];
96
XFree (class_hints.res_class);
97
XFree (class_hints.res_name);
102
XFree (class_hints.res_class);
103
XFree (class_hints.res_name);
110
if (our_kids) XFree ((char *)our_kids);
115
void free_button_list (GList *buttons)
123
button *value= (button*) l->data;
128
g_list_free (buttons);
131
GList *get_button_list (Window kwin_window)
134
Window *kwin_kids, root_return, parent;
140
gdk_error_trap_push();
141
if (!XQueryTree (GDK_DISPLAY (), kwin_window, &root_return, &parent, &kwin_kids, (unsigned int *) &kwin_nkids))
143
gdk_error_trap_pop();
146
for (i=0; i < kwin_nkids; i++) {
147
if (debug) printf ("kwin_kid[%d]: %d ", i, (gint) kwin_kids[i]);
151
gdk_error_trap_push();
152
XGetWindowAttributes (GDK_DISPLAY (), kwin_kids[i], &w);
153
if (gdk_error_trap_pop())
156
if (debug) printf ("x: %d; y: %d width: %d \n", w.x, w.y, w.width);
158
button *new =g_new (button, 1);
160
new->window_xlib = kwin_kids[i];
161
new->window_gdk =gdk_window_foreign_new (new->window_xlib);
165
new->height=w.height;
167
buttons= g_list_append (buttons, (gpointer) new);
170
if (kwin_kids) XFree ((char *)kwin_kids);
176
button *value= (button*) l->data;
178
if (debug) printf ("button window: %d\n", (gint) value->window_xlib);
188
gint button_num_by_x (GList *buttons, gint x, gint y)
191
gboolean valid=FALSE;
199
button *value= (button*) l->data;
201
// printf ("start_x: %d, end_x: %d, start_y: %d, end_y: %d\n",
202
// value->start_x, value->end_x,value->start_y,value->end_y);
204
if (x >= value->start_x && x <= (value->start_x + value->width -1) &&
205
y >= value->start_y && y <= (value->start_y + value->height -1)) {
206
if (debug) printf ("valid\n");
223
gboolean notabutton_func (gpointer user_data)
226
gtk_label_set_text (GTK_LABEL(hint_label), " >not a button<");
228
gtk_label_set_text (GTK_LABEL(hint_label), "Waiting for click...");
233
gint get_button_number (Window target, GList *buttons)
238
gboolean button_pressed=FALSE;
239
gboolean canceled =FALSE;
242
Cursor cursor = XCreateFontCursor(GDK_DISPLAY(), XC_crosshair);
244
status = XGrabPointer(GDK_DISPLAY(), target, False, ButtonReleaseMask |
245
ButtonPressMask, GrabModeSync, GrabModeAsync, target, cursor, CurrentTime);
247
if (status != GrabSuccess) {
251
while (!button_pressed && !canceled) {
253
XAllowEvents(GDK_DISPLAY(), SyncPointer, CurrentTime);
254
XWindowEvent(GDK_DISPLAY(), target,
255
ButtonPressMask | ButtonReleaseMask, &event);
257
switch (event.type) {
261
num=button_num_by_x (buttons, event.xbutton.x, event.xbutton.y);
262
if (debug) printf ("num: %d\n", num);
267
if (debug) printf ("canceld=TRUE\n");
276
/*if (debug) printf ("button press\n");
277
num=button_num_by_x (buttons, event.xbutton.x, event.xbutton.y);
278
if (debug) printf ("num: %d\n", num);
281
g_timeout_add (1, notabutton_func, NULL);*/
287
// while (gtk_events_pending ())
288
// gtk_main_iteration ();
292
XUngrabPointer(GDK_DISPLAY(), CurrentTime);
293
XFreeCursor (GDK_DISPLAY(), cursor);
295
gtk_label_set_markup (GTK_LABEL(cancel_label), "<span size=\"small\"> </span>");
298
gtk_label_set_text (GTK_LABEL(hint_label), "Thanks. Configuration completed.");
303
gtk_label_set_text (GTK_LABEL(hint_label), "Configuration canceled.");
310
gboolean write_string_to_file (char *str, char* file)
313
mode_t mode = S_IRUSR | S_IWUSR;
321
fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, mode);
324
perror("error with open()");
328
if(write(fd, str, size) != size) {
329
perror("error with write()");
340
alltray_user_dir(void)
343
gchar *user_dir=NULL;
344
user_dir=g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S, ".alltray", NULL);
350
create_configure_window (void)
352
GtkWidget *configure_window;
355
GtkWidget *hseparator1;
358
configure_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
359
gtk_window_set_title (GTK_WINDOW (configure_window), "AllTray - Configuration");
360
gtk_window_set_position (GTK_WINDOW (configure_window), GTK_WIN_POS_CENTER);
361
gtk_window_set_resizable (GTK_WINDOW (configure_window), FALSE);
362
//gtk_window_set_skip_taskbar_hint (GTK_WINDOW (configure_window), TRUE);
363
gtk_window_set_skip_pager_hint (GTK_WINDOW (configure_window), TRUE);
365
vbox1 = gtk_vbox_new (FALSE, 0);
366
gtk_widget_show (vbox1);
367
gtk_container_add (GTK_CONTAINER (configure_window), vbox1);
368
gtk_container_set_border_width (GTK_CONTAINER (vbox1), 20);
370
label3 = gtk_label_new ( "<span size=\"large\">Welcome to AllTray Configuration utility </span>\n\nAllTray need to know which of the Window - Frame buttons\nis the \"Close\" button (the one with the \"X\").\n\t\n<span foreground=\"red\">To configure AllTay please click on the close button\n in the top Frame of this window. </span>\n\nYou need to do this only after each theme change !\nYou can start this wizard manualy with: \"alltray --configure\"\n");
371
gtk_widget_show (label3);
372
gtk_box_pack_start (GTK_BOX (vbox1), label3, FALSE, FALSE, 0);
373
gtk_label_set_use_markup (GTK_LABEL (label3), TRUE);
374
gtk_label_set_justify (GTK_LABEL (label3), GTK_JUSTIFY_CENTER);
376
hseparator1 = gtk_hseparator_new ();
377
gtk_widget_show (hseparator1);
378
gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, TRUE, TRUE, 7);
380
vbox2 = gtk_vbox_new (FALSE, 0);
381
gtk_widget_show (vbox2);
382
gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
384
hint_label = gtk_label_new ("Waiting for click...");
385
gtk_widget_show (hint_label);
386
gtk_box_pack_start (GTK_BOX (vbox2), hint_label, FALSE, FALSE, 0);
388
cancel_label = gtk_label_new ("<span size=\"small\"> (To cancel click somewhere else) </span>");
389
gtk_widget_show (cancel_label);
390
gtk_box_pack_start (GTK_BOX (vbox2), cancel_label, FALSE, FALSE, 0);
391
gtk_label_set_use_markup (GTK_LABEL (cancel_label), TRUE);
393
return configure_window;
396
void save_close_button_position (gboolean pos)
399
gchar *user_dir=NULL;
400
gchar *filename=NULL;
403
user_dir=alltray_user_dir();
404
if (debug) printf ("user_dir: %s\n", user_dir);
406
file = fopen(user_dir, "r");
409
mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
413
filename = g_build_filename(user_dir, "prefs", NULL);
415
if (debug) printf ("filnename: %s\n", filename);
418
write_string_to_file ("left", filename);
420
write_string_to_file ("right", filename);
427
gboolean kde_get_close_button_positon (void)
430
gchar *user_dir=NULL;
433
gboolean return_value=NO_SUCCESS;
435
user_dir=alltray_user_dir();
436
if (debug) printf ("user_dir: %s\n", user_dir);
438
filename = g_build_filename(user_dir, "prefs", NULL);
442
if (!g_file_get_contents (filename, &content, NULL, NULL))
447
if (debug) printf ("prefs content: %s\n", content);
449
if (!strcmp (content, "left"))
452
if (!strcmp (content, "right"))
461
gboolean kde_show_configure_dialog (win_struct *win)
465
GdkWindow *target_gdk;
471
window=create_configure_window();
472
gtk_window_set_keep_above (GTK_WINDOW (window), TRUE); //kwin bug
473
gtk_widget_realize (window);
474
gtk_widget_show (window);
476
//while (gtk_events_pending ())
477
// gtk_main_iteration ();
481
target_gdk = window->window;
482
target=GDK_WINDOW_XID(target_gdk);
484
//printf ("target id is: %d\n", target);
486
kwin_window= get_kwin_window (target);
487
//printf ("kwin_window: %d\n", kwin_window);
489
buttons=get_button_list (kwin_window);
490
num= get_button_number (kwin_window, buttons);
492
if (debug) printf ("return num is: %d\n", num);
494
free_button_list (buttons);
496
gtk_widget_destroy (window);
502
save_close_button_position (LEFT);
503
win->kde_close_button_pos=LEFT;
505
save_close_button_position (RIGHT);
506
win->kde_close_button_pos=RIGHT;
513
button kde_get_close_button (Window target, gboolean pos)
517
Window kwin_window= get_kwin_window (target);;
519
buttons=get_button_list (kwin_window);
522
buttons=g_list_last (buttons);
524
buttons=g_list_first (buttons);
526
button value= *((button*) buttons->data);
528
free_button_list (buttons);