~ubuntu-branches/debian/lenny/italc/lenny

« back to all changes in this revision

Viewing changes to ica/x11/x11vnc/solid.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-06-17 13:46:54 UTC
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20080617134654-2y5m7ki93r5c1ysf
Tags: upstream-1.0.9~rc3
ImportĀ upstreamĀ versionĀ 1.0.9~rc3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -- solid.c -- */
 
2
 
 
3
#include "x11vnc.h"
 
4
#include "win_utils.h"
 
5
#include "xwrappers.h"
 
6
#include "connections.h"
 
7
#include "cleanup.h"
 
8
 
 
9
char *guess_desktop(void);
 
10
void solid_bg(int restore);
 
11
 
 
12
 
 
13
static void usr_bin_path(int restore);
 
14
static int dt_cmd(char *cmd);
 
15
static char *cmd_output(char *cmd);
 
16
XImage *solid_root(char *color);
 
17
static void solid_cde(char *color);
 
18
static void solid_gnome(char *color);
 
19
static void solid_kde(char *color);
 
20
 
 
21
 
 
22
static void usr_bin_path(int restore) {
 
23
        static char *oldpath = NULL;
 
24
        char *newpath;
 
25
        char addpath[] = "/usr/bin:/bin:";
 
26
 
 
27
        if (restore) {
 
28
                if (oldpath) {
 
29
                        set_env("PATH", oldpath);
 
30
                        free(oldpath);
 
31
                        oldpath = NULL;
 
32
                }
 
33
                return;
 
34
        }
 
35
 
 
36
        if (getenv("PATH")) {
 
37
                oldpath = strdup(getenv("PATH"));
 
38
        } else {
 
39
                oldpath = strdup("/usr/bin");
 
40
        }
 
41
        newpath = (char *) malloc(strlen(oldpath) + strlen(addpath) + 1);
 
42
        newpath[0] = '\0';
 
43
        strcat(newpath, addpath);
 
44
        strcat(newpath, oldpath);
 
45
        set_env("PATH", newpath);
 
46
        free(newpath);
 
47
}
 
48
 
 
49
static int dt_cmd(char *cmd) {
 
50
        int rc;
 
51
 
 
52
        RAWFB_RET(0)
 
53
 
 
54
        if (!cmd || *cmd == '\0') {
 
55
                return 0;
 
56
        }
 
57
 
 
58
        /* dt */
 
59
        if (no_external_cmds || !cmd_ok("dt")) {
 
60
                rfbLog("cannot run external commands in -nocmds mode:\n");
 
61
                rfbLog("   \"%s\"\n", cmd);
 
62
                rfbLog("   dt_cmd: returning 1\n");
 
63
                return 1;
 
64
        }
 
65
 
 
66
        if (getenv("DISPLAY") == NULL) {
 
67
                set_env("DISPLAY", DisplayString(dpy));
 
68
        }
 
69
 
 
70
        rfbLog("running command:\n");
 
71
        if (!quiet) {
 
72
                fprintf(stderr, "\n  %s\n\n", cmd);
 
73
        }
 
74
        usr_bin_path(0);
 
75
        close_exec_fds();
 
76
        rc = system(cmd);
 
77
        usr_bin_path(1);
 
78
 
 
79
        if (rc >= 256) {
 
80
                rc = rc/256;
 
81
        }
 
82
        return rc;
 
83
}
 
84
 
 
85
static char *cmd_output(char *cmd) {
 
86
        FILE *p;
 
87
        static char output[50000];
 
88
        char line[1024];
 
89
        int rc;
 
90
 
 
91
        if (!cmd || *cmd == '\0') {
 
92
                return "";
 
93
        }
 
94
 
 
95
        if (no_external_cmds) {
 
96
                rfbLog("cannot run external commands in -nocmds mode:\n");
 
97
                rfbLog("   \"%s\"\n", cmd);
 
98
                rfbLog("   cmd_output: null string.\n");
 
99
                return "";
 
100
        }
 
101
 
 
102
        rfbLog("running pipe:\n");
 
103
        if (!quiet) {
 
104
                fprintf(stderr, "\n  %s\n\n", cmd);
 
105
        }
 
106
        usr_bin_path(0);
 
107
        close_exec_fds();
 
108
        p = popen(cmd, "r");
 
109
        usr_bin_path(1);
 
110
 
 
111
        output[0] = '\0';
 
112
 
 
113
        while (fgets(line, 1024, p) != NULL) {
 
114
                if (strlen(output) + strlen(line) + 1 < 50000) {
 
115
                        strcat(output, line);
 
116
                }
 
117
        }
 
118
        rc = pclose(p);
 
119
        return(output);
 
120
}
 
121
 
 
122
static char *last_color = NULL;
 
123
 
 
124
unsigned long get_pixel(char *color) {
 
125
#if NO_X11
 
126
        return 0;
 
127
#else
 
128
        XColor cdef;
 
129
        Colormap cmap;
 
130
        unsigned long pixel = BlackPixel(dpy, scr);
 
131
        if (depth > 8 || strcmp(color, solid_default)) {
 
132
                cmap = DefaultColormap (dpy, scr);
 
133
                if (XParseColor(dpy, cmap, color, &cdef) &&
 
134
                    XAllocColor(dpy, cmap, &cdef)) {
 
135
                        pixel = cdef.pixel;
 
136
                } else {
 
137
                        rfbLog("error parsing/allocing color: %s\n", color);
 
138
                }
 
139
        }
 
140
        return pixel;
 
141
#endif
 
142
}
 
143
 
 
144
XImage *solid_root(char *color) {
 
145
#if NO_X11
 
146
        RAWFB_RET_VOID
 
147
        if (!color) {}
 
148
        return NULL;
 
149
#else
 
150
        Window expose;
 
151
        static XImage *image = NULL;
 
152
        Pixmap pixmap;
 
153
        XGCValues gcv;
 
154
        GC gc;
 
155
        XSetWindowAttributes swa;
 
156
        Visual visual;
 
157
        static unsigned long mask, pixel = 0;
 
158
 
 
159
        RAWFB_RET(NULL)
 
160
 
 
161
        if (subwin || window != rootwin) {
 
162
                rfbLog("cannot set subwin to solid color, must be rootwin\n");
 
163
                return NULL;
 
164
        }
 
165
 
 
166
        /* create the "clear" window just for generating exposures */
 
167
        swa.override_redirect = True;
 
168
        swa.backing_store = NotUseful;
 
169
        swa.save_under = False;
 
170
        swa.background_pixmap = None;
 
171
        visual.visualid = CopyFromParent;
 
172
        mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
 
173
        expose = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0, depth,
 
174
            InputOutput, &visual, mask, &swa);
 
175
 
 
176
        if (! color) {
 
177
 
 
178
                if (! image) {
 
179
                        /* whoops */
 
180
                        XDestroyWindow(dpy, expose);
 
181
                        rfbLog("no root snapshot available.\n");
 
182
                        return NULL;
 
183
                }
 
184
 
 
185
                /* restore the root window from the XImage snapshot */
 
186
                pixmap = XCreatePixmap(dpy, window, wdpy_x, wdpy_y, depth);
 
187
                
 
188
                /* draw the image to a pixmap: */
 
189
                gcv.function = GXcopy;
 
190
                gcv.plane_mask = AllPlanes;
 
191
                gc = XCreateGC(dpy, window, GCFunction|GCPlaneMask, &gcv);
 
192
 
 
193
                XPutImage(dpy, pixmap, gc, image, 0, 0, 0, 0, wdpy_x, wdpy_y);
 
194
 
 
195
                gcv.foreground = gcv.background = BlackPixel(dpy, scr);
 
196
                gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
 
197
 
 
198
                rfbLog("restoring root snapshot...\n");
 
199
                /* set the pixmap as the bg: */
 
200
                XSetWindowBackgroundPixmap(dpy, window, pixmap);
 
201
                XFreePixmap(dpy, pixmap);
 
202
                XClearWindow(dpy, window);
 
203
                XFlush_wr(dpy);
 
204
                
 
205
                /* generate exposures */
 
206
                XMapWindow(dpy, expose);
 
207
                XSync(dpy, False);
 
208
                XDestroyWindow(dpy, expose);
 
209
                return NULL;
 
210
        }
 
211
 
 
212
        if (! image) {
 
213
                /* need to retrieve a snapshot of the root background: */
 
214
                Window iwin;
 
215
                XSetWindowAttributes iswa;
 
216
 
 
217
                /* create image window: */
 
218
                iswa.override_redirect = True;
 
219
                iswa.backing_store = NotUseful;
 
220
                iswa.save_under = False;
 
221
                iswa.background_pixmap = ParentRelative;
 
222
 
 
223
                iwin = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0,
 
224
                    depth, InputOutput, &visual, mask, &iswa);
 
225
 
 
226
                rfbLog("snapshotting background...\n");
 
227
 
 
228
                XMapWindow(dpy, iwin);
 
229
                XSync(dpy, False);
 
230
                image = XGetImage(dpy, iwin, 0, 0, wdpy_x, wdpy_y, AllPlanes,
 
231
                    ZPixmap);
 
232
                XSync(dpy, False);
 
233
                XDestroyWindow(dpy, iwin);
 
234
                rfbLog("done.\n");
 
235
        }
 
236
        if (color == (char *) 0x1) {
 
237
                /* caller will XDestroyImage it: */
 
238
                XImage *xi = image;
 
239
                image = NULL;
 
240
                return xi;
 
241
        }
 
242
 
 
243
        /* use black for low colors or failure */
 
244
        pixel = get_pixel(color);
 
245
 
 
246
        rfbLog("setting solid background...\n");
 
247
        XSetWindowBackground(dpy, window, pixel);
 
248
        XMapWindow(dpy, expose);
 
249
        XSync(dpy, False);
 
250
        XDestroyWindow(dpy, expose);
 
251
#endif  /* NO_X11 */
 
252
        return NULL;
 
253
}
 
254
 
 
255
static void solid_cde(char *color) {
 
256
#if NO_X11
 
257
        RAWFB_RET_VOID
 
258
        if (!color) {}
 
259
        return;
 
260
#else
 
261
        int wsmax = 16;
 
262
        static XImage *image[16];
 
263
        static Window ws_wins[16];
 
264
        static int nws = -1;
 
265
 
 
266
        Window expose;
 
267
        Pixmap pixmap;
 
268
        XGCValues gcv;
 
269
        GC gc;
 
270
        XSetWindowAttributes swa;
 
271
        Visual visual;
 
272
        unsigned long mask, pixel;
 
273
        XColor cdef;
 
274
        Colormap cmap;
 
275
        int n;
 
276
 
 
277
        RAWFB_RET_VOID
 
278
 
 
279
        if (subwin || window != rootwin) {
 
280
                rfbLog("cannot set subwin to solid color, must be rootwin\n");
 
281
                return;
 
282
        }
 
283
 
 
284
        /* create the "clear" window just for generating exposures */
 
285
        swa.override_redirect = True;
 
286
        swa.backing_store = NotUseful;
 
287
        swa.save_under = False;
 
288
        swa.background_pixmap = None;
 
289
        visual.visualid = CopyFromParent;
 
290
        mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
 
291
        expose = XCreateWindow(dpy, window, 0, 0, wdpy_x, wdpy_y, 0, depth,
 
292
            InputOutput, &visual, mask, &swa);
 
293
 
 
294
        if (! color) {
 
295
                /* restore the backdrop windows from the XImage snapshots */
 
296
 
 
297
                for (n=0; n < nws; n++) {
 
298
                        Window twin;
 
299
 
 
300
                        if (! image[n]) {
 
301
                                continue;
 
302
                        }
 
303
 
 
304
                        twin = ws_wins[n];
 
305
                        if (! twin) {
 
306
                                twin = rootwin;
 
307
                        }
 
308
                        if (! valid_window(twin, NULL, 0)) {
 
309
                                continue;
 
310
                        }
 
311
 
 
312
                        pixmap = XCreatePixmap(dpy, twin, wdpy_x, wdpy_y,
 
313
                            depth);
 
314
                        
 
315
                        /* draw the image to a pixmap: */
 
316
                        gcv.function = GXcopy;
 
317
                        gcv.plane_mask = AllPlanes;
 
318
                        gc = XCreateGC(dpy, twin, GCFunction|GCPlaneMask, &gcv);
 
319
 
 
320
                        XPutImage(dpy, pixmap, gc, image[n], 0, 0, 0, 0,
 
321
                            wdpy_x, wdpy_y);
 
322
 
 
323
                        gcv.foreground = gcv.background = BlackPixel(dpy, scr);
 
324
                        gc = XCreateGC(dpy, twin, GCForeground|GCBackground,
 
325
                            &gcv);
 
326
 
 
327
                        rfbLog("restoring CDE ws%d snapshot to 0x%lx\n",
 
328
                            n, twin);
 
329
                        /* set the pixmap as the bg: */
 
330
                        XSetWindowBackgroundPixmap(dpy, twin, pixmap);
 
331
                        XFreePixmap(dpy, pixmap);
 
332
                        XClearWindow(dpy, twin);
 
333
                        XFlush_wr(dpy);
 
334
                }
 
335
                
 
336
                /* generate exposures */
 
337
                XMapWindow(dpy, expose);
 
338
                XSync(dpy, False);
 
339
                XDestroyWindow(dpy, expose);
 
340
                return;
 
341
        }
 
342
 
 
343
        if (nws < 0) {
 
344
                /* need to retrieve snapshots of the ws backgrounds: */
 
345
                Window iwin, wm_win;
 
346
                XSetWindowAttributes iswa;
 
347
                Atom dt_list, wm_info, type;
 
348
                int format;
 
349
                unsigned long length, after;
 
350
                unsigned char *data;
 
351
                unsigned long *dp;      /* crash on 64bit with int */
 
352
 
 
353
                nws = 0;
 
354
 
 
355
                /* extract the hidden wm properties about backdrops: */
 
356
 
 
357
                wm_info = XInternAtom(dpy, "_MOTIF_WM_INFO", True);
 
358
                if (wm_info == None) {
 
359
                        return;
 
360
                }
 
361
 
 
362
                XGetWindowProperty(dpy, rootwin, wm_info, 0L, 10L, False,
 
363
                    AnyPropertyType, &type, &format, &length, &after, &data);
 
364
 
 
365
                /*
 
366
                 * xprop -notype -root _MOTIF_WM_INFO
 
367
                 * _MOTIF_WM_INFO = 0x2, 0x580028
 
368
                 */
 
369
 
 
370
                if (length < 2 || format != 32 || after != 0) {
 
371
                        return;
 
372
                }
 
373
 
 
374
                dp = (unsigned long *) data;
 
375
                wm_win = (Window) *(dp+1);      /* 2nd item. */
 
376
 
 
377
 
 
378
                dt_list = XInternAtom(dpy, "_DT_WORKSPACE_LIST", True);
 
379
                if (dt_list == None) {
 
380
                        return;
 
381
                }
 
382
 
 
383
                XGetWindowProperty(dpy, wm_win, dt_list, 0L, 10L, False,
 
384
                   AnyPropertyType, &type, &format, &length, &after, &data);
 
385
 
 
386
                nws = length;
 
387
 
 
388
                if (nws > wsmax) {
 
389
                        nws = wsmax;
 
390
                }
 
391
                if (nws < 0) {
 
392
                        nws = 0;
 
393
                }
 
394
 
 
395
                rfbLog("special CDE win: 0x%lx, %d workspaces\n", wm_win, nws);
 
396
                if (nws == 0) {
 
397
                        return;
 
398
                }
 
399
 
 
400
                for (n=0; n<nws; n++) {
 
401
                        Atom ws_atom;
 
402
                        char tmp[32];
 
403
                        Window twin;
 
404
                        XWindowAttributes attr;
 
405
                        int i, cnt;
 
406
 
 
407
                        image[n] = NULL;
 
408
                        ws_wins[n] = 0x0;
 
409
 
 
410
                        sprintf(tmp, "_DT_WORKSPACE_INFO_ws%d", n);
 
411
                        ws_atom = XInternAtom(dpy, tmp, False);
 
412
                        if (ws_atom == None) {
 
413
                                continue;
 
414
                        }
 
415
                        XGetWindowProperty(dpy, wm_win, ws_atom, 0L, 100L,
 
416
                           False, AnyPropertyType, &type, &format, &length,
 
417
                           &after, &data);
 
418
 
 
419
                        if (format != 8 || after != 0) {
 
420
                                continue;
 
421
                        }
 
422
                        /*
 
423
                         * xprop -notype -id wm_win
 
424
                         * _DT_WORKSPACE_INFO_ws0 = "One", "3", "0x2f2f4a",
 
425
                         * "0x63639c", "0x103", "1", "0x58044e"
 
426
                         */
 
427
 
 
428
                        cnt = 0;
 
429
                        twin = 0x0;
 
430
                        for (i=0; i< (int) length; i++) {
 
431
                                if (*(data+i) != '\0') {
 
432
                                        continue;
 
433
                                }
 
434
                                cnt++;  /* count nulls to indicate field */
 
435
                                if (cnt == 6) {
 
436
                                        /* one past the null: */
 
437
                                        char *q = (char *) (data+i+1);
 
438
                                        unsigned long in;
 
439
                                        if (sscanf(q, "0x%lx", &in) == 1) {
 
440
                                                twin = (Window) in;
 
441
                                                break;
 
442
                                        }
 
443
                                }
 
444
                        }
 
445
                        ws_wins[n] = twin;
 
446
 
 
447
                        if (! twin) {
 
448
                                twin = rootwin;
 
449
                        }
 
450
 
 
451
                        XGetWindowAttributes(dpy, twin, &attr);
 
452
                        if (twin != rootwin) {
 
453
                                if (attr.map_state != IsViewable) {
 
454
                                        XMapWindow(dpy, twin);
 
455
                                }
 
456
                                XRaiseWindow(dpy, twin);
 
457
                        }
 
458
                        XSync(dpy, False);
 
459
                
 
460
                        /* create image window: */
 
461
                        iswa.override_redirect = True;
 
462
                        iswa.backing_store = NotUseful;
 
463
                        iswa.save_under = False;
 
464
                        iswa.background_pixmap = ParentRelative;
 
465
                        visual.visualid = CopyFromParent;
 
466
 
 
467
                        iwin = XCreateWindow(dpy, twin, 0, 0, wdpy_x, wdpy_y,
 
468
                            0, depth, InputOutput, &visual, mask, &iswa);
 
469
 
 
470
                        rfbLog("snapshotting CDE backdrop ws%d 0x%lx -> "
 
471
                            "0x%lx ...\n", n, twin, iwin);
 
472
                        XMapWindow(dpy, iwin);
 
473
                        XSync(dpy, False);
 
474
 
 
475
                        image[n] = XGetImage(dpy, iwin, 0, 0, wdpy_x, wdpy_y,
 
476
                            AllPlanes, ZPixmap);
 
477
                        XSync(dpy, False);
 
478
                        XDestroyWindow(dpy, iwin);
 
479
                        if (twin != rootwin) {
 
480
                                XLowerWindow(dpy, twin);
 
481
                                if (attr.map_state != IsViewable) {
 
482
                                        XUnmapWindow(dpy, twin);
 
483
                                }
 
484
                        }
 
485
                }
 
486
        }
 
487
        if (nws == 0) {
 
488
                return;
 
489
        }
 
490
 
 
491
        /* use black for low colors or failure */
 
492
        pixel = BlackPixel(dpy, scr);
 
493
        if (depth > 8 || strcmp(color, solid_default)) {
 
494
                cmap = DefaultColormap (dpy, scr);
 
495
                if (XParseColor(dpy, cmap, color, &cdef) &&
 
496
                    XAllocColor(dpy, cmap, &cdef)) {
 
497
                        pixel = cdef.pixel;
 
498
                } else {
 
499
                        rfbLog("error parsing/allocing color: %s\n", color);
 
500
                }
 
501
        }
 
502
 
 
503
        rfbLog("setting solid backgrounds...\n");
 
504
 
 
505
        for (n=0; n < nws; n++)  {
 
506
                Window twin = ws_wins[n];
 
507
                if (image[n] == NULL) {
 
508
                        continue;
 
509
                }
 
510
                if (! twin)  {
 
511
                        twin = rootwin;
 
512
                }
 
513
                XSetWindowBackground(dpy, twin, pixel);
 
514
        }
 
515
        XMapWindow(dpy, expose);
 
516
        XSync(dpy, False);
 
517
        XDestroyWindow(dpy, expose);
 
518
#endif  /* NO_X11 */
 
519
}
 
520
 
 
521
static void solid_gnome(char *color) {
 
522
#if NO_X11
 
523
        RAWFB_RET_VOID
 
524
        if (!color) {}
 
525
        return;
 
526
#else
 
527
        char get_color[] = "gconftool-2 --get "
 
528
            "/desktop/gnome/background/primary_color";
 
529
        char set_color[] = "gconftool-2 --set "
 
530
            "/desktop/gnome/background/primary_color --type string '%s'";
 
531
        char get_option[] = "gconftool-2 --get "
 
532
            "/desktop/gnome/background/picture_options";
 
533
        char set_option[] = "gconftool-2 --set "
 
534
            "/desktop/gnome/background/picture_options --type string '%s'";
 
535
        static char *orig_color = NULL;
 
536
        static char *orig_option = NULL;
 
537
        char *cmd;
 
538
 
 
539
        RAWFB_RET_VOID
 
540
        
 
541
        if (! color) {
 
542
                if (! orig_color) {
 
543
                        orig_color = strdup("#FFFFFF");
 
544
                }
 
545
                if (! orig_option) {
 
546
                        orig_option = strdup("stretched");
 
547
                }
 
548
                if (strstr(orig_color, "'") != NULL)  {
 
549
                        rfbLog("invalid color: %s\n", orig_color);
 
550
                        return;
 
551
                }
 
552
                if (strstr(orig_option, "'") != NULL)  {
 
553
                        rfbLog("invalid option: %s\n", orig_option);
 
554
                        return;
 
555
                }
 
556
                cmd = (char *) malloc(strlen(set_option) - 2 +
 
557
                    strlen(orig_option) + 1);
 
558
                sprintf(cmd, set_option, orig_option);
 
559
                dt_cmd(cmd);
 
560
                free(cmd);
 
561
                cmd = (char *) malloc(strlen(set_color) - 2 +
 
562
                    strlen(orig_color) + 1);
 
563
                sprintf(cmd, set_color, orig_color);
 
564
                dt_cmd(cmd);
 
565
                free(cmd);
 
566
                return;
 
567
        }
 
568
 
 
569
        if (! orig_color) {
 
570
                char *q;
 
571
                if (cmd_ok("dt")) {
 
572
                        orig_color = strdup(cmd_output(get_color));
 
573
                } else {
 
574
                        orig_color = "";
 
575
                }
 
576
                if (*orig_color == '\0') {
 
577
                        orig_color = strdup("#FFFFFF");
 
578
                }
 
579
                if ((q = strchr(orig_color, '\n')) != NULL) {
 
580
                        *q = '\0';
 
581
                }
 
582
        }
 
583
        if (! orig_option) {
 
584
                char *q;
 
585
                if (cmd_ok("dt")) {
 
586
                        orig_option = strdup(cmd_output(get_option));
 
587
                } else {
 
588
                        orig_color = "";
 
589
                }
 
590
                if (*orig_option == '\0') {
 
591
                        orig_option = strdup("stretched");
 
592
                }
 
593
                if ((q = strchr(orig_option, '\n')) != NULL) {
 
594
                        *q = '\0';
 
595
                }
 
596
        }
 
597
        if (strstr(color, "'") != NULL)  {
 
598
                rfbLog("invalid color: %s\n", color);
 
599
                return;
 
600
        }
 
601
        cmd = (char *) malloc(strlen(set_color) + strlen(color) + 1);
 
602
        sprintf(cmd, set_color, color);
 
603
        dt_cmd(cmd);
 
604
        free(cmd);
 
605
 
 
606
        cmd = (char *) malloc(strlen(set_option) + strlen("none") + 1);
 
607
        sprintf(cmd, set_option, "none");
 
608
        dt_cmd(cmd);
 
609
        free(cmd);
 
610
#endif  /* NO_X11 */
 
611
}
 
612
 
 
613
static char *dcop_session(void) {
 
614
        char *empty = strdup("");
 
615
#if NO_X11
 
616
        RAWFB_RET(empty);
 
617
        return empty;
 
618
#else
 
619
        char list_sessions[] = "dcop --user '%s' --list-sessions";
 
620
        int len;
 
621
        char *cmd, *host, *user = NULL;
 
622
        char *out, *p, *ds, *dsn = NULL, *sess = NULL, *sess2 = NULL;
 
623
        int db = 0;
 
624
 
 
625
        RAWFB_RET(empty);
 
626
 
 
627
        if (getenv("SESSION_MANAGER")) {
 
628
                return empty;
 
629
        }
 
630
 
 
631
        user = get_user_name();
 
632
        if (strstr(user, "'") != NULL)  {
 
633
                rfbLog("invalid user: %s\n", user);
 
634
                free(user);
 
635
                return empty;
 
636
        }
 
637
 
 
638
        len = strlen(list_sessions) + strlen(user) + 1;
 
639
        cmd = (char *) malloc(len);
 
640
        sprintf(cmd, list_sessions, user);
 
641
 
 
642
        out = strdup(cmd_output(cmd));
 
643
        free(cmd);
 
644
        free(user);
 
645
 
 
646
        ds = DisplayString(dpy);
 
647
        if (!ds || !strcmp(ds, "")) {
 
648
                ds = getenv("DISPLAY");
 
649
        }
 
650
        if (!ds) {
 
651
                ds = ":0";
 
652
        }
 
653
        ds = strdup(ds);
 
654
        p = strrchr(ds, '.');
 
655
        if (p) *p = '\0';
 
656
 
 
657
        dsn = strchr(ds, ':');
 
658
        if (dsn) {
 
659
                *dsn = '_';
 
660
        } else {
 
661
                free(ds);
 
662
                ds = strdup("_0");
 
663
                dsn = ds;
 
664
        }
 
665
        if (db) fprintf(stderr, "ds:  %s\n", ds);
 
666
        if (db) fprintf(stderr, "dsn: %s\n", dsn);
 
667
 
 
668
        host = this_host();
 
669
        if (host) {
 
670
                char *h2 = (char *) malloc(strlen(host) + 2 + 1);
 
671
                sprintf(h2, "_%s_", host);
 
672
                free(host);
 
673
                host = h2;
 
674
        } else {
 
675
                host = strdup("");
 
676
        }
 
677
        if (db) fprintf(stderr, "host: %s\n", host);
 
678
 
 
679
        p = strtok(out, "\n");
 
680
        while (p) {
 
681
                char *q = strstr(p, ".DCOP");
 
682
                if (db) fprintf(stderr, "p:  %s\n", p);
 
683
                if (q == NULL) {
 
684
                        ;
 
685
                } else if (host) {
 
686
                        if (strstr(q, host)) {
 
687
                                char *r = strstr(p, dsn);
 
688
                                int n = strlen(dsn);
 
689
                                if(r && !isalnum((int) *(r+n))) {
 
690
                                        sess = strdup(q);
 
691
                                        break;
 
692
                                } else {
 
693
                                        if (sess2) {
 
694
                                                free(sess2);
 
695
                                        } 
 
696
                                        sess2 = strdup(q);
 
697
                                }
 
698
                        }
 
699
                } else {
 
700
                        char *r = strstr(p, dsn);
 
701
                        int n = strlen(dsn);
 
702
                        if(r && !isalnum((int) *(r+n))) {
 
703
                                sess = strdup(q);
 
704
                                break;
 
705
                        }
 
706
                }
 
707
                p = strtok(NULL, "\n");
 
708
        }
 
709
        free(ds);
 
710
        free(out);
 
711
        free(host);
 
712
        if (!sess && sess2) {
 
713
                sess = sess2;
 
714
        }
 
715
        if (!sess || strchr(sess, '\'')) {
 
716
                if (sess) free(sess);
 
717
                sess = strdup("--all-sessions");
 
718
        } else {
 
719
                len = strlen("--session ") + 2 + strlen(sess) + 1;
 
720
                cmd = (char *) malloc(len);
 
721
                sprintf(cmd, "--session '%s'", sess);
 
722
                free(sess);
 
723
                sess = cmd;
 
724
        }
 
725
        return sess;
 
726
#endif
 
727
}
 
728
 
 
729
static void solid_kde(char *color) {
 
730
#if NO_X11
 
731
        RAWFB_RET_VOID
 
732
        if (!color) {}
 
733
        return;
 
734
#else
 
735
        char set_color[] =
 
736
            "dcop --user '%s' %s kdesktop KBackgroundIface setColor '%s' 1";
 
737
        char bg_off[] =
 
738
            "dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 0";
 
739
        char bg_on[] =
 
740
            "dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 1";
 
741
        char *cmd, *user = NULL, *sess;
 
742
        int len;
 
743
 
 
744
        RAWFB_RET_VOID
 
745
 
 
746
        user = get_user_name();
 
747
        if (strstr(user, "'") != NULL)  {
 
748
                rfbLog("invalid user: %s\n", user);
 
749
                free(user);
 
750
                return;
 
751
        }
 
752
 
 
753
        set_env("DISPLAY", DisplayString(dpy));
 
754
 
 
755
        if (! color) {
 
756
                sess = dcop_session();
 
757
                len = strlen(bg_on) + strlen(user) + strlen(sess) + 1;
 
758
                cmd = (char *) malloc(len);
 
759
                sprintf(cmd, bg_on, user, sess);
 
760
 
 
761
                dt_cmd(cmd);
 
762
 
 
763
                free(cmd);
 
764
                free(user);
 
765
                free(sess);
 
766
 
 
767
                return;
 
768
        }
 
769
 
 
770
        if (strstr(color, "'") != NULL)  {
 
771
                rfbLog("invalid color: %s\n", color);
 
772
                return;
 
773
        }
 
774
 
 
775
        sess = dcop_session();
 
776
 
 
777
        len = strlen(set_color) + strlen(user) + strlen(sess) + strlen(color) + 1;
 
778
        cmd = (char *) malloc(len);
 
779
        sprintf(cmd, set_color, user, sess, color);
 
780
        dt_cmd(cmd);
 
781
        free(cmd);
 
782
 
 
783
        len = strlen(bg_off) + strlen(user) + strlen(sess) + 1;
 
784
        cmd = (char *) malloc(len);
 
785
        sprintf(cmd, bg_off, user, sess);
 
786
        dt_cmd(cmd);
 
787
        free(cmd);
 
788
        free(user);
 
789
#endif  /* NO_X11 */
 
790
}
 
791
 
 
792
void kde_no_animate(int restore) {
 
793
#if NO_X11
 
794
        if (!restore) {}
 
795
        RAWFB_RET_VOID
 
796
        return;
 
797
#else
 
798
        char query_setting[] =
 
799
            "kreadconfig  --file kwinrc --group Windows --key AnimateMinimize";
 
800
        char kwinrc_off[] =
 
801
            "kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool false";
 
802
        char kwinrc_on[] =
 
803
            "kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool true";
 
804
        char kwin_reconfigure[] =
 
805
            "dcop --user '%s' %s kwin KWinInterface reconfigure";
 
806
        char *cmd, *cmd2, *out, *user = NULL, *sess;
 
807
        int len;
 
808
        static int anim_state = 1;
 
809
 
 
810
        RAWFB_RET_VOID
 
811
 
 
812
        if (ncache_keep_anims) {
 
813
                return;
 
814
        }
 
815
 
 
816
        if (restore) {
 
817
                if (anim_state == 1) {
 
818
                        return;
 
819
                }
 
820
 
 
821
                user = get_user_name();
 
822
                if (strstr(user, "'") != NULL)  {
 
823
                        rfbLog("invalid user: %s\n", user);
 
824
                        free(user);
 
825
                        return;
 
826
                }
 
827
 
 
828
                sess = dcop_session();
 
829
 
 
830
                len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
 
831
                cmd = (char *) malloc(len);
 
832
                sprintf(cmd, kwin_reconfigure, user, sess);
 
833
                rfbLog("\n");
 
834
                rfbLog("Restoring KDE kwinrc settings.\n");
 
835
                rfbLog("\n");
 
836
                dt_cmd(cmd);
 
837
                free(cmd);
 
838
                free(user);
 
839
                free(sess);
 
840
                anim_state = 1;
 
841
                return;
 
842
        } else {
 
843
                if (anim_state == 0) {
 
844
                        return;
 
845
                }
 
846
                anim_state = 0;
 
847
        }
 
848
 
 
849
        user = get_user_name();
 
850
        if (strstr(user, "'") != NULL)  {
 
851
                rfbLog("invalid user: %s\n", user);
 
852
                free(user);
 
853
                return;
 
854
        }
 
855
        out = cmd_output(query_setting);
 
856
 
 
857
 
 
858
        if (!out || strstr(out, "false")) {
 
859
                rfbLog("\n");
 
860
                rfbLog("********************************************************\n");
 
861
                rfbLog("KDE kwinrc AnimateMinimize is false. Good.\n");
 
862
                rfbLog("********************************************************\n");
 
863
                rfbLog("\n");
 
864
                free(user);
 
865
                return;
 
866
        }
 
867
 
 
868
        rfbLog("\n");
 
869
        rfbLog("********************************************************\n");
 
870
        rfbLog("To improve the -ncache client-side caching performance\n");
 
871
        rfbLog("temporarily setting KDE kwinrc AnimateMinimize to false.\n");
 
872
        rfbLog("It will be reset for the next session or when VNC client\n");
 
873
        rfbLog("disconnects.  Or you can use the Control Center GUI to\n");
 
874
        rfbLog("change it now (toggle its setting a few times):\n");
 
875
        rfbLog("   Desktop -> Window Behavior -> Moving\n");
 
876
        rfbLog("********************************************************\n");
 
877
        rfbLog("\n");
 
878
 
 
879
        set_env("DISPLAY", DisplayString(dpy));
 
880
 
 
881
        sess = dcop_session();
 
882
        len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
 
883
        cmd = (char *) malloc(len);
 
884
        sprintf(cmd, kwin_reconfigure, user, sess);
 
885
 
 
886
        len = 1 + strlen("sleep 10") + 2 + strlen(kwinrc_off) + 2 + strlen(cmd) + 2 + strlen("sleep 5") + 2 + strlen(kwinrc_on) + 3 + 1;
 
887
        cmd2 = (char *) malloc(len);
 
888
 
 
889
        sprintf(cmd2, "(sleep 10; %s; %s; sleep 5; %s) &", kwinrc_off, cmd, kwinrc_on);
 
890
 
 
891
        dt_cmd(cmd2);
 
892
        free(cmd);
 
893
        free(cmd2);
 
894
        free(user);
 
895
        free(sess);
 
896
#endif  /* NO_X11 */
 
897
}
 
898
 
 
899
void gnome_no_animate(void) {
 
900
        ;
 
901
}
 
902
 
 
903
char *guess_desktop(void) {
 
904
#if NO_X11
 
905
        RAWFB_RET("root")
 
906
        return "root";
 
907
#else
 
908
        Atom prop;
 
909
 
 
910
        RAWFB_RET("root")
 
911
 
 
912
        if (wmdt_str && *wmdt_str != '\0') {
 
913
                char *s = wmdt_str;
 
914
                lowercase(s);
 
915
                if (strstr(s, "xfce")) {
 
916
                        return "xfce";
 
917
                }
 
918
                if (strstr(s, "gnome") || strstr(s, "metacity")) {
 
919
                        return "gnome";
 
920
                }
 
921
                if (strstr(s, "kde") || strstr(s, "kwin")) {
 
922
                        return "kde";
 
923
                }
 
924
                if (strstr(s, "cde")) {
 
925
                        return "cde";
 
926
                }
 
927
                return "root";
 
928
        }
 
929
 
 
930
        if (! dpy) {
 
931
                return "";
 
932
        }
 
933
 
 
934
        prop = XInternAtom(dpy, "XFCE_DESKTOP_WINDOW", True);
 
935
        if (prop != None) return "xfce";
 
936
 
 
937
        /* special case windowmaker */
 
938
        prop = XInternAtom(dpy, "_WINDOWMAKER_WM_PROTOCOLS", True);
 
939
        if (prop != None)  return "root";
 
940
 
 
941
        prop = XInternAtom(dpy, "_WINDOWMAKER_COMMAND", True);
 
942
        if (prop != None) return "root";
 
943
 
 
944
        prop = XInternAtom(dpy, "NAUTILUS_DESKTOP_WINDOW_ID", True);
 
945
        if (prop != None) return "gnome";
 
946
 
 
947
        prop = XInternAtom(dpy, "KWIN_RUNNING", True);
 
948
        if (prop != None) {
 
949
                prop = XInternAtom(dpy, "_KDE_RUNNING", True);
 
950
                if (prop != None) {
 
951
                        prop = XInternAtom(dpy, "KDE_DESKTOP_WINDOW", True);
 
952
                        if (prop != None) return "kde";
 
953
                }
 
954
        }
 
955
 
 
956
        prop = XInternAtom(dpy, "_MOTIF_WM_INFO", True);
 
957
        if (prop != None) {
 
958
                prop = XInternAtom(dpy, "_DT_WORKSPACE_LIST", True);
 
959
                if (prop != None) return "cde";
 
960
        }
 
961
        return "root";
 
962
#endif  /* NO_X11 */
 
963
}
 
964
 
 
965
XImage *solid_image(char *color) {
 
966
#if NO_X11
 
967
        RAWFB_RET(NULL)
 
968
        return NULL;
 
969
#else
 
970
        XImage *image = NULL;
 
971
        unsigned long pixel = 0;
 
972
        int x, y;
 
973
 
 
974
        RAWFB_RET(NULL)
 
975
 
 
976
        if (!color) {
 
977
                color = last_color;
 
978
        }
 
979
 
 
980
        if (!color) {
 
981
                return NULL;
 
982
        }
 
983
 
 
984
        image = XGetImage(dpy, rootwin, 0, 0, wdpy_x, wdpy_y, AllPlanes,
 
985
            ZPixmap);
 
986
 
 
987
        if (!image) {
 
988
                return NULL;
 
989
        }
 
990
        pixel = get_pixel(color);
 
991
 
 
992
        for (y=0; y<wdpy_y; y++) {
 
993
                for (x=0; x<wdpy_x; x++) {
 
994
                        XPutPixel(image, x, y, pixel);
 
995
                }
 
996
        }
 
997
        return image;
 
998
#endif  /* NO_X11 */
 
999
}
 
1000
 
 
1001
void solid_bg(int restore) {
 
1002
        static int desktop = -1;
 
1003
        static int solid_on = 0;
 
1004
        static char *prev_str;
 
1005
        char *dtname, *color;
 
1006
 
 
1007
        RAWFB_RET_VOID
 
1008
 
 
1009
        if (started_as_root == 1 && users_list) {
 
1010
                /* we are still root, don't try. */
 
1011
                return;
 
1012
        }
 
1013
 
 
1014
        if (restore) {
 
1015
                if (! solid_on) {
 
1016
                        return;
 
1017
                }
 
1018
                if (desktop == 0) {
 
1019
                        solid_root(NULL);
 
1020
                } else if (desktop == 1) {
 
1021
                        solid_gnome(NULL);
 
1022
                } else if (desktop == 2) {
 
1023
                        solid_kde(NULL);
 
1024
                } else if (desktop == 3) {
 
1025
                        solid_cde(NULL);
 
1026
                }
 
1027
                solid_on = 0;
 
1028
                return;
 
1029
        }
 
1030
        if (! solid_str) {
 
1031
                return;
 
1032
        }
 
1033
        if (solid_on && !strcmp(prev_str, solid_str)) {
 
1034
                return;
 
1035
        }
 
1036
        if (strstr(solid_str, "guess:") == solid_str
 
1037
            || !strchr(solid_str, ':')) {
 
1038
                dtname = guess_desktop();
 
1039
                rfbLog("guessed desktop: %s\n", dtname);
 
1040
        } else {
 
1041
                if (strstr(solid_str, "gnome:") == solid_str) {
 
1042
                        dtname = "gnome";
 
1043
                } else if (strstr(solid_str, "kde:") == solid_str) {
 
1044
                        dtname = "kde";
 
1045
                } else if (strstr(solid_str, "cde:") == solid_str) {
 
1046
                        dtname = "cde";
 
1047
                } else {
 
1048
                        dtname = "root";
 
1049
                }
 
1050
        }
 
1051
 
 
1052
        color = strchr(solid_str, ':');
 
1053
        if (! color) {
 
1054
                color = solid_str;
 
1055
        } else {
 
1056
                color++;
 
1057
                if (*color == '\0') {
 
1058
                        color = solid_default;
 
1059
                }
 
1060
        }
 
1061
        if (last_color) {
 
1062
                free(last_color);
 
1063
        }
 
1064
        last_color = strdup(color);
 
1065
 
 
1066
        if (!strcmp(dtname, "gnome")) {
 
1067
                desktop = 1;
 
1068
                solid_gnome(color);
 
1069
        } else if (!strcmp(dtname, "kde")) {
 
1070
                desktop = 2;
 
1071
                solid_kde(color);
 
1072
        } else if (!strcmp(dtname, "cde")) {
 
1073
                desktop = 3;
 
1074
                solid_cde(color);
 
1075
        } else {
 
1076
                desktop = 0;
 
1077
                solid_root(color);
 
1078
        }
 
1079
        if (prev_str) {
 
1080
                free(prev_str);
 
1081
        }
 
1082
        prev_str = strdup(solid_str);
 
1083
        solid_on = 1;
 
1084
}
 
1085
 
 
1086