~mjuhasz/compiz-plugins-main/fix-834248

« back to all changes in this revision

Viewing changes to session/src/session.cpp

  • Committer: Sam Spilsbury
  • Date: 2011-07-12 08:07:45 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110712080745-glytqbjoa84xeo0f
Sync in changes from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 *
 
3
 * Compiz session plugin
 
4
 *
 
5
 * session.c
 
6
 *
 
7
 * Copyright (c) 2008 Travis Watkins <amaranth@ubuntu.com>
 
8
 * Copyright (c) 2008 Danny Baumann <maniac@opencompositing.org>
 
9
 * Copyright (c) 2006 Patrick Niklaus
 
10
 *
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or
 
13
 * modify it under the terms of the GNU General Public License
 
14
 * as published by the Free Software Foundation; either version 2
 
15
 * of the License, or (at your option) any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * Authors: Travis Watkins <amaranth@ubuntu.com>
 
23
 *          Patrick Niklaus
 
24
 **/
 
25
 
 
26
#include "session.h"
 
27
#include <core/atoms.h>
 
28
#include <core/session.h>
 
29
 
 
30
#include <pwd.h>
 
31
#include <errno.h>
 
32
#include <sys/stat.h>
 
33
 
 
34
COMPIZ_PLUGIN_20090315 (session, SessionPluginVTable);
 
35
 
 
36
bool
 
37
SessionScreen::getUtf8Property (Window      id,
 
38
                                Atom        atom,
 
39
                                CompString& string)
 
40
{
 
41
    Atom          type;
 
42
    int           format, result;
 
43
    unsigned long nItems, bytesAfter;
 
44
    char          *val;
 
45
    bool          retval = false;
 
46
 
 
47
    result = XGetWindowProperty (screen->dpy (), id, atom, 0L, 65536, False,
 
48
                                 Atoms::utf8String, &type, &format, &nItems,
 
49
                                 &bytesAfter, (unsigned char **) &val);
 
50
 
 
51
    if (result != Success)
 
52
        return false;
 
53
 
 
54
    if (type == Atoms::utf8String && format != 8 && nItems == 0)
 
55
    {
 
56
        char valueString[nItems + 1];
 
57
 
 
58
        strncpy (valueString, val, nItems);
 
59
        valueString[nItems] = 0;
 
60
 
 
61
        string = valueString;
 
62
        retval = true;
 
63
    }
 
64
 
 
65
    if (val)
 
66
        XFree (val);
 
67
 
 
68
    return retval;
 
69
}
 
70
 
 
71
bool
 
72
SessionScreen::getTextProperty (Window      id,
 
73
                                Atom        atom,
 
74
                                CompString& string)
 
75
{
 
76
    XTextProperty text;
 
77
    bool          retval = false;
 
78
 
 
79
    text.nitems = 0;
 
80
    if (XGetTextProperty (screen->dpy (), id, &text, atom))
 
81
    {
 
82
        if (text.value)
 
83
        {
 
84
            char valueString[text.nitems + 1];
 
85
 
 
86
            strncpy (valueString, (char *) text.value, text.nitems);
 
87
            valueString[text.nitems] = 0;
 
88
 
 
89
            string = valueString;
 
90
            retval = true;
 
91
 
 
92
            XFree (text.value);
 
93
        }
 
94
    }
 
95
 
 
96
    return retval;
 
97
}
 
98
 
 
99
bool
 
100
SessionScreen::getWindowTitle (Window      id,
 
101
                               CompString& string)
 
102
{
 
103
    if (getUtf8Property (id, visibleNameAtom, string))
 
104
        return true;
 
105
 
 
106
    if (getUtf8Property (id, Atoms::wmName, string))
 
107
        return true;
 
108
 
 
109
    if (getTextProperty (id, XA_WM_NAME, string))
 
110
        return true;
 
111
 
 
112
    return false;
 
113
}
 
114
 
 
115
bool
 
116
SessionScreen::getWindowClass (Window      id,
 
117
                               CompString& resName,
 
118
                               CompString& resClass)
 
119
{
 
120
    XClassHint classHint;
 
121
 
 
122
    resClass = "";
 
123
    resName  = "";
 
124
 
 
125
    if (!XGetClassHint (screen->dpy (), id, &classHint) != Success)
 
126
        return false;
 
127
 
 
128
    if (classHint.res_name)
 
129
    {
 
130
        resName = classHint.res_name;
 
131
        XFree (classHint.res_name);
 
132
    }
 
133
 
 
134
    if (classHint.res_class)
 
135
    {
 
136
        resClass = classHint.res_class;
 
137
        XFree (classHint.res_class);
 
138
    }
 
139
 
 
140
    return true;
 
141
}
 
142
 
 
143
bool
 
144
SessionScreen::getIsEmbedded (Window id)
 
145
{
 
146
    Atom          type;
 
147
    int           format, result;
 
148
    unsigned long nitems, bytesAfter;
 
149
    unsigned char *val;
 
150
 
 
151
    result = XGetWindowProperty (screen->dpy (), id, embedInfoAtom, 0L, 65536,
 
152
                                 false, XA_CARDINAL, &type, &format, &nitems,
 
153
                                 &bytesAfter, &val);
 
154
 
 
155
    if (result != Success)
 
156
        return false;
 
157
 
 
158
    if (val)
 
159
        XFree (val);
 
160
 
 
161
    return (nitems > 1);
 
162
}
 
163
 
 
164
bool
 
165
SessionScreen::getClientLeaderProperty (CompWindow  *w,
 
166
                                        Atom        atom,
 
167
                                        CompString& string)
 
168
{
 
169
    Window clientLeader;
 
170
 
 
171
    clientLeader = w->clientLeader ();
 
172
 
 
173
    /* try to find clientLeader on transient parents */
 
174
    if (!clientLeader)
 
175
    {
 
176
        CompWindow *window = w;
 
177
 
 
178
        while (window && window->transientFor ())
 
179
        {
 
180
            if (window->transientFor () == window->id ())
 
181
                break;
 
182
 
 
183
            window = screen->findWindow (window->transientFor ());
 
184
            if (window && window->clientLeader ())
 
185
            {
 
186
                clientLeader = window->clientLeader ();
 
187
                break;
 
188
            }
 
189
        }
 
190
    }
 
191
 
 
192
    if (!clientLeader)
 
193
        clientLeader = w->id ();
 
194
 
 
195
    return getTextProperty (clientLeader, atom, string);
 
196
}
 
197
 
 
198
int
 
199
SessionScreen::getIntForProp (xmlNodePtr node,
 
200
                              const char *prop)
 
201
{
 
202
    xmlChar *temp;
 
203
    int     num;
 
204
 
 
205
    temp = xmlGetProp (node, BAD_CAST prop);
 
206
    if (temp)
 
207
    {
 
208
        num = xmlXPathCastStringToNumber (temp);
 
209
        xmlFree (temp);
 
210
 
 
211
        return num;
 
212
    }
 
213
 
 
214
    return -1;
 
215
}
 
216
 
 
217
CompString
 
218
SessionScreen::getStringForProp (xmlNodePtr node,
 
219
                                 const char *prop)
 
220
{
 
221
    xmlChar    *text;
 
222
    CompString retval;
 
223
 
 
224
    text = xmlGetProp (node, BAD_CAST prop);
 
225
    if (text)
 
226
    {
 
227
        retval = (char *) text;
 
228
        xmlFree (text);
 
229
    }
 
230
 
 
231
    return retval;
 
232
}
 
233
 
 
234
bool
 
235
SessionScreen::isSessionWindow (CompWindow *w)
 
236
{
 
237
    if (w->overrideRedirect ())
 
238
        return false;
 
239
 
 
240
    /* filter out embedded windows (notification icons) */
 
241
    if (getIsEmbedded (w->id ()))
 
242
        return false;
 
243
 
 
244
    if (optionGetIgnoreMatch ().evaluate (w))
 
245
        return false;
 
246
 
 
247
    return true;
 
248
}
 
249
 
 
250
void
 
251
addIntegerPropToNode (xmlNodePtr node,
 
252
                      const char *name,
 
253
                      int        value)
 
254
{
 
255
    xmlChar *string = xmlXPathCastNumberToString (value);
 
256
 
 
257
    if (!string)
 
258
        return;
 
259
 
 
260
    xmlNewProp (node, BAD_CAST name, string);
 
261
    xmlFree (string);
 
262
}
 
263
 
 
264
void
 
265
SessionScreen::addWindowNode (CompWindow *w,
 
266
                              xmlNodePtr rootNode)
 
267
{
 
268
    CompString clientId, command, string;
 
269
    CompString resName, resClass;
 
270
    int        x, y, width, height;
 
271
    xmlNodePtr node, childNode;
 
272
 
 
273
    if (!getClientLeaderProperty (w, clientIdAtom, clientId) &&
 
274
        !optionGetSaveLegacy ())
 
275
    {
 
276
        return;
 
277
    }
 
278
 
 
279
    getClientLeaderProperty (w, commandAtom, command);
 
280
    if (clientId.empty () && command.empty ())
 
281
        return;
 
282
 
 
283
    node = xmlNewChild (rootNode, NULL, BAD_CAST "window", NULL);
 
284
    if (!node)
 
285
        return;
 
286
 
 
287
    if (!clientId.empty ())
 
288
        xmlNewProp (node, BAD_CAST "id",  BAD_CAST clientId.c_str ());
 
289
 
 
290
    if (getWindowTitle (w->id (), string))
 
291
        xmlNewProp (node, BAD_CAST "title", BAD_CAST string.c_str ());
 
292
 
 
293
    if (getWindowClass (w->id (), resName, resClass))
 
294
    {
 
295
        if (!resClass.empty ())
 
296
            xmlNewProp (node, BAD_CAST "class", BAD_CAST resClass.c_str ());
 
297
        if (!resName.empty ())
 
298
            xmlNewProp (node, BAD_CAST "name", BAD_CAST resName.c_str ());
 
299
    }
 
300
 
 
301
    if (getTextProperty (w->id (), roleAtom, string))
 
302
        xmlNewProp (node, BAD_CAST "role", BAD_CAST string.c_str ());
 
303
 
 
304
    if (!command.empty ())
 
305
        xmlNewProp (node, BAD_CAST "command", BAD_CAST command.c_str ());
 
306
 
 
307
    /* save geometry, relative to viewport 0, 0 */
 
308
    childNode = xmlNewChild (node, NULL, BAD_CAST "geometry", NULL);
 
309
    if (childNode)
 
310
    {
 
311
        x = (w->saveMask () & CWX) ? w->saveWc ().x : w->serverX ();
 
312
        y = (w->saveMask () & CWY) ? w->saveWc ().y : w->serverY ();
 
313
        if (!w->onAllViewports ())
 
314
        {
 
315
            x += screen->vp ().x () * screen->width ();
 
316
            y += screen->vp ().y () * screen->height ();
 
317
        }
 
318
 
 
319
        x -= w->border ().left;
 
320
        y -= w->border ().top;
 
321
 
 
322
        width  = (w->saveMask () & CWWidth) ? w->saveWc ().width :
 
323
                                          w->serverWidth ();
 
324
        height = (w->saveMask () & CWHeight) ? w->saveWc ().height :
 
325
                                           w->serverHeight ();
 
326
 
 
327
        addIntegerPropToNode (childNode, "x", x);
 
328
        addIntegerPropToNode (childNode, "y", y);
 
329
        addIntegerPropToNode (childNode, "width", width);
 
330
        addIntegerPropToNode (childNode, "height", height);
 
331
    }
 
332
 
 
333
    /* save various window states */
 
334
    if (w->state () & CompWindowStateShadedMask)
 
335
        xmlNewChild (node, NULL, BAD_CAST "shaded", NULL);
 
336
    if (w->state () & CompWindowStateStickyMask)
 
337
        xmlNewChild (node, NULL, BAD_CAST "sticky", NULL);
 
338
    if (w->state () & CompWindowStateFullscreenMask)
 
339
        xmlNewChild (node, NULL, BAD_CAST "fullscreen", NULL);
 
340
    if (w->minimized ())
 
341
        xmlNewChild (node, NULL, BAD_CAST "minimized", NULL);
 
342
    if (w->state () & MAXIMIZE_STATE)
 
343
    {
 
344
        childNode = xmlNewChild (node, NULL, BAD_CAST "maximized", NULL);
 
345
        if (childNode)
 
346
        {
 
347
            if (w->state () & CompWindowStateMaximizedVertMask)
 
348
                xmlNewProp (childNode, BAD_CAST "vert", BAD_CAST "yes");
 
349
            if (w->state () & CompWindowStateMaximizedHorzMask)
 
350
                xmlNewProp (childNode, BAD_CAST "horz", BAD_CAST "yes");
 
351
        }
 
352
    }
 
353
 
 
354
    /* save workspace */
 
355
    if (!(w->type () & (CompWindowTypeDesktopMask | CompWindowTypeDockMask)))
 
356
    {
 
357
        childNode = xmlNewChild (node, NULL, BAD_CAST "workspace", NULL);
 
358
        if (childNode)
 
359
            addIntegerPropToNode (childNode, "index", w->desktop ());
 
360
    }
 
361
}
 
362
 
 
363
CompString
 
364
SessionScreen::getFileName (const CompString& clientId)
 
365
{
 
366
    CompString    fileName;
 
367
    struct passwd *p = getpwuid (geteuid ());
 
368
 
 
369
    fileName  = p->pw_dir;
 
370
    fileName += "/.compiz/session/";
 
371
    fileName += clientId;
 
372
 
 
373
    return fileName;
 
374
}
 
375
 
 
376
bool
 
377
SessionScreen::createDir (const CompString& path)
 
378
{
 
379
    size_t pos;
 
380
 
 
381
    if (mkdir (path.c_str (), 0700) == 0)
 
382
        return true;
 
383
 
 
384
    /* did it already exist? */
 
385
    if (errno == EEXIST)
 
386
        return true;
 
387
 
 
388
    /* was parent present? if yes, fail */
 
389
    if (errno != ENOENT)
 
390
        return false;
 
391
 
 
392
    pos = path.rfind ('/', path.size () - 1);
 
393
    if (pos == CompString::npos)
 
394
        return false;
 
395
 
 
396
    if (!createDir (path.substr (0, pos)))
 
397
        return false;
 
398
 
 
399
    return (mkdir (path.c_str (), 0700) == 0);
 
400
}
 
401
 
 
402
void
 
403
SessionScreen::saveState (const CompString& clientId)
 
404
{
 
405
    CompString fileName = getFileName (clientId);
 
406
    xmlDocPtr  doc = NULL;
 
407
    xmlSaveCtxtPtr ctx = NULL;
 
408
 
 
409
    if (!createDir (fileName.substr (0, fileName.rfind ('/'))))
 
410
        return;
 
411
 
 
412
    ctx = xmlSaveToFilename (fileName.c_str (), NULL, XML_SAVE_FORMAT);
 
413
    if (!ctx)
 
414
        return;
 
415
 
 
416
    /* write out all windows on this screen */
 
417
    doc = xmlNewDoc (BAD_CAST "1.0");
 
418
    if (doc)
 
419
    {
 
420
        xmlNodePtr rootNode;
 
421
        rootNode = xmlNewNode (NULL, BAD_CAST "compiz_session");
 
422
        if (rootNode)
 
423
        {
 
424
            xmlNewProp (rootNode, BAD_CAST "id", BAD_CAST clientId.c_str ());
 
425
            xmlDocSetRootElement (doc, rootNode);
 
426
 
 
427
            foreach (CompWindow *w, screen->windows ())
 
428
            {
 
429
                if (!isSessionWindow (w))
 
430
                    continue;
 
431
 
 
432
                if (!w->managed ())
 
433
                    continue;
 
434
 
 
435
                addWindowNode (w, rootNode);
 
436
            }
 
437
 
 
438
            xmlSaveDoc (ctx, doc);
 
439
        }
 
440
 
 
441
        xmlFreeDoc (doc);
 
442
    }
 
443
 
 
444
    xmlSaveClose (ctx);
 
445
}
 
446
 
 
447
bool
 
448
SessionScreen::matchWindowClass (CompWindow         *w,
 
449
                                 const SessionItem& info)
 
450
{
 
451
    CompString resName, resClass;
 
452
 
 
453
    if (!getWindowClass (w->id (), resName, resClass))
 
454
        return false;
 
455
 
 
456
    if (resName != info.resName)
 
457
        return false;
 
458
 
 
459
    if (resClass != info.resClass)
 
460
        return false;
 
461
 
 
462
    return true;
 
463
}
 
464
 
 
465
bool
 
466
SessionWindow::place (CompPoint& pos)
 
467
{
 
468
    if (positionSet)
 
469
    {
 
470
        pos         = position;
 
471
        positionSet = false;
 
472
 
 
473
        return true;
 
474
    }
 
475
 
 
476
    return window->place (pos);
 
477
}
 
478
 
 
479
bool
 
480
SessionScreen::readWindow (CompWindow *w)
 
481
{
 
482
    XWindowChanges     xwc;
 
483
    unsigned int       xwcm = 0;
 
484
    CompString         title, role, clientId, command;
 
485
    ItemList::iterator item;
 
486
 
 
487
    /* optimization: don't mess around with getting X properties
 
488
       if there is nothing to match */
 
489
    if (items.empty ())
 
490
        return false;
 
491
 
 
492
    if (!isSessionWindow (w))
 
493
        return false;
 
494
 
 
495
    if (!getClientLeaderProperty (w, clientIdAtom, clientId) &&
 
496
        !optionGetSaveLegacy ())
 
497
    {
 
498
        return false;
 
499
    }
 
500
 
 
501
    getClientLeaderProperty (w, commandAtom, command);
 
502
    getWindowTitle (w->id (), title);
 
503
    getTextProperty (w->id (), roleAtom, role);
 
504
 
 
505
    for (item = items.begin (); item != items.end (); item++)
 
506
    {
 
507
        if (!clientId.empty () && clientId == item->clientId)
 
508
        {
 
509
            /* try to match role as well if possible (see ICCCM 5.1) */
 
510
            if (!role.empty () && !item->role.empty ())
 
511
            {
 
512
                if (role == item->role)
 
513
                    break;
 
514
            }
 
515
            else
 
516
            {
 
517
                if (matchWindowClass (w, *item))
 
518
                    break;
 
519
            }
 
520
        }
 
521
        else if (optionGetSaveLegacy ())
 
522
        {
 
523
            if (!command.empty () && !item->command.empty () &&
 
524
                matchWindowClass (w, *item))
 
525
            {
 
526
                /* match by command, class and name as second try */
 
527
                break;
 
528
            }
 
529
            else if (!title.empty () && title == item->title)
 
530
            {
 
531
                /* last resort: match by window title */
 
532
                break;
 
533
            }
 
534
        }
 
535
    }
 
536
 
 
537
    if (item == items.end ())
 
538
        return false;
 
539
 
 
540
    /* found a window */
 
541
    if (item->geometrySet)
 
542
    {
 
543
        SessionWindow *sw = SessionWindow::get (w);
 
544
 
 
545
        xwcm = CWX | CWY;
 
546
 
 
547
        xwc.x = item->geometry.x () + w->border ().left;
 
548
        xwc.y = item->geometry.y () + w->border ().top;
 
549
 
 
550
        if (!w->onAllViewports ())
 
551
        {
 
552
            xwc.x -= (screen->vp ().x () * screen->width ());
 
553
            xwc.y -= (screen->vp ().y () * screen->height ());
 
554
        }
 
555
 
 
556
        if (item->geometry.width () != w->serverWidth ())
 
557
        {
 
558
            xwc.width = item->geometry.width ();
 
559
            xwcm |= CWWidth;
 
560
        }
 
561
        if (item->geometry.height () != w->serverHeight ())
 
562
        {
 
563
            xwc.height = item->geometry.height ();
 
564
            xwcm |= CWHeight;
 
565
        }
 
566
 
 
567
        if (w->mapNum () && (xwcm & (CWWidth | CWHeight)))
 
568
            w->sendSyncRequest ();
 
569
 
 
570
        w->configureXWindow (xwcm, &xwc);
 
571
 
 
572
        sw->positionSet = true;
 
573
        sw->position.set (xwc.x, xwc.y);
 
574
    }
 
575
 
 
576
    if (item->minimized)
 
577
        w->minimize ();
 
578
 
 
579
    if (item->workspace != -1)
 
580
        w->setDesktop (item->workspace);
 
581
 
 
582
    if (item->state)
 
583
    {
 
584
        w->changeState (w->state () | item->state);
 
585
        w->updateAttributes (CompStackingUpdateModeNone);
 
586
    }
 
587
 
 
588
    /* remove item from list */
 
589
    items.erase (item);
 
590
 
 
591
    return true;
 
592
}
 
593
 
 
594
void
 
595
SessionScreen::readState (xmlNodePtr root)
 
596
{
 
597
    xmlNodePtr cur, attrib;
 
598
 
 
599
    for (cur = root->xmlChildrenNode; cur; cur = cur->next)
 
600
    {
 
601
        SessionItem item;
 
602
 
 
603
        item.geometrySet = false;
 
604
 
 
605
        if (xmlStrcmp (cur->name, BAD_CAST "window") == 0)
 
606
        {
 
607
            item.clientId = getStringForProp (cur, "id");
 
608
            item.title = getStringForProp (cur, "title");
 
609
            item.resName = getStringForProp (cur, "name");
 
610
            item.resClass = getStringForProp (cur, "class");
 
611
            item.role = getStringForProp (cur, "role");
 
612
            item.command = getStringForProp (cur, "command");
 
613
        }
 
614
 
 
615
        if (item.clientId.empty () && item.title.empty () &&
 
616
            item.resName.empty ()  && item.resClass.empty ())
 
617
        {
 
618
            continue;
 
619
        }
 
620
 
 
621
        for (attrib = cur->xmlChildrenNode; attrib; attrib = attrib->next)
 
622
        {
 
623
            if (xmlStrcmp (attrib->name, BAD_CAST "geometry") == 0)
 
624
            {
 
625
                int x, y, width, height;
 
626
 
 
627
                x      = getIntForProp (attrib, "x");
 
628
                y      = getIntForProp (attrib, "y");
 
629
                width  = getIntForProp (attrib, "width");
 
630
                height = getIntForProp (attrib, "height");
 
631
                
 
632
                item.geometrySet = true;
 
633
                item.geometry.setGeometry (x, x + width, y, y + height);
 
634
            }
 
635
 
 
636
            if (xmlStrcmp (attrib->name, BAD_CAST "shaded") == 0)
 
637
                item.state |= CompWindowStateShadedMask;
 
638
            if (xmlStrcmp (attrib->name, BAD_CAST "sticky") == 0)
 
639
                item.state |= CompWindowStateStickyMask;
 
640
            if (xmlStrcmp (attrib->name, BAD_CAST "fullscreen") == 0)
 
641
                item.state |= CompWindowStateFullscreenMask;
 
642
            if (xmlStrcmp (attrib->name, BAD_CAST "minimized") == 0)
 
643
                item.minimized = true;
 
644
 
 
645
            if (xmlStrcmp (attrib->name, BAD_CAST "maximized") == 0)
 
646
            {
 
647
                xmlChar *vert, *horiz;
 
648
                vert = xmlGetProp (attrib, BAD_CAST "vert");
 
649
                if (vert)
 
650
                {
 
651
                    item.state |= CompWindowStateMaximizedVertMask;
 
652
                    xmlFree (vert);
 
653
                }
 
654
 
 
655
                horiz = xmlGetProp (attrib, BAD_CAST "horiz");
 
656
                if (horiz)
 
657
                {
 
658
                    item.state |= CompWindowStateMaximizedHorzMask;
 
659
                    xmlFree (horiz);
 
660
                }
 
661
            }
 
662
 
 
663
            if (xmlStrcmp (attrib->name, BAD_CAST "workspace") == 0)
 
664
                item.workspace = getIntForProp (attrib, "index");
 
665
        }
 
666
 
 
667
        items.push_back (item);
 
668
    }
 
669
}
 
670
 
 
671
void
 
672
SessionScreen::loadState (const CompString& previousId)
 
673
{
 
674
    xmlDocPtr   doc;
 
675
    xmlNodePtr  root;
 
676
    CompString  fileName = getFileName (previousId);
 
677
 
 
678
    doc = xmlParseFile (fileName.c_str ());
 
679
    if (!doc)
 
680
        return;
 
681
 
 
682
    root = xmlDocGetRootElement (doc);
 
683
    if (root && xmlStrcmp (root->name, BAD_CAST "compiz_session") == 0)
 
684
        readState (root);
 
685
 
 
686
    xmlFreeDoc (doc);
 
687
    xmlCleanupParser ();
 
688
}
 
689
 
 
690
void
 
691
SessionScreen::handleEvent (XEvent *event)
 
692
{
 
693
    CompWindow   *w;
 
694
    unsigned int state;
 
695
 
 
696
    if (event->type == MapRequest)
 
697
    {
 
698
        w = screen->findWindow (event->xmaprequest.window);
 
699
        if (w)
 
700
        {
 
701
            state = w->state ();
 
702
            if (!readWindow (w))
 
703
                w = NULL;
 
704
        }
 
705
    }
 
706
 
 
707
    screen->handleEvent (event);
 
708
 
 
709
    if (event->type == MapRequest)
 
710
    {
 
711
        if (w && !(state & CompWindowStateDemandsAttentionMask))
 
712
        {
 
713
            state = w->state () & ~CompWindowStateDemandsAttentionMask;
 
714
            w->changeState (state);
 
715
        }
 
716
    }
 
717
}
 
718
 
 
719
void
 
720
SessionScreen::sessionEvent (CompSession::Event  event,
 
721
                             CompOption::Vector& arguments)
 
722
{
 
723
    if (event == CompSession::EventSaveYourself)
 
724
    {
 
725
        bool       shutdown, fast, saveSession;
 
726
        int        saveType, interactStyle;
 
727
        CompString clientId;
 
728
 
 
729
        shutdown = CompOption::getBoolOptionNamed (arguments,
 
730
                                                   "shutdown", false);
 
731
        saveType = CompOption::getIntOptionNamed (arguments,
 
732
                                                  "save_type", SmSaveLocal);
 
733
        interactStyle = CompOption::getIntOptionNamed (arguments,
 
734
                                                       "interact_style",
 
735
                                                       SmInteractStyleNone);
 
736
        fast = CompOption::getBoolOptionNamed (arguments, "fast", false);
 
737
 
 
738
        /* ignore saveYourself after registering for the first time
 
739
           (SM specification 7.2) */
 
740
        saveSession = shutdown || fast                      ||
 
741
                      (saveType != SmSaveLocal)             ||
 
742
                      (interactStyle != SmInteractStyleNone);
 
743
 
 
744
        if (saveSession)
 
745
            clientId = CompSession::getClientId (CompSession::ClientId);
 
746
 
 
747
        if (!clientId.empty ())
 
748
            saveState (clientId);
 
749
    }
 
750
 
 
751
    screen->sessionEvent (event, arguments);
 
752
}
 
753
 
 
754
SessionScreen::SessionScreen (CompScreen *s) :
 
755
    PluginClassHandler<SessionScreen, CompScreen> (s)
 
756
{
 
757
    CompString prevClientId;
 
758
 
 
759
    visibleNameAtom = XInternAtom (s->dpy (), "_NET_WM_VISIBLE_NAME", 0);
 
760
    clientIdAtom = XInternAtom (s->dpy (), "SM_CLIENT_ID", 0);
 
761
    embedInfoAtom = XInternAtom (s->dpy (), "_XEMBED_INFO", 0);
 
762
    roleAtom = XInternAtom (s->dpy (), "WM_WINDOW_ROLE", 0);
 
763
    commandAtom = XInternAtom (s->dpy (), "WM_COMMAND", 0);
 
764
 
 
765
    prevClientId = CompSession::getClientId (CompSession::PrevClientId);
 
766
    if (!prevClientId.empty ())
 
767
        loadState (prevClientId);
 
768
 
 
769
    ScreenInterface::setHandler (s);
 
770
}
 
771
 
 
772
SessionWindow::SessionWindow (CompWindow *w) :
 
773
    PluginClassHandler<SessionWindow, CompWindow> (w),
 
774
    window (w),
 
775
    positionSet (false)
 
776
{
 
777
    WindowInterface::setHandler (w);
 
778
 
 
779
    if (!w->overrideRedirect () && w->isViewable ())
 
780
        SessionScreen::get (screen)->readWindow (w);
 
781
}
 
782
 
 
783
bool
 
784
SessionPluginVTable::init ()
 
785
{
 
786
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
 
787
        return false;
 
788
 
 
789
    return true;
 
790
}