~ubuntu-branches/ubuntu/karmic/alltray/karmic

« back to all changes in this revision

Viewing changes to src/kde.c

  • Committer: Bazaar Package Importer
  • Author(s): Raphael Hertzog
  • Date: 2007-01-14 18:36:56 UTC
  • Revision ID: james.westby@ubuntu.com-20070114183656-tutd3t7x0kifep7a
Tags: upstream-0.69
ImportĀ upstreamĀ versionĀ 0.69

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * GPL Notice:
 
3
 *
 
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.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *
 
18
 *
 
19
 * Name:
 
20
 *
 
21
 *    alltray
 
22
 *
 
23
 *
 
24
 * Copyright:
 
25
 * 
 
26
 *    Jochen Baier, 2004, 2005, 2006 (email@Jochen-Baier.de)
 
27
 *
 
28
 *
 
29
 * Based on code from:
 
30
 *
 
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 !!!
 
39
 *    
 
40
*/
 
41
 
 
42
 
 
43
#include "config.h"
 
44
#include "common.h"
 
45
#include "parent.h"
 
46
#include "utils.h"
 
47
 
 
48
#include <X11/cursorfont.h>
 
49
#include <fcntl.h>
 
50
#include <sys/stat.h>
 
51
 
 
52
GtkWidget *hint_label;
 
53
GtkWidget *cancel_label;
 
54
 
 
55
Window get_kwin_window (Window target)
 
56
{
 
57
 
 
58
  Window our;
 
59
  Window parent=None;
 
60
  Window root_return=None;
 
61
  Window *our_kids;
 
62
  gint our_nkids;
 
63
  gint err;
 
64
  gint i;
 
65
  XClassHint class_hints;
 
66
  int result;
 
67
  Window kwin_window=None;
 
68
 
 
69
  our= one_under_root (GDK_DISPLAY(), target);
 
70
 
 
71
  gdk_error_trap_push();
 
72
  if (!XQueryTree (GDK_DISPLAY (), our, &root_return, &parent, &our_kids, (unsigned int *) &our_nkids))
 
73
     {exit (1); }
 
74
  gdk_error_trap_pop();
 
75
 
 
76
 
 
77
  for (i=0; i < our_nkids; i++)  {
 
78
 
 
79
    if (debug) printf ("our kid %d: %d\n", i, (gint) our_kids[i]);
 
80
    
 
81
    gdk_error_trap_push();
 
82
    result=XGetClassHint(GDK_DISPLAY(), our_kids[i], &class_hints);
 
83
    err=gdk_error_trap_pop();
 
84
    
 
85
    if (err || result==0 ) {
 
86
      printf ("ERROR get class hints\n"); 
 
87
      continue;
 
88
    } else {
 
89
    
 
90
      if (debug) printf ("our_kids: res_class: %s  res_name %s   \n",
 
91
      class_hints.res_class, class_hints.res_name);
 
92
      
 
93
      if (!strcmp (class_hints.res_class, "Kwin")) {
 
94
      
 
95
        kwin_window = our_kids[i];
 
96
        XFree (class_hints.res_class);
 
97
        XFree (class_hints.res_name);
 
98
        break;
 
99
      
 
100
      }
 
101
 
 
102
      XFree (class_hints.res_class);
 
103
      XFree (class_hints.res_name);
 
104
    
 
105
    }
 
106
 
 
107
 
 
108
  }
 
109
 
 
110
  if (our_kids) XFree ((char *)our_kids);
 
111
 
 
112
  return kwin_window;
 
113
}
 
114
 
 
115
void free_button_list (GList *buttons)
 
116
{
 
117
 
 
118
  GList *l;
 
119
 
 
120
   l=buttons;
 
121
  
 
122
  while (l != NULL) {
 
123
    button *value= (button*) l->data;
 
124
    g_free (value);
 
125
    l=l->next;
 
126
  }
 
127
 
 
128
  g_list_free (buttons);
 
129
}
 
130
 
 
131
GList *get_button_list (Window kwin_window)
 
132
{
 
133
 
 
134
  Window *kwin_kids, root_return, parent;
 
135
  gint kwin_nkids;
 
136
  GList *buttons=NULL;
 
137
  gint i;
 
138
  GList *l;
 
139
 
 
140
  gdk_error_trap_push();
 
141
   if (!XQueryTree (GDK_DISPLAY (), kwin_window, &root_return, &parent, &kwin_kids, (unsigned int *) &kwin_nkids))
 
142
     { exit (1); }
 
143
  gdk_error_trap_pop();
 
144
 
 
145
 
 
146
  for (i=0; i < kwin_nkids; i++) {
 
147
    if (debug) printf ("kwin_kid[%d]: %d        ", i, (gint) kwin_kids[i]);
 
148
  
 
149
    XWindowAttributes w;
 
150
  
 
151
    gdk_error_trap_push();
 
152
    XGetWindowAttributes (GDK_DISPLAY (), kwin_kids[i], &w);
 
153
    if (gdk_error_trap_pop())
 
154
      continue;
 
155
 
 
156
    if (debug) printf ("x: %d; y: %d width: %d \n", w.x, w.y, w.width);
 
157
  
 
158
    button *new =g_new (button, 1);
 
159
  
 
160
    new->window_xlib = kwin_kids[i];
 
161
    new->window_gdk =gdk_window_foreign_new (new->window_xlib);
 
162
    new->start_x = w.x;
 
163
    new->start_y = w.y;
 
164
    new->width=w.width;
 
165
    new->height=w.height;
 
166
  
 
167
    buttons= g_list_append (buttons, (gpointer) new);
 
168
  }
 
169
 
 
170
  if (kwin_kids) XFree ((char *)kwin_kids);
 
171
  
 
172
  l=buttons;
 
173
  
 
174
  while (l != NULL) {
 
175
  
 
176
    button *value= (button*) l->data;
 
177
    
 
178
    if (debug) printf ("button window: %d\n", (gint) value->window_xlib);
 
179
    
 
180
    l=l->next;
 
181
  
 
182
  }
 
183
 
 
184
  return buttons;
 
185
 
 
186
}
 
187
 
 
188
gint button_num_by_x (GList *buttons, gint x, gint y)
 
189
{
 
190
 
 
191
  gboolean valid=FALSE;
 
192
  gint num=1;
 
193
  GList *l;
 
194
 
 
195
  l=buttons;
 
196
  
 
197
  while (l != NULL) {
 
198
  
 
199
    button *value= (button*) l->data;
 
200
 
 
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);
 
203
 
 
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");
 
207
      valid=TRUE;
 
208
      break;
 
209
    }
 
210
    
 
211
    num++;
 
212
    l=l->next;
 
213
  
 
214
  }
 
215
  
 
216
  if (valid)
 
217
    return num;
 
218
  else
 
219
   return 0;
 
220
 
 
221
}
 
222
 
 
223
gboolean notabutton_func (gpointer user_data)
 
224
{
 
225
 
 
226
  gtk_label_set_text (GTK_LABEL(hint_label), " >not a button<");
 
227
  gtk_sleep (1000);
 
228
  gtk_label_set_text (GTK_LABEL(hint_label), "Waiting for click...");
 
229
 
 
230
  return FALSE;
 
231
}
 
232
 
 
233
gint get_button_number (Window target, GList *buttons)
 
234
{
 
235
  
 
236
  int status;
 
237
  XEvent event;
 
238
  gboolean button_pressed=FALSE;
 
239
  gboolean canceled =FALSE;
 
240
  gint num=0;
 
241
 
 
242
  Cursor cursor = XCreateFontCursor(GDK_DISPLAY(), XC_crosshair);
 
243
 
 
244
  status = XGrabPointer(GDK_DISPLAY(), target, False, ButtonReleaseMask |
 
245
    ButtonPressMask, GrabModeSync, GrabModeAsync, target, cursor, CurrentTime);
 
246
  
 
247
  if (status != GrabSuccess) {
 
248
    exit (1);
 
249
  }
 
250
 
 
251
  while (!button_pressed && !canceled) {
 
252
  
 
253
    XAllowEvents(GDK_DISPLAY(), SyncPointer, CurrentTime);
 
254
      XWindowEvent(GDK_DISPLAY(), target,
 
255
      ButtonPressMask | ButtonReleaseMask, &event);
 
256
    
 
257
    switch (event.type) {
 
258
    
 
259
      case ButtonRelease:
 
260
  
 
261
        num=button_num_by_x (buttons, event.xbutton.x, event.xbutton.y);
 
262
        if (debug) printf ("num: %d\n", num);
 
263
            
 
264
        if (num != 0)
 
265
          button_pressed=TRUE;
 
266
        else {
 
267
          if (debug) printf ("canceld=TRUE\n");
 
268
          canceled=TRUE;
 
269
        }
 
270
         
 
271
      break;
 
272
     
 
273
        
 
274
       case ButtonPress:
 
275
         
 
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);
 
279
        
 
280
        if (num == 0)
 
281
          g_timeout_add (1, notabutton_func, NULL);*/
 
282
  
 
283
       break;
 
284
 
 
285
   }
 
286
  
 
287
  // while (gtk_events_pending ())
 
288
  //   gtk_main_iteration ();
 
289
  
 
290
  }
 
291
 
 
292
  XUngrabPointer(GDK_DISPLAY(), CurrentTime);
 
293
  XFreeCursor (GDK_DISPLAY(), cursor);
 
294
 
 
295
  gtk_label_set_markup (GTK_LABEL(cancel_label), "<span size=\"small\"> </span>");
 
296
 
 
297
  if (!canceled) {
 
298
    gtk_label_set_text (GTK_LABEL(hint_label), "Thanks. Configuration completed.");
 
299
    gtk_sleep  (4000);
 
300
  }
 
301
    
 
302
  else {
 
303
    gtk_label_set_text (GTK_LABEL(hint_label), "Configuration canceled.");
 
304
    gtk_sleep (2000);
 
305
  }
 
306
 
 
307
  return num;
 
308
}
 
309
 
 
310
gboolean write_string_to_file (char *str, char* file)
 
311
{
 
312
 
 
313
  mode_t mode = S_IRUSR | S_IWUSR;
 
314
  ssize_t size;
 
315
  int fd;
 
316
 
 
317
  umask(0);
 
318
 
 
319
  size = strlen(str);
 
320
 
 
321
  fd = open(file, O_WRONLY | O_TRUNC | O_CREAT, mode);
 
322
 
 
323
  if(fd == -1) {
 
324
      perror("error with open()");
 
325
      return FALSE;
 
326
  }
 
327
 
 
328
  if(write(fd, str, size) != size) {
 
329
      perror("error with write()");
 
330
      return FALSE;
 
331
  }
 
332
 
 
333
  close (fd);
 
334
 
 
335
  return TRUE;
 
336
 
 
337
}
 
338
 
 
339
gchar *
 
340
alltray_user_dir(void) 
 
341
{
 
342
 
 
343
  gchar *user_dir=NULL;
 
344
  user_dir=g_strconcat (g_get_home_dir (), G_DIR_SEPARATOR_S, ".alltray", NULL);
 
345
 
 
346
  return user_dir;
 
347
}
 
348
 
 
349
GtkWidget*
 
350
create_configure_window (void)
 
351
{
 
352
  GtkWidget *configure_window;
 
353
  GtkWidget *vbox1;
 
354
  GtkWidget *label3;
 
355
  GtkWidget *hseparator1;
 
356
  GtkWidget *vbox2;
 
357
 
 
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);
 
364
 
 
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);
 
369
 
 
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);
 
375
 
 
376
  hseparator1 = gtk_hseparator_new ();
 
377
  gtk_widget_show (hseparator1);
 
378
  gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, TRUE, TRUE, 7);
 
379
 
 
380
  vbox2 = gtk_vbox_new (FALSE, 0);
 
381
  gtk_widget_show (vbox2);
 
382
  gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
 
383
 
 
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);
 
387
 
 
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);
 
392
 
 
393
  return configure_window;
 
394
}
 
395
 
 
396
void save_close_button_position (gboolean pos)
 
397
{
 
398
 
 
399
  gchar *user_dir=NULL;
 
400
  gchar *filename=NULL;
 
401
  FILE *file;
 
402
 
 
403
  user_dir=alltray_user_dir();
 
404
  if (debug) printf ("user_dir: %s\n", user_dir);
 
405
 
 
406
  file = fopen(user_dir, "r");
 
407
 
 
408
  if(!file)
 
409
    mkdir(user_dir, S_IRUSR | S_IWUSR | S_IXUSR);
 
410
  else
 
411
    fclose(file);
 
412
  
 
413
  filename = g_build_filename(user_dir, "prefs", NULL);
 
414
  
 
415
  if (debug) printf ("filnename: %s\n", filename);
 
416
  
 
417
  if (pos == LEFT)
 
418
    write_string_to_file ("left", filename);
 
419
  else
 
420
    write_string_to_file ("right", filename);
 
421
 
 
422
  g_free (user_dir);
 
423
  g_free (filename);
 
424
 
 
425
}
 
426
 
 
427
gboolean kde_get_close_button_positon (void)
 
428
{
 
429
 
 
430
  gchar *user_dir=NULL;
 
431
  gchar *content;
 
432
  gchar *filename;
 
433
  gboolean return_value=NO_SUCCESS;
 
434
 
 
435
  user_dir=alltray_user_dir();
 
436
  if (debug) printf ("user_dir: %s\n", user_dir);
 
437
 
 
438
  filename = g_build_filename(user_dir, "prefs", NULL);
 
439
 
 
440
  g_free (user_dir);
 
441
 
 
442
  if (!g_file_get_contents (filename, &content, NULL, NULL))
 
443
    return NO_SUCCESS;
 
444
 
 
445
  g_free (filename);
 
446
 
 
447
  if (debug) printf ("prefs content: %s\n", content);
 
448
 
 
449
  if (!strcmp (content, "left"))
 
450
    return_value=LEFT;
 
451
 
 
452
  if (!strcmp (content, "right"))
 
453
    return_value=RIGHT;
 
454
 
 
455
  g_free (content);
 
456
 
 
457
  return return_value;
 
458
 
 
459
}
 
460
 
 
461
gboolean kde_show_configure_dialog (win_struct *win)
 
462
{
 
463
 
 
464
  GtkWidget *window;
 
465
  GdkWindow  *target_gdk;
 
466
  Window target;
 
467
  Window kwin_window;
 
468
  gint num;
 
469
  GList *buttons;
 
470
 
 
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);
 
475
 
 
476
  //while (gtk_events_pending ())
 
477
  // gtk_main_iteration ();
 
478
 
 
479
  gtk_sleep (500);
 
480
 
 
481
  target_gdk = window->window;
 
482
  target=GDK_WINDOW_XID(target_gdk);
 
483
 
 
484
  //printf ("target id is: %d\n", target);
 
485
  
 
486
  kwin_window= get_kwin_window (target);
 
487
  //printf ("kwin_window: %d\n", kwin_window);
 
488
  
 
489
  buttons=get_button_list (kwin_window);
 
490
  num= get_button_number (kwin_window, buttons);
 
491
  
 
492
  if (debug) printf ("return num is: %d\n", num);
 
493
 
 
494
  free_button_list (buttons);
 
495
 
 
496
  gtk_widget_destroy (window);
 
497
 
 
498
  if (num == 0)
 
499
    return FALSE;
 
500
 
 
501
  if (num ==1)  {
 
502
    save_close_button_position (LEFT);
 
503
    win->kde_close_button_pos=LEFT;
 
504
  } else {
 
505
    save_close_button_position (RIGHT);
 
506
    win->kde_close_button_pos=RIGHT;
 
507
  }
 
508
 
 
509
return TRUE;
 
510
 
 
511
}
 
512
 
 
513
button kde_get_close_button (Window target, gboolean pos)
 
514
{
 
515
 
 
516
  GList *buttons;
 
517
  Window kwin_window= get_kwin_window (target);;
 
518
 
 
519
  buttons=get_button_list (kwin_window);
 
520
 
 
521
  if (pos ==RIGHT) 
 
522
      buttons=g_list_last (buttons);
 
523
  else
 
524
    buttons=g_list_first (buttons);
 
525
 
 
526
  button value=  *((button*) buttons->data);
 
527
 
 
528
  free_button_list (buttons);
 
529
  
 
530
  return value;
 
531
 
 
532
}