]> Dogcows Code - chaz/openbox/blobdiff - openbox/session.c
1) translate all of openbox's output
[chaz/openbox] / openbox / session.c
index 63a8658eea61c2f4529f549c84a5d8c8d6280f12..1ff41519e9098de0ac433a34c23e8427d0cfcd6d 100644 (file)
@@ -1,3 +1,21 @@
+/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
+
+   session.c for the Openbox window manager
+   Copyright (c) 2003-2007   Dana Jansens
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   See the COPYING file for a copy of the GNU General Public License.
+*/
+
 /* This session code is largely inspired by metacity code. */
 
 #ifndef USE_SM
 
 GList *session_saved_state;
 
-void session_load(char *path) {}
-void session_startup(int argc, char **argv) {}
-void session_shutdown() {}
+void session_startup(gint argc, gchar **argv) {}
+void session_shutdown(gboolean permanent) {}
 GList* session_state_find(ObClient *c) { return NULL; }
-gboolean session_state_cmp(ObSessionState *s, struct _ObClient *c)
-{ return FALSE; }
+gboolean session_state_cmp(ObSessionState *s, ObClient *c) { return FALSE; }
 void session_state_free(ObSessionState *state) {}
 
 #else
@@ -22,6 +38,7 @@ void session_state_free(ObSessionState *state) {}
 #include "session.h"
 #include "client.h"
 #include "prop.h"
+#include "gettext.h"
 #include "parser/parse.h"
 
 #include <time.h>
@@ -37,15 +54,19 @@ void session_state_free(ObSessionState *state) {}
 
 GList *session_saved_state;
 
+static gboolean    sm_disable;
 static SmcConn     sm_conn;
 static gchar      *save_file;
+static gchar      *sm_id;
 static gint        sm_argc;
 static gchar     **sm_argv;
+static gchar      *sm_sessions_path;
 
+static void session_load(gchar *path);
 static gboolean session_save();
 
-static void sm_save_yourself(SmcConn conn, SmPointer data, int save_type,
-                             Bool shutdown, int interact_style, Bool fast);
+static void sm_save_yourself(SmcConn conn, SmPointer data, gint save_type,
+                             Bool shutdown, gint interact_style, Bool fast);
 static void sm_die(SmcConn conn, SmPointer data);
 static void sm_save_complete(SmcConn conn, SmPointer data);
 static void sm_shutdown_cancelled(SmcConn conn, SmPointer data);
@@ -55,55 +76,26 @@ static void save_commands()
     SmProp *props[2];
     SmProp prop_cmd = { SmCloneCommand, SmLISTofARRAY8, 1, };
     SmProp prop_res = { SmRestartCommand, SmLISTofARRAY8, };
-    gint i, j, n;
-    gboolean has_id = FALSE, has_file = FALSE;
-
-    for (i = 1; !has_id && !has_file && i < sm_argc - 1; ++i) {
-        if (!has_id && strcmp(sm_argv[i], "--sm-client-id") == 0)
-            has_id = TRUE;
-        if (!has_file && strcmp(sm_argv[i], "--sm-save-file") == 0)
-            has_file = TRUE;
-    }
+    gint i;
 
-    n = (has_file ? sm_argc-2 : sm_argc);
-    n = (has_id ? n-2 : n);
-    prop_cmd.vals = g_new(SmPropValue, n);
-    prop_cmd.num_vals = n;
-    for (i = 0, j = 0; i < sm_argc; ++i, ++j) {
-        if (strcmp (sm_argv[i], "--sm-client-id") == 0 ||
-            strcmp (sm_argv[i], "--sm-save-file") == 0) {
-            ++i, --j; /* skip the next as well, keep j where it is */
-        } else {
-            prop_cmd.vals[j].value = sm_argv[i];
-            prop_cmd.vals[j].length = strlen(sm_argv[i]);
-        }
+    prop_cmd.vals = g_new(SmPropValue, sm_argc);
+    prop_cmd.num_vals = sm_argc;
+    for (i = 0; i < sm_argc; ++i) {
+        prop_cmd.vals[i].value = sm_argv[i];
+        prop_cmd.vals[i].length = strlen(sm_argv[i]);
     }
 
-    n = (has_file ? sm_argc : sm_argc+2);
-    n = (has_id ? n-2 : n);
-    prop_res.vals = g_new(SmPropValue, n);
-    prop_res.num_vals = n;
-    for (i = 0, j = 0; i < sm_argc; ++i, ++j) { 
-        if (strcmp (sm_argv[i], "--sm-client-id") == 0 ||
-            strcmp (sm_argv[i], "--sm-save-file") == 0) {
-            ++i, --j; /* skip the next as well, keep j where it is */
-        } else {
-            prop_res.vals[j].value = sm_argv[i];
-            prop_res.vals[j].length = strlen(sm_argv[i]);
-        }
+    prop_res.vals = g_new(SmPropValue, sm_argc + 2);
+    prop_res.num_vals = sm_argc + 2;
+    for (i = 0; i < sm_argc; ++i) { 
+        prop_res.vals[i].value = sm_argv[i];
+        prop_res.vals[i].length = strlen(sm_argv[i]);
     }
 
-    if (save_file) {
-        prop_res.vals[j].value = "--sm-save-file";
-        prop_res.vals[j++].length = strlen("--sm-save-file");
-        prop_res.vals[j].value = save_file;
-        prop_res.vals[j++].length = strlen(save_file);
-    } else {
-        prop_res.vals[j].value = "--sm-client-id";
-        prop_res.vals[j++].length = strlen("--sm-client-id");
-        prop_res.vals[j].value = ob_sm_id;
-        prop_res.vals[j++].length = strlen(ob_sm_id);
-    }
+    prop_res.vals[i].value = "--sm-save-file";
+    prop_res.vals[i++].length = strlen("--sm-save-file");
+    prop_res.vals[i].value = save_file;
+    prop_res.vals[i++].length = strlen(save_file);
 
     props[0] = &prop_res;
     props[1] = &prop_cmd;
@@ -113,15 +105,83 @@ static void save_commands()
     g_free(prop_cmd.vals);
 }
 
-void session_startup(int argc, char **argv)
+static void remove_args(gint *argc, gchar ***argv, gint index, gint num)
+{
+    gint i;
+
+    for (i = index; i < index + num; ++i)
+        (*argv)[i] = (*argv)[i+num];
+    *argc -= num;
+}
+
+static void parse_args(gint *argc, gchar ***argv)
+{
+    gint i;
+
+    for (i = 1; i < *argc; ++i) {
+        if (!strcmp((*argv)[i], "--sm-client-id")) {
+            if (i == *argc - 1) /* no args left */
+                g_printerr(_("--sm-client-id requires an argument\n"));
+            else {
+                sm_id = g_strdup((*argv)[i+1]);
+                remove_args(argc, argv, i, 2);
+                ++i;
+            }
+        } else if (!strcmp((*argv)[i], "--sm-save-file")) {
+            if (i == *argc - 1) /* no args left */
+                g_printerr(_("--sm-save-file requires an argument\n"));
+            else {
+                save_file = g_strdup((*argv)[i+1]);
+                remove_args(argc, argv, i, 2);
+                ++i;
+            }
+        } else if (!strcmp((*argv)[i], "--sm-disable")) {
+            sm_disable = TRUE;
+            remove_args(argc, argv, i, 1);
+        }
+    }
+}
+
+void session_startup(gint argc, gchar **argv)
 {
 #define SM_ERR_LEN 1024
 
     SmcCallbacks cb;
-    char sm_err[SM_ERR_LEN];
+    gchar sm_err[SM_ERR_LEN];
+    gint i;
 
     sm_argc = argc;
-    sm_argv = argv;
+    sm_argv = g_new(gchar*, argc);
+    for (i = 0; i < argc; ++i)
+        sm_argv[i] = argv[i];
+
+    parse_args(&sm_argc, &sm_argv);
+
+    if (sm_disable) {
+        g_free(sm_argv);
+        return;
+    }
+
+    sm_sessions_path = g_build_filename(parse_xdg_data_home_path(),
+                                        "openbox", "sessions", NULL);
+    if (!parse_mkdir_path(sm_sessions_path, 0700)) {
+        g_message(_("Unable to make directory '%s': %s"),
+                  sm_sessions_path, g_strerror(errno));
+    }
+
+    if (save_file)
+        session_load(save_file);
+    else {
+        gchar *filename;
+
+        /* this algo is from metacity */
+        filename = g_strdup_printf("%d-%d-%u.obs",
+                                   (gint) time(NULL),
+                                   (gint) getpid(),
+                                   g_random_int());
+        save_file = g_build_filename(sm_sessions_path, filename, NULL);
+        g_free(filename);
+    }
 
     cb.save_yourself.callback = sm_save_yourself;
     cb.save_yourself.client_data = NULL;
@@ -140,10 +200,10 @@ void session_startup(int argc, char **argv)
                                 SmcDieProcMask |
                                 SmcSaveCompleteProcMask |
                                 SmcShutdownCancelledProcMask,
-                                &cb, ob_sm_id, &ob_sm_id,
+                                &cb, sm_id, &sm_id,
                                 SM_ERR_LEN, sm_err);
     if (sm_conn == NULL)
-        g_warning("Failed to connect to session manager: %s", sm_err);
+        ob_debug("Failed to connect to session manager: %s\n", sm_err);
     else {
         SmPropValue val_prog;
         SmPropValue val_uid;
@@ -159,8 +219,8 @@ void session_startup(int argc, char **argv)
         gchar hint, pri;
         gchar pid[32];
 
-        val_prog.value = argv[0];
-        val_prog.length = strlen(argv[0]);
+        val_prog.value = sm_argv[0];
+        val_prog.length = strlen(sm_argv[0]);
 
         val_uid.value = g_strdup(g_get_user_name());
         val_uid.length = strlen(val_uid.value);
@@ -169,7 +229,7 @@ void session_startup(int argc, char **argv)
         val_hint.value = &hint;
         val_hint.length = 1;
 
-        sprintf(pid, "%ld", (long)getpid());
+        g_snprintf(pid, sizeof(pid), "%ld", (glong) getpid());
         val_pid.value = pid;
         val_pid.length = strlen(pid);
 
@@ -195,31 +255,39 @@ void session_startup(int argc, char **argv)
         g_free(val_uid.value);
 
         save_commands();
-
-        ob_debug("Connected to session manager with id %s\n", ob_sm_id);
     }
 }
 
-void session_shutdown()
+void session_shutdown(gboolean permanent)
 {
+    if (sm_disable)
+        return;
+
+    g_free(sm_sessions_path);
     g_free(save_file);
+    g_free(sm_id);
+    g_free(sm_argv);
 
     if (sm_conn) {
-        SmPropValue val_hint;
-        SmProp prop_hint = { SmRestartStyleHint, SmCARD8, 1, };
-        SmProp *props[1];
-        gulong hint;
+        /* if permanent is true then we will change our session state so that
+           the SM won't run us again */
+        if (permanent) {
+            SmPropValue val_hint;
+            SmProp prop_hint = { SmRestartStyleHint, SmCARD8, 1, };
+            SmProp *props[1];
+            gulong hint;
 
-        /* when we exit, we want to reset this to a more friendly state */
-        hint = SmRestartIfRunning;
-        val_hint.value = &hint;
-        val_hint.length = 1;
+            /* when we exit, we want to reset this to a more friendly state */
+            hint = SmRestartIfRunning;
+            val_hint.value = &hint;
+            val_hint.length = 1;
 
-        prop_hint.vals = &val_hint;
+            prop_hint.vals = &val_hint;
 
-        props[0] = &prop_hint;
+            props[0] = &prop_hint;
 
-        SmcSetProperties(sm_conn, 1, props);
+            SmcSetProperties(sm_conn, 1, props);
+        }
 
         SmcCloseConnection(sm_conn, 0, NULL);
 
@@ -235,19 +303,15 @@ static void sm_save_yourself_phase2(SmcConn conn, SmPointer data)
 {
     gboolean success;
 
-    ob_debug("got SAVE YOURSELF PHASE 2 from session manager\n");
-
     success = session_save();
     save_commands();
 
     SmcSaveYourselfDone(conn, success);
 }
 
-static void sm_save_yourself(SmcConn conn, SmPointer data, int save_type,
-                             Bool shutdown, int interact_style, Bool fast)
+static void sm_save_yourself(SmcConn conn, SmPointer data, gint save_type,
+                             Bool shutdown, gint interact_style, Bool fast)
 {
-    ob_debug("got SAVE YOURSELF from session manager\n");
-
     if (!SmcRequestSaveYourselfPhase2(conn, sm_save_yourself_phase2, data)) {
         ob_debug("SAVE YOURSELF PHASE 2 failed\n");
         SmcSaveYourselfDone(conn, FALSE);
@@ -256,53 +320,38 @@ static void sm_save_yourself(SmcConn conn, SmPointer data, int save_type,
 
 static void sm_die(SmcConn conn, SmPointer data)
 {
-    ob_exit();
-    ob_debug("got DIE from session manager\n");
+    ob_exit(0);
 }
 
 static void sm_save_complete(SmcConn conn, SmPointer data)
 {
-    ob_debug("got SAVE COMPLETE from session manager\n");
 }
 
 static void sm_shutdown_cancelled(SmcConn conn, SmPointer data)
 {
-    ob_debug("got SHUTDOWN CANCELLED from session manager\n");
 }
 
 static gboolean session_save()
 {
-    gchar *filename;
     FILE *f;
     GList *it;
     gboolean success = TRUE;
 
-    /* this algo is from metacity */
-    filename = g_strdup_printf("%d-%d-%u.obs",
-                               (int) time(NULL),
-                               (int) getpid(),
-                               g_random_int());
-    save_file = g_build_filename(g_get_home_dir(), ".openbox", "sessions",
-                                 filename, NULL);
-    g_free(filename);
-
     f = fopen(save_file, "w");
     if (!f) {
         success = FALSE;
-        g_warning("unable to save the session to %s: %s",
-                  save_file, strerror(errno));
+        g_message(_("Unable to save the session to '%s': %s"),
+                  save_file, g_strerror(errno));
     } else {
         guint stack_pos = 0;
 
         fprintf(f, "<?xml version=\"1.0\"?>\n\n");
-        fprintf(f, "<openbox_session id=\"%s\">\n\n", ob_sm_id);
+        fprintf(f, "<openbox_session id=\"%s\">\n\n", sm_id);
 
         for (it = stacking_list; it; it = g_list_next(it)) {
-            guint num;
-            gint32 *dimensions;
             gint prex, prey, prew, preh;
             ObClient *c;
-            gchar *client_id, *t;
+            gchar *t;
 
             if (WINDOW_IS_CLIENT(it->data))
                 c = WINDOW_AS_CLIENT(it->data);
@@ -312,25 +361,29 @@ static gboolean session_save()
             if (!client_normal(c))
                 continue;
 
-            if (!(client_id = client_get_sm_client_id(c)))
+            if (!c->sm_client_id)
                 continue;
 
             prex = c->area.x;
             prey = c->area.y;
             prew = c->area.width;
             preh = c->area.height;
-            if (PROP_GETA32(c->window, openbox_premax, cardinal,
-                            (guint32**)&dimensions, &num)) {
-                if (num == 4) {
-                    prex = dimensions[0];
-                    prey = dimensions[1];
-                    prew = dimensions[2];
-                    preh = dimensions[3];
-                }
-                g_free(dimensions);
+            if (c->fullscreen) {
+                prex = c->pre_fullscreen_area.x;
+                prey = c->pre_fullscreen_area.x;
+                prew = c->pre_fullscreen_area.width;
+                preh = c->pre_fullscreen_area.height;
+            }
+            if (c->max_horz) {
+                prex = c->pre_max_area.x;
+                prew = c->pre_max_area.width;
+            }
+            if (c->max_vert) {
+                prey = c->pre_max_area.y;
+                preh = c->pre_max_area.height;
             }
 
-            fprintf(f, "<window id=\"%s\">\n", client_id);
+            fprintf(f, "<window id=\"%s\">\n", c->sm_client_id);
 
             t = g_markup_escape_text(c->name, -1);
             fprintf(f, "\t<name>%s</name>\n", t);
@@ -371,16 +424,14 @@ static gboolean session_save()
             fprintf(f, "</window>\n\n");
 
             ++stack_pos;
-
-            g_free(client_id);
         }
 
         fprintf(f, "</openbox_session>\n");
 
         if (fflush(f)) {
             success = FALSE;
-            g_warning("error while saving the session to %s: %s",
-                      save_file, strerror(errno));
+            g_message(_("Error while saving the session to '%s': %s"),
+                      save_file, g_strerror(errno));
         }
         fclose(f);
     }
@@ -402,22 +453,11 @@ void session_state_free(ObSessionState *state)
 
 gboolean session_state_cmp(ObSessionState *s, ObClient *c)
 {
-    gchar *client_id;
-
-    if (!(client_id = client_get_sm_client_id(c)))
-        return FALSE;
-    if (strcmp(s->id, client_id)) {
-        g_free(client_id);
-        return FALSE;
-    }
-    g_free(client_id);
-    if (strcmp(s->name, c->name))
-        return FALSE;
-    if (strcmp(s->class, c->class))
-        return FALSE;
-    if (strcmp(s->role, c->role))
-        return FALSE;
-    return TRUE;
+    return (c->sm_client_id &&
+            !strcmp(s->id, c->sm_client_id) &&
+            !strcmp(s->name, c->name) &&
+            !strcmp(s->class, c->class) &&
+            !strcmp(s->role, c->role));
 }
 
 GList* session_state_find(ObClient *c)
@@ -439,20 +479,21 @@ static gint stack_sort(const ObSessionState *s1, const ObSessionState *s2)
     return s1->stacking - s2->stacking;
 }
 
-void session_load(char *path)
+static void session_load(gchar *path)
 {
     xmlDocPtr doc;
     xmlNodePtr node, n;
-    gchar *sm_id;
+    gchar *id;
 
     if (!parse_load(path, "openbox_session", &doc, &node))
         return;
 
-    if (!parse_attr_string("id", node, &sm_id))
+    if (!parse_attr_string("id", node, &id))
         return;
-    ob_sm_id = g_strdup(sm_id);
+    g_free(sm_id);
+    sm_id = id;
 
-    node = parse_find_node("window", node->xmlChildrenNode);
+    node = parse_find_node("window", node->children);
     while (node) {
         ObSessionState *state;
 
@@ -460,52 +501,52 @@ void session_load(char *path)
 
         if (!parse_attr_string("id", node, &state->id))
             goto session_load_bail;
-        if (!(n = parse_find_node("name", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("name", node->children)))
             goto session_load_bail;
         state->name = parse_string(doc, n);
-        if (!(n = parse_find_node("class", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("class", node->children)))
             goto session_load_bail;
         state->class = parse_string(doc, n);
-        if (!(n = parse_find_node("role", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("role", node->children)))
             goto session_load_bail;
         state->role = parse_string(doc, n);
-        if (!(n = parse_find_node("stacking", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("stacking", node->children)))
             goto session_load_bail;
         state->stacking = parse_int(doc, n);
-        if (!(n = parse_find_node("desktop", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("desktop", node->children)))
             goto session_load_bail;
         state->desktop = parse_int(doc, n);
-        if (!(n = parse_find_node("x", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("x", node->children)))
             goto session_load_bail;
         state->x = parse_int(doc, n);
-        if (!(n = parse_find_node("y", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("y", node->children)))
             goto session_load_bail;
         state->y = parse_int(doc, n);
-        if (!(n = parse_find_node("width", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("width", node->children)))
             goto session_load_bail;
         state->w = parse_int(doc, n);
-        if (!(n = parse_find_node("height", node->xmlChildrenNode)))
+        if (!(n = parse_find_node("height", node->children)))
             goto session_load_bail;
         state->h = parse_int(doc, n);
 
         state->shaded =
-            parse_find_node("shaded", node->xmlChildrenNode) != NULL;
+            parse_find_node("shaded", node->children) != NULL;
         state->iconic =
-            parse_find_node("iconic", node->xmlChildrenNode) != NULL;
+            parse_find_node("iconic", node->children) != NULL;
         state->skip_pager =
-            parse_find_node("skip_pager", node->xmlChildrenNode) != NULL;
+            parse_find_node("skip_pager", node->children) != NULL;
         state->skip_taskbar =
-            parse_find_node("skip_taskbar", node->xmlChildrenNode) != NULL;
+            parse_find_node("skip_taskbar", node->children) != NULL;
         state->fullscreen =
-            parse_find_node("fullscreen", node->xmlChildrenNode) != NULL;
+            parse_find_node("fullscreen", node->children) != NULL;
         state->above =
-            parse_find_node("above", node->xmlChildrenNode) != NULL;
+            parse_find_node("above", node->children) != NULL;
         state->below =
-            parse_find_node("below", node->xmlChildrenNode) != NULL;
+            parse_find_node("below", node->children) != NULL;
         state->max_horz =
-            parse_find_node("max_horz", node->xmlChildrenNode) != NULL;
+            parse_find_node("max_horz", node->children) != NULL;
         state->max_vert =
-            parse_find_node("max_vert", node->xmlChildrenNode) != NULL;
+            parse_find_node("max_vert", node->children) != NULL;
         
         /* save this */
         session_saved_state = g_list_prepend(session_saved_state, state);
This page took 0.038337 seconds and 4 git commands to generate.