summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2010-08-26 09:22:14 +0200
committerDanny Baumann <dannybaumann@web.de>2010-08-26 09:22:14 +0200
commit8d9fbe0d6cfd3e4416cca5609ca012f57b3adc25 (patch)
tree9c1e7e7431728a910788f44ee03ae51115cbb70d
parent31fc609a1d91b9587d68efbdc7d3f60741d87621 (diff)
downloadsession-8d9fbe0d6cfd3e4416cca5609ca012f57b3adc25.tar.gz
session-8d9fbe0d6cfd3e4416cca5609ca012f57b3adc25.tar.bz2
Use libxml to write out session file so that the output is properly
encoded. This fixes restoration of sessions which had windows with e.g. '&' in its title.
-rw-r--r--session.c165
1 files changed, 103 insertions, 62 deletions
diff --git a/session.c b/session.c
index 58632a1..72297ad 100644
--- a/session.c
+++ b/session.c
@@ -37,6 +37,7 @@
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
+#include <libxml/xmlsave.h>
#define SESSION_DISPLAY_OPTION_SAVE_LEGACY 0
#define SESSION_DISPLAY_OPTION_IGNORE_MATCH 1
@@ -267,7 +268,7 @@ sessionGetIsEmbedded (CompDisplay *d,
return (nitems > 1);
}
-static char*
+static char *
sessionGetClientLeaderProperty (CompWindow *w,
Atom atom)
{
@@ -354,11 +355,25 @@ isSessionWindow (CompWindow *w)
}
static void
-sessionWriteWindow (CompWindow *w,
- FILE *outfile)
+addIntegerPropToNode (xmlNodePtr node,
+ const char *name,
+ int value)
+{
+ xmlChar *string = xmlXPathCastNumberToString (value);
+
+ if (!string)
+ return;
+
+ xmlNewProp (node, BAD_CAST name, string);
+ xmlFree (string);
+}
+
+static void
+sessionAddWindowNode (CompWindow *w,
+ xmlNodePtr rootNode)
{
- char *string, *clientId, *command;
- int x, y;
+ xmlNodePtr node, childNode;
+ char *string, *clientId, *command;
SESSION_DISPLAY (w->screen->display);
@@ -371,93 +386,107 @@ sessionWriteWindow (CompWindow *w,
if (!clientId && !command)
return;
- fprintf (outfile, " <window ");
+ node = xmlNewChild (rootNode, NULL, BAD_CAST "window", NULL);
+ if (!node)
+ return;
+
if (clientId)
{
- fprintf (outfile, "id=\"%s\"", clientId);
+ xmlNewProp (node, BAD_CAST "id", BAD_CAST clientId);
free (clientId);
}
string = sessionGetWindowTitle (w);
if (string)
{
- fprintf (outfile, " title=\"%s\"", string);
+ xmlNewProp (node, BAD_CAST "title", BAD_CAST string);
free (string);
}
if (w->resClass)
- fprintf (outfile, " class=\"%s\"", w->resClass);
+ xmlNewProp (node, BAD_CAST "class", BAD_CAST w->resClass);
if (w->resName)
- fprintf (outfile, " name=\"%s\"", w->resName);
+ xmlNewProp (node, BAD_CAST "name", BAD_CAST w->resName);
string = sessionGetTextProperty (w->screen->display, w->id, sd->roleAtom);
if (string)
{
- fprintf (outfile, " role=\"%s\"", string);
+ xmlNewProp (node, BAD_CAST "role", BAD_CAST string);
free (string);
}
if (command)
{
- fprintf (outfile, " command=\"%s\"", command);
+ xmlNewProp (node, BAD_CAST "command", BAD_CAST command);
free (command);
}
- fprintf (outfile, ">\n");
/* save geometry, relative to viewport 0, 0 */
- x = (w->saveMask & CWX) ? w->saveWc.x : w->serverX;
- y = (w->saveMask & CWY) ? w->saveWc.y : w->serverY;
- if (!windowOnAllViewports (w))
+ childNode = xmlNewChild (node, NULL, BAD_CAST "geometry", NULL);
+ if (childNode)
{
- x += w->screen->x * w->screen->width;
- y += w->screen->y * w->screen->height;
- }
+ int x, y, width, height;
- x -= w->input.left;
- y -= w->input.top;
+ x = (w->saveMask & CWX) ? w->saveWc.x : w->serverX;
+ y = (w->saveMask & CWY) ? w->saveWc.y : w->serverY;
+ if (!windowOnAllViewports (w))
+ {
+ x += w->screen->x * w->screen->width;
+ y += w->screen->y * w->screen->height;
+ }
+
+ x -= w->input.left;
+ y -= w->input.top;
- fprintf (outfile,
- " <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n",
- x, y,
- (w->saveMask & CWWidth) ? w->saveWc.width : w->serverWidth,
- (w->saveMask & CWHeight) ? w->saveWc.height : w->serverHeight);
+ width = (w->saveMask & CWWidth) ? w->saveWc.width : w->serverWidth;
+ height = (w->saveMask & CWHeight) ? w->saveWc.height : w->serverHeight;
+
+ addIntegerPropToNode (childNode, "x", x);
+ addIntegerPropToNode (childNode, "y", y);
+ addIntegerPropToNode (childNode, "width", width);
+ addIntegerPropToNode (childNode, "height", height);
+ }
/* save various window states */
if (w->state & CompWindowStateShadedMask)
- fprintf (outfile, " <shaded/>\n");
+ xmlNewChild (node, NULL, BAD_CAST "shaded", NULL);
if (w->state & CompWindowStateStickyMask)
- fprintf (outfile, " <sticky/>\n");
+ xmlNewChild (node, NULL, BAD_CAST "sticky", NULL);
if (w->state & CompWindowStateFullscreenMask)
- fprintf (outfile, " <fullscreen/>\n");
+ xmlNewChild (node, NULL, BAD_CAST "fullscreen", NULL);
if (w->minimized)
- fprintf (outfile, " <minimized/>\n");
+ xmlNewChild (node, NULL, BAD_CAST "minimized", NULL);
if (w->state & MAXIMIZE_STATE)
{
- fprintf (outfile, " <maximized ");
- if (w->state & CompWindowStateMaximizedVertMask)
- fprintf (outfile, "vert=\"yes\" ");
- if (w->state & CompWindowStateMaximizedHorzMask)
- fprintf (outfile, "horiz=\"yes\"");
- fprintf (outfile, "/>\n");
+ childNode = xmlNewChild (node, NULL, BAD_CAST "maximized", NULL);
+ if (childNode)
+ {
+ if (w->state & CompWindowStateMaximizedVertMask)
+ xmlNewProp (childNode, BAD_CAST "vert", BAD_CAST "yes");
+ if (w->state & CompWindowStateMaximizedHorzMask)
+ xmlNewProp (childNode, BAD_CAST "horiz", BAD_CAST "yes");
+ }
}
/* save workspace */
if (!(w->type & CompWindowTypeDesktopMask ||
w->type & CompWindowTypeDockMask))
- fprintf (outfile, " <workspace index=\"%d\"/>\n",
- w->desktop);
-
- fprintf (outfile, " </window>\n");
+ {
+ childNode = xmlNewChild (node, NULL, BAD_CAST "workspace", NULL);
+ if (childNode)
+ addIntegerPropToNode (childNode, "index", w->desktop);
+ }
}
static void
saveState (CompDisplay *d,
const char *clientId)
{
- char *filename;
- FILE *outfile = NULL;
- struct passwd *p = getpwuid (geteuid ());
- CompScreen *s;
+ char *filename;
+ struct passwd *p = getpwuid (geteuid ());
+ xmlDocPtr doc = NULL;
+ xmlSaveCtxtPtr ctx = NULL;
+ CompScreen *s;
/* setup filename and create directories as needed */
filename = malloc (sizeof (char) *
@@ -474,36 +503,48 @@ saveState (CompDisplay *d,
{
strcat (filename, "/");
strcat (filename, clientId);
- outfile = fopen (filename, "w");
+ ctx = xmlSaveToFilename (filename, NULL, XML_SAVE_FORMAT);
}
}
free (filename);
- if (!outfile)
+ if (!ctx)
return;
- fprintf (outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- fprintf (outfile, "<compiz_session id=\"%s\">\n", clientId);
-
- /* write out all windows on this display */
- for (s = d->screens; s; s = s->next)
+ doc = xmlNewDoc (BAD_CAST "1.0");
+ if (doc)
{
- CompWindow *w;
-
- for (w = s->windows; w; w = w->next)
+ xmlNodePtr rootNode;
+ rootNode = xmlNewNode (NULL, BAD_CAST "compiz_session");
+ if (rootNode)
{
- if (!isSessionWindow (w))
- continue;
+ xmlNewProp (rootNode, BAD_CAST "id", BAD_CAST clientId);
+ xmlDocSetRootElement (doc, rootNode);
+
+ /* write out all windows on this display */
+ for (s = d->screens; s; s = s->next)
+ {
+ CompWindow *w;
+
+ for (w = s->windows; w; w = w->next)
+ {
+ if (!isSessionWindow (w))
+ continue;
- if (!w->managed)
- continue;
+ if (!w->managed)
+ continue;
- sessionWriteWindow (w, outfile);
+ sessionAddWindowNode (w, rootNode);
+ }
+ }
+
+ xmlSaveDoc (ctx, doc);
}
+
+ xmlFreeDoc (doc);
}
- fprintf (outfile, "</compiz_session>\n");
- fclose (outfile);
+ xmlSaveClose (ctx);
}
static Bool
@@ -764,7 +805,7 @@ sessionWindowAdd (CompScreen *s,
CompWindow *w)
{
if (!w->attrib.override_redirect && w->attrib.map_state == IsViewable)
- sessionReadWindow (w);
+ sessionReadWindow (w);
}
static void