~ubuntu-branches/ubuntu/karmic/xfce4-session/karmic

« back to all changes in this revision

Viewing changes to xfce4-session/xfsm-legacy.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2005-11-06 22:01:12 UTC
  • mto: (4.1.1 lenny) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051106220112-5rusox237ymjghsp
Tags: upstream-4.2.3
ImportĀ upstreamĀ versionĀ 4.2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: xfsm-legacy.c 4751 2004-12-27 17:25:51Z benny $ */
 
2
/*-
 
3
 * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
 
4
 * All rights reserved.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2, or (at your option)
 
9
 * any later version.
 
10
 *                                                                              
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *                                                                              
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
19
 * 02111-1307, USA.
 
20
 *
 
21
 *
 
22
 * Most of the code in this file is borred from ksmserver, the KDE session
 
23
 * management server.
 
24
 * Copyright (C) 2000 Matthias Ettrich <ettrich@kde.org>
 
25
 *
 
26
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
27
 * of this software and associated documentation files (the "Software"), to deal
 
28
 * in the Software without restriction, including without limitation the rights
 
29
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
30
 * copies of the Software, and to permit persons to whom the Software is
 
31
 * furnished to do so, subject to the following conditions:
 
32
 * 
 
33
 * The above copyright notice and this permission notice shall be included in
 
34
 * all copies or substantial portions of the Software.
 
35
 * 
 
36
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
37
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
38
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
39
 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
40
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
41
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
42
 */
 
43
/* After all, this code is mostly a hack now, one should cleanup the
 
44
 * stuff before 4.2!
 
45
 */
 
46
 
 
47
#ifdef HAVE_CONFIG_H
 
48
#include <config.h>
 
49
#endif
 
50
 
 
51
#ifdef HAVE_SYS_TYPES_H
 
52
#include <sys/types.h>
 
53
#endif
 
54
#ifdef HAVE_SYS_TIME_H
 
55
#include <sys/time.h>
 
56
#endif
 
57
 
 
58
#ifdef HAVE_MEMORY_H
 
59
#include <memory.h>
 
60
#endif
 
61
#ifdef HAVE_STRING_H
 
62
#include <string.h>
 
63
#endif
 
64
#ifdef HAVE_UNISTD_H
 
65
#include <unistd.h>
 
66
#endif
 
67
 
 
68
#include <X11/Xatom.h>
 
69
#include <X11/Xlib.h>
 
70
#include <X11/Xutil.h>
 
71
 
 
72
#include <gdk/gdkx.h>
 
73
 
 
74
#include <libxfcegui4/libxfcegui4.h>
 
75
 
 
76
#include <libxfsm/xfsm-util.h>
 
77
 
 
78
 
 
79
#ifdef LEGACY_SESSION_MANAGEMENT
 
80
 
 
81
#define WM_SAVE_YOURSELF_TIMEOUT  4000
 
82
 
 
83
enum
 
84
{
 
85
  SM_ERROR,
 
86
  SM_WMCOMMAND,
 
87
  SM_WMSAVEYOURSELF,
 
88
};
 
89
 
 
90
 
 
91
typedef struct _SmWindow SmWindow;
 
92
struct _SmWindow
 
93
{
 
94
  gint    type;
 
95
  gchar **wm_command;
 
96
  gchar  *wm_client_machine;
 
97
  gchar  *wm_class1;
 
98
  gchar  *wm_class2;
 
99
  Window  wid;
 
100
  gint    screen_num;
 
101
};
 
102
#define SM_WINDOW(window) ((SmWindow *) (window))
 
103
 
 
104
typedef struct
 
105
{
 
106
  gint screen_num;
 
107
  gchar **command;
 
108
} SmRestartApp;
 
109
#define SM_RESTART_APP(a) ((SmRestartApp *) (a))
 
110
 
 
111
 
 
112
static GList *restart_apps = NULL;
 
113
static GList *window_list = NULL;
 
114
 
 
115
 
 
116
/* X Atoms */
 
117
static Atom _XA_WM_PROTOCOLS     = None;
 
118
static Atom _XA_WM_SAVE_YOURSELF = None;
 
119
static Atom _XA_WM_CLIENT_LEADER = None;
 
120
static Atom _XA_SM_CLIENT_ID     = None;
 
121
 
 
122
 
 
123
static SmWindow*
 
124
sm_window_new (Window wid, gint screen_num, gint type,
 
125
               gchar *wm_class1, gchar *wm_class2)
 
126
{
 
127
  SmWindow *smw;
 
128
 
 
129
  smw = g_new0 (SmWindow, 1);
 
130
  smw->wid = wid;
 
131
  smw->type = type;
 
132
  smw->wm_class1 = wm_class1;
 
133
  smw->wm_class2 = wm_class2;
 
134
  smw->screen_num = screen_num;
 
135
 
 
136
  return smw;
 
137
}
 
138
 
 
139
 
 
140
static void
 
141
sm_window_free (SmWindow *window)
 
142
{
 
143
  g_return_if_fail (window != NULL);
 
144
 
 
145
  if (window->wm_command != NULL)
 
146
    g_strfreev (window->wm_command);
 
147
  if (window->wm_client_machine != NULL)
 
148
    g_free (window->wm_client_machine);
 
149
  if (window->wm_class1)
 
150
    g_free (window->wm_class1);
 
151
  if (window->wm_class2)
 
152
    g_free (window->wm_class2);
 
153
  g_free (window);
 
154
}
 
155
 
 
156
 
 
157
static void
 
158
sm_window_list_clear (void)
 
159
{
 
160
  GList *lp;
 
161
 
 
162
  for (lp = window_list; lp != NULL; lp = lp->next)
 
163
    sm_window_free (SM_WINDOW (lp->data));
 
164
 
 
165
  g_list_free (window_list);
 
166
  window_list = NULL;
 
167
}
 
168
 
 
169
 
 
170
static gboolean
 
171
sm_window_list_contains (Window window)
 
172
{
 
173
  GList *lp;
 
174
 
 
175
  for (lp = window_list; lp != NULL; lp = lp->next)
 
176
    if (SM_WINDOW (lp->data)->wid == window)
 
177
      return TRUE;
 
178
 
 
179
  return FALSE;
 
180
}
 
181
 
 
182
 
 
183
static int
 
184
wins_error_handler (Display *display, XErrorEvent *event)
 
185
{
 
186
  GList *lp;
 
187
  for (lp = window_list; lp != NULL; lp = lp->next)
 
188
    if (SM_WINDOW (lp->data)->wid == event->resourceid)
 
189
      SM_WINDOW (lp->data)->type = SM_ERROR;
 
190
  return 0;
 
191
}
 
192
 
 
193
 
 
194
static gboolean
 
195
has_xsmp_support (Window window)
 
196
{
 
197
  XTextProperty tp;
 
198
  gboolean has_it = FALSE;
 
199
 
 
200
  if (XGetTextProperty (gdk_display, window, &tp, _XA_SM_CLIENT_ID))
 
201
    {
 
202
      if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0)
 
203
        has_it = TRUE;
 
204
 
 
205
      if (tp.value != NULL)
 
206
        XFree ((char *) tp.value);
 
207
    }
 
208
 
 
209
  return has_it;
 
210
}
 
211
 
 
212
 
 
213
static gchar**
 
214
get_wmcommand (Window window)
 
215
{
 
216
  gchar **result = NULL;
 
217
  Status status;
 
218
  char **argv;
 
219
  int argc, i;
 
220
 
 
221
  gdk_error_trap_push ();
 
222
  status = XGetCommand (gdk_display, window, &argv, &argc);
 
223
  if (gdk_error_trap_pop ())
 
224
    return NULL;
 
225
 
 
226
  if (status && argv && argc > 0)
 
227
    {
 
228
      result = g_new0 (gchar *, argc + 1);
 
229
      for (i = 0; i < argc; ++i)
 
230
        result[i] = g_strdup (argv[i]);
 
231
      XFreeStringList (argv);
 
232
    }
 
233
 
 
234
  return result;
 
235
}
 
236
 
 
237
 
 
238
static gchar*
 
239
get_wmclientmachine (Window window)
 
240
{
 
241
  XTextProperty tp;
 
242
  gchar *result = NULL;
 
243
  Status status;
 
244
 
 
245
  gdk_error_trap_push ();
 
246
  status = XGetWMClientMachine (gdk_display, window, &tp);
 
247
  if (gdk_error_trap_pop ())
 
248
    return NULL;
 
249
  
 
250
  if (status)
 
251
    {
 
252
      if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0)
 
253
        result = g_strdup ((char *) tp.value);
 
254
 
 
255
      if (tp.value != NULL)
 
256
        XFree ((char *) tp.value);
 
257
    }
 
258
 
 
259
  if (result == NULL)
 
260
    result = g_strdup ("localhost");
 
261
 
 
262
  return result;
 
263
}
 
264
 
 
265
static Window
 
266
get_clientleader (Window window)
 
267
{
 
268
  Atom type;
 
269
  int format, status;
 
270
  unsigned long nitems = 0;
 
271
  unsigned long extra = 0;
 
272
  unsigned char *data = 0;
 
273
  Window result = window;
 
274
 
 
275
  status = XGetWindowProperty (gdk_display, window, _XA_WM_CLIENT_LEADER,
 
276
                               0, 10000, FALSE, XA_WINDOW, &type, &format,
 
277
                               &nitems, &extra, &data);
 
278
  if (status  == Success)
 
279
    {
 
280
      if (data != NULL && nitems > 0)
 
281
          result = *((Window *) data);
 
282
      XFree(data);
 
283
    }
 
284
 
 
285
  return result;
 
286
}
 
287
 
 
288
#endif
 
289
 
 
290
 
 
291
void
 
292
xfsm_legacy_perform_session_save (void)
 
293
{
 
294
#ifdef LEGACY_SESSION_MANAGEMENT
 
295
  XErrorHandler old_handler;
 
296
  NetkScreen *screen;
 
297
  GList *windows;
 
298
  GList *lp;
 
299
  Window leader;
 
300
  Display *display;
 
301
  Atom *protocols;
 
302
  int nprotocols;
 
303
  XClassHint class_hint;
 
304
  SmWindow *sm_window;
 
305
  int n, i;
 
306
  int type;
 
307
  gchar *wmclass1;
 
308
  gchar *wmclass2;
 
309
  Window root, window;
 
310
  XEvent ev;
 
311
  int awaiting_replies = 0;
 
312
  GTimer *timer;
 
313
 
 
314
  /* clear window list */
 
315
  sm_window_list_clear ();
 
316
 
 
317
  /* query X atoms */
 
318
  if (_XA_WM_SAVE_YOURSELF == None)
 
319
    {
 
320
      _XA_SM_CLIENT_ID = XInternAtom (gdk_display, "SM_CLIENT_ID", False);
 
321
      _XA_WM_PROTOCOLS = XInternAtom (gdk_display, "WM_PROTOCOLS", False);
 
322
      _XA_WM_SAVE_YOURSELF = XInternAtom (gdk_display, "WM_SAVE_YOURSELF",
 
323
                                          False);
 
324
      _XA_WM_CLIENT_LEADER = XInternAtom (gdk_display, "WM_CLIENT_LEADER",
 
325
                                          False);
 
326
    }
 
327
 
 
328
  /* install custom X error handler */
 
329
  old_handler = XSetErrorHandler (wins_error_handler);
 
330
 
 
331
  /* query mapped windows on all screens */
 
332
  for (n = 0; n < ScreenCount (gdk_display); ++n)
 
333
    {
 
334
      screen = netk_screen_get (n);
 
335
      netk_screen_force_update (screen);
 
336
 
 
337
      windows = netk_screen_get_windows (screen);
 
338
 
 
339
      for (lp = windows; lp != NULL; lp = lp->next)
 
340
        {
 
341
          window = netk_window_get_xid (NETK_WINDOW (lp->data));
 
342
          leader = get_clientleader (window);
 
343
          if (leader == None || sm_window_list_contains (leader)
 
344
              || has_xsmp_support (window) || has_xsmp_support (leader))
 
345
            continue;
 
346
 
 
347
          type = SM_WMCOMMAND;
 
348
          wmclass1 = NULL;
 
349
          wmclass2 = NULL;
 
350
 
 
351
          nprotocols = 0;
 
352
          protocols = NULL;
 
353
 
 
354
          if (XGetWMProtocols (gdk_display, leader, &protocols, &nprotocols))
 
355
            {
 
356
              for (i = 0; i < nprotocols; ++i)
 
357
                if (protocols[i] == _XA_WM_SAVE_YOURSELF)
 
358
                  {
 
359
                    type = SM_WMSAVEYOURSELF;
 
360
                    break;
 
361
                  }
 
362
              XFree ((void *) protocols);
 
363
            }
 
364
 
 
365
          if (XGetClassHint (gdk_display, leader, &class_hint))
 
366
            {
 
367
              wmclass2 = g_strdup (class_hint.res_class);
 
368
              wmclass1 = g_strdup (class_hint.res_name);
 
369
              XFree (class_hint.res_class);
 
370
              XFree (class_hint.res_name);
 
371
            }
 
372
 
 
373
          sm_window = sm_window_new (leader, n, type, wmclass1, wmclass2);
 
374
          window_list = g_list_append (window_list, sm_window);
 
375
        }
 
376
    }
 
377
 
 
378
  /* open fresh display for sending WM_SAVE_YOURSELF commands */
 
379
  XSync (gdk_display, False);
 
380
  display = XOpenDisplay (DisplayString (gdk_display));
 
381
  if (display == NULL)
 
382
    {
 
383
      XSetErrorHandler (old_handler);
 
384
      return;
 
385
    }
 
386
 
 
387
  /* grab keyboard/pointer (XXX - check pointer pos first?) */
 
388
  root = DefaultRootWindow (display);
 
389
  XGrabKeyboard (display, root, False, GrabModeAsync, GrabModeAsync,
 
390
                 CurrentTime);
 
391
  XGrabPointer (display, root, False, Button1Mask | Button2Mask | Button3Mask,
 
392
                GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
 
393
  for (lp = window_list; lp != NULL; lp = lp->next)
 
394
    {
 
395
      sm_window = SM_WINDOW (lp->data);
 
396
      if (sm_window->type == SM_WMSAVEYOURSELF)
 
397
        {
 
398
          ++awaiting_replies;
 
399
 
 
400
          bzero (&ev, sizeof (ev));
 
401
 
 
402
          ev.xclient.type = ClientMessage;
 
403
          ev.xclient.window = sm_window->wid;
 
404
          ev.xclient.message_type = _XA_WM_PROTOCOLS;
 
405
          ev.xclient.format = 32;
 
406
          ev.xclient.data.l[0] = _XA_WM_SAVE_YOURSELF;
 
407
          ev.xclient.data.l[1] = CurrentTime;
 
408
          XSelectInput (display, sm_window->wid,
 
409
                        PropertyChangeMask | StructureNotifyMask);
 
410
          XSendEvent (display, sm_window->wid, False, 0, &ev);
 
411
        }
 
412
    }
 
413
 
 
414
  /* wait for change in WM_COMMAND with timeout */
 
415
  XFlush (display);
 
416
  timer = g_timer_new ();
 
417
  while (awaiting_replies > 0)
 
418
    {
 
419
      if (XPending (display))
 
420
        {
 
421
          XNextEvent (display, &ev);
 
422
          if (ev.type == UnmapNotify || (ev.type == PropertyNotify
 
423
                && ev.xproperty.atom == XA_WM_COMMAND))
 
424
            {
 
425
              for (lp = window_list; lp != NULL; lp = lp->next)
 
426
                {
 
427
                  if (SM_WINDOW (lp->data)->wid == ev.xany.window
 
428
                      && SM_WINDOW (lp->data)->type != SM_WMCOMMAND)
 
429
                    {
 
430
                      --awaiting_replies;
 
431
                      if (SM_WINDOW (lp->data)->type != SM_ERROR)
 
432
                        SM_WINDOW (lp->data)->type = SM_WMCOMMAND;
 
433
                    }
 
434
                }
 
435
            }
 
436
        }
 
437
      else
 
438
        {
 
439
          struct timeval tv;
 
440
          fd_set fds;
 
441
          int msecs;
 
442
          int fd;
 
443
 
 
444
          msecs = (int)(g_timer_elapsed (timer, NULL) * 1000);
 
445
          if (msecs >= WM_SAVE_YOURSELF_TIMEOUT)
 
446
            break;
 
447
 
 
448
          fd = ConnectionNumber (display);
 
449
          FD_ZERO (&fds);
 
450
          FD_SET (fd, &fds);
 
451
          tv.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000;
 
452
          tv.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000;
 
453
          select (fd + 1, &fds, NULL, &fds, &tv);
 
454
        }
 
455
    }
 
456
  g_timer_destroy (timer);
 
457
 
 
458
  /* Terminate work in new display */
 
459
  XAllowEvents (display, ReplayPointer, CurrentTime);
 
460
  XAllowEvents (display, ReplayKeyboard, CurrentTime);
 
461
  XSync (display, False);
 
462
  XCloseDisplay (display);
 
463
  XSetErrorHandler (old_handler);
 
464
 
 
465
  for (lp = window_list; lp != NULL; lp = lp->next)
 
466
    {
 
467
      sm_window = SM_WINDOW (lp->data);
 
468
      if (sm_window->type != SM_ERROR)
 
469
        {
 
470
          sm_window->wm_command = get_wmcommand (sm_window->wid);
 
471
          sm_window->wm_client_machine = get_wmclientmachine (sm_window->wid);
 
472
          if (sm_window->wm_command == NULL || sm_window->wm_client_machine == NULL)
 
473
            sm_window->type = SM_ERROR;
 
474
        }
 
475
    }
 
476
#endif
 
477
}
 
478
 
 
479
 
 
480
void
 
481
xfsm_legacy_store_session (XfceRc *rc)
 
482
{
 
483
#ifdef LEGACY_SESSION_MANAGEMENT
 
484
  int count = 0;
 
485
  SmWindow *sm_window;
 
486
  GList *lp;
 
487
  gchar buffer[256];
 
488
 
 
489
  for (lp = window_list; lp != NULL; lp = lp->next)
 
490
    {
 
491
      sm_window = SM_WINDOW (lp->data);
 
492
      if (sm_window->type != SM_ERROR)
 
493
        {
 
494
          /* xmms is b0rked, surprise, surprise */
 
495
          if ((sm_window->wm_class1 != NULL
 
496
                && strcmp (sm_window->wm_class1, "xmms") == 0)
 
497
              || (sm_window->wm_class2 != NULL
 
498
                && strcmp (sm_window->wm_class2, "xmms") == 0))
 
499
            continue;
 
500
 
 
501
          if (sm_window->wm_command == NULL
 
502
              || sm_window->wm_client_machine == NULL)
 
503
            continue;
 
504
 
 
505
          g_snprintf (buffer, 256, "Legacy%d_Screen", count);
 
506
          xfce_rc_write_int_entry (rc, buffer, sm_window->screen_num);
 
507
 
 
508
          g_snprintf (buffer, 256, "Legacy%d_Command", count);
 
509
          xfce_rc_write_list_entry (rc, buffer, sm_window->wm_command, NULL);
 
510
 
 
511
          g_snprintf (buffer, 256, "Legacy%d_ClientMachine", count);
 
512
          xfce_rc_write_entry (rc, buffer, sm_window->wm_client_machine);
 
513
 
 
514
          ++count;
 
515
        }
 
516
    }
 
517
 
 
518
  xfce_rc_write_int_entry (rc, "LegacyCount", count);
 
519
#endif
 
520
}
 
521
 
 
522
 
 
523
void
 
524
xfsm_legacy_load_session (XfceRc *rc)
 
525
{
 
526
#ifdef LEGACY_SESSION_MANAGEMENT
 
527
  gchar buffer[256];
 
528
  int count;
 
529
  int i;
 
530
  gchar **command;
 
531
  SmRestartApp *app;
 
532
  int screen_num;
 
533
 
 
534
  count = xfce_rc_read_int_entry (rc, "LegacyCount", 0);
 
535
  for (i = 0; i < count; ++i)
 
536
    {
 
537
      g_snprintf (buffer, 256, "Legacy%d_Screen", i);
 
538
      screen_num = xfce_rc_read_int_entry (rc, buffer, 0);
 
539
 
 
540
      g_snprintf (buffer, 256, "Legacy%d_Command", i);
 
541
      command = xfce_rc_read_list_entry (rc, buffer, NULL);
 
542
      if (command == NULL)
 
543
        continue;
 
544
 
 
545
      app = g_new0 (SmRestartApp, 1);
 
546
      app->screen_num = screen_num;
 
547
      app->command = command;
 
548
 
 
549
      restart_apps = g_list_append (restart_apps, app);
 
550
    }
 
551
#endif
 
552
}
 
553
 
 
554
 
 
555
void
 
556
xfsm_legacy_init (void)
 
557
{
 
558
#ifdef LEGACY_SESSION_MANAGEMENT
 
559
  Atom dt_save_mode;
 
560
  Atom dt_restore_mode;
 
561
  Display *dpy;
 
562
  Window root;
 
563
  int n;
 
564
 
 
565
  dpy = gdk_display;
 
566
 
 
567
  /* Some CDE apps are broken (thanks again to Craig for the Sun Box :).
 
568
   * Bugfix found on http://bugzilla.gnome.org/long_list.cgi?buglist=81343
 
569
   * and implemented in gnome-session. The following code extends what
 
570
   * gnome does, since it seems to be necessary to set both properties
 
571
   * per screen, not just for the first screen. Anybody with access to
 
572
   * CDE source code to enlighten me?
 
573
   *                                          -- bm, 20040530
 
574
   */
 
575
  dt_save_mode = XInternAtom (dpy, "_DT_SAVE_MODE", False);
 
576
  dt_restore_mode = XInternAtom (dpy, "_DT_RESTORE_MODE", False);
 
577
  for (n = 0; n < ScreenCount (dpy); ++n)
 
578
    {
 
579
      root = RootWindow (dpy, n);
 
580
      XChangeProperty (dpy, root, dt_save_mode, XA_STRING, 8,
 
581
                       PropModeReplace, "xfce4", sizeof ("xfce4"));
 
582
      XChangeProperty (dpy, root, dt_restore_mode, XA_STRING, 8,
 
583
                       PropModeReplace, "xfce4", sizeof ("xfce4"));
 
584
    }
 
585
#endif
 
586
}
 
587
 
 
588
 
 
589
void
 
590
xfsm_legacy_startup (void)
 
591
{
 
592
#ifdef LEGACY_SESSION_MANAGEMENT
 
593
  GdkScreen *screen;
 
594
  GList *lp;
 
595
 
 
596
  for (lp = restart_apps; lp != NULL; lp = lp->next)
 
597
    {
 
598
      screen = gdk_display_get_screen (gdk_display_get_default (),
 
599
                                       SM_RESTART_APP (lp->data)->screen_num);
 
600
      xfsm_start_application (SM_RESTART_APP (lp->data)->command, NULL,
 
601
                              screen, NULL, NULL, NULL);
 
602
      g_strfreev (SM_RESTART_APP (lp->data)->command);
 
603
      g_free (lp->data);
 
604
    }
 
605
 
 
606
  g_list_free (restart_apps);
 
607
  restart_apps = NULL;
 
608
#endif
 
609
}
 
610
 
 
611
 
 
612
void
 
613
xfsm_legacy_shutdown (void)
 
614
{
 
615
#ifdef LEGACY_SESSION_MANAGEMENT
 
616
  SmWindow *sm_window;
 
617
  GList *lp;
 
618
 
 
619
  gdk_error_trap_push ();
 
620
 
 
621
  /* kill 'em all! */
 
622
  for (lp = window_list; lp != NULL; lp = lp->next)
 
623
    {
 
624
      sm_window = SM_WINDOW (lp->data);
 
625
      if (sm_window->wid != None)
 
626
        XKillClient (gdk_display, sm_window->wid);
 
627
    }
 
628
 
 
629
  sm_window_list_clear ();
 
630
 
 
631
  gdk_flush ();
 
632
 
 
633
  gdk_error_trap_pop ();
 
634
#endif
 
635
}
 
636
 
 
637
 
 
638