File pcmanfm-0.9.8-fixbnc648882.patch of Package pcmanfm

From cda6259f02a01b2b02e33aebfd11825425c3b2db Mon Sep 17 00:00:00 2001
From: Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
Date: Sun, 7 Nov 2010 23:47:47 +0800
Subject: [PATCH] Reimplement a simpler yet cleaner IPC mechanism again.

---
 src/pcmanfm.c     |  130 ++++---------------
 src/single-inst.c |  368 ++++++++++++++++++-----------------------------------
 src/single-inst.h |   73 +++--------
 3 files changed, 173 insertions(+), 398 deletions(-)

diff --git a/src/pcmanfm.c b/src/pcmanfm.c
index 50488a5..3e21aaa 100644
--- a/src/pcmanfm.c
+++ b/src/pcmanfm.c
@@ -65,37 +65,23 @@ static int n_pcmanfm_ref = 0;
 
 static GOptionEntry opt_entries[] =
 {
-    /* { "new-tab", 't', 0, G_OPTION_ARG_NONE, &new_tab, N_("Open folders in new tabs of the last used window instead of creating new windows"), NULL }, */
+    /* options only acceptable by first pcmanfm instance. These options are not passed through IPC */
     { "profile", 'p', 0, G_OPTION_ARG_STRING, &profile, N_("Name of configuration profile"), "<profile name>" },
+    { "daemon-mode", 'd', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Run PCManFM as a daemon"), NULL },
+    { "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &no_desktop, N_("No function. Just to be compatible with nautilus"), NULL },
+
+    /* options that are acceptable for every instance of pcmanfm and will be passed through IPC. */
     { "desktop", '\0', 0, G_OPTION_ARG_NONE, &show_desktop, N_("Launch desktop manager"), NULL },
     { "desktop-off", '\0', 0, G_OPTION_ARG_NONE, &desktop_off, N_("Turn off desktop manager if it's running"), NULL },
-    { "daemon-mode", 'd', 0, G_OPTION_ARG_NONE, &daemon_mode, N_("Run PCManFM as a daemon"), NULL },
     { "desktop-pref", '\0', 0, G_OPTION_ARG_NONE, &desktop_pref, N_("Open desktop preference dialog"), NULL },
     { "set-wallpaper", 'w', 0, G_OPTION_ARG_FILENAME, &set_wallpaper, N_("Set desktop wallpaper"), N_("<image file>") },
     { "wallpaper-mode", '\0', 0, G_OPTION_ARG_STRING, &wallpaper_mode, N_("Set mode of desktop wallpaper. <mode>=(color|stretch|fit|center|tile)"), N_("<mode>") },
     { "show-pref", '\0', 0, G_OPTION_ARG_INT, &show_pref, N_("Open preference dialog. 'n' is number of the page you want to show (1, 2, 3...)."), "n" },
     /* { "find-files", 'f', 0, G_OPTION_ARG_NONE, &find_files, N_("Open Find Files utility"), NULL }, */
-    { "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &no_desktop, N_("No function. Just to be compatible with nautilus"), NULL },
     {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files_to_open, NULL, N_("[FILE1, FILE2,...]")},
     { NULL }
 };
 
-/* single instance command id */
-enum {
-    CMD_INVALID,
-    CMD_CWD,
-    CMD_PROFILE,
-    CMD_DESKTOP,
-    CMD_DESKTOP_OFF,
-    CMD_DAEMON_MODE,
-    CMD_DESKTOP_PREF,
-    CMD_SET_WALLPAPER,
-    CMD_WALLPAPER_MODE,
-    CMD_SHOW_PREF,
-    CMD_FILES_TO_OPEN,
-    CMD_EOF
-};
-
 static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
 
 static gboolean pcmanfm_run();
@@ -121,101 +107,39 @@ static gboolean on_unix_signal(GIOChannel* ch, GIOCondition cond, gpointer user_
     return TRUE;
 }
 
-static gboolean on_single_inst_command(int cmd, SingleInstCmdData* data)
+static void single_inst_cb(const char* cwd, int workspace, int screen)
 {
-    switch(cmd)
+    g_free(ipc_cwd);
+    ipc_cwd = g_strdup(cwd);
+
+    if(files_to_open)
     {
-    case CMD_CWD:
-        g_free(ipc_cwd);
-        ipc_cwd = single_inst_get_str(data, NULL);
-        break;
-    case CMD_PROFILE:
-        /* Not supported */
-        break;
-    case CMD_DESKTOP:
-        single_inst_get_bool(data, &show_desktop);
-        break;
-    case CMD_DESKTOP_OFF:
-        single_inst_get_bool(data, &desktop_off);
-        break;
-    case CMD_DAEMON_MODE:
-        /* Not supported */
-        break;
-    case CMD_DESKTOP_PREF:
-        single_inst_get_bool(data, &desktop_pref);
-        break;
-    case CMD_SET_WALLPAPER:
-        g_free(set_wallpaper);
-        set_wallpaper = single_inst_get_str(data, NULL);
-        break;
-    case CMD_WALLPAPER_MODE:
-        g_free(wallpaper_mode);
-        wallpaper_mode = single_inst_get_str(data, NULL);
-        break;
-    case CMD_SHOW_PREF:
-        single_inst_get_int(data, &show_pref);
-        break;
-    case CMD_FILES_TO_OPEN:
-        {
-            g_strfreev(files_to_open);
-            n_files_to_open = 0;
-            files_to_open = single_inst_get_strv(data, &n_files_to_open);
-        }
-        break;
-    case CMD_EOF:
+        int i;
+        /* canonicalize filename if needed. */
+        for(i = 0; i < n_files_to_open; ++i)
         {
-            int i;
-            /* canonicalize filename if needed. */
-            for(i = 0; i < n_files_to_open; ++i)
+            char* file = files_to_open[i];
+            char* scheme = g_uri_parse_scheme(file);
+            if(scheme) /* a valid URI */
             {
-                char* file = files_to_open[i];
-                char* scheme = g_uri_parse_scheme(file);
-                if(scheme) /* a valid URI */
-                {
-                    /* FIXME: should we canonicalize URIs? and how about file:///? */
-                    g_free(scheme);
-                }
-                else /* a file path */
-                {
-                    files_to_open[i] = fm_canonicalize_filename(file, ipc_cwd);
-                    g_free(file);
-                }
+                /* FIXME: should we canonicalize URIs? and how about file:///? */
+                g_free(scheme);
+            }
+            else /* a file path */
+            {
+                files_to_open[i] = fm_canonicalize_filename(file, cwd);
+                g_free(file);
             }
-
-            /* handle the parsed result and run the main program */
-            pcmanfm_run();
         }
-        break;
     }
-    return TRUE;
-}
-
-/* we're not the first instance. pass the argv to the existing one. */
-static void pass_args_to_existing_instance()
-{
-    /* send our current working dir to existing instance via IPC. */
-    ipc_cwd = g_get_current_dir();
-    single_inst_send_str(CMD_CWD, ipc_cwd);
-    g_free(ipc_cwd);
-
-    single_inst_send_bool(CMD_DESKTOP, show_desktop);
-    single_inst_send_bool(CMD_DESKTOP_OFF, desktop_off);
-    single_inst_send_bool(CMD_DESKTOP_PREF, desktop_pref);
-    single_inst_send_str(CMD_SET_WALLPAPER, set_wallpaper);
-    single_inst_send_str(CMD_WALLPAPER_MODE, wallpaper_mode);
-    single_inst_send_int(CMD_SHOW_PREF, show_pref);
-    /* single_inst_send_bool(CMD_FIND_FILES, find_files); */
-
-    single_inst_send_strv(CMD_FILES_TO_OPEN, files_to_open);
-    single_inst_send_bool(CMD_EOF, TRUE); /* all args have been sent. */
-
-    single_inst_finalize();
+    pcmanfm_run();
 }
 
 int main(int argc, char** argv)
 {
     FmConfig* config;
     GError* err = NULL;
+
 #ifdef ENABLE_NLS
     bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
     bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
@@ -231,10 +155,10 @@ int main(int argc, char** argv)
     }
 
     /* ensure that there is only one instance of pcmanfm. */
-    switch(single_inst_init("pcmanfm", on_single_inst_command))
+    switch(single_inst_init("pcmanfm", single_inst_cb, opt_entries + 3))
     {
     case SINGLE_INST_CLIENT: /* we're not the first instance. */
-        pass_args_to_existing_instance();
+        single_inst_finalize();
         gdk_notify_startup_complete();
         return 0;
     case SINGLE_INST_ERROR: /* error happened. */
diff --git a/src/single-inst.c b/src/single-inst.c
index 63c7885..175809d 100644
--- a/src/single-inst.c
+++ b/src/single-inst.c
@@ -1,22 +1,24 @@
-//      single-inst.c: simple IPC mechanism for single instance app
-//
-//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
-//
-//      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.
-//
-//      You should have received a copy of the GNU General Public License
-//      along with this program; if not, write to the Free Software
-//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-//      MA 02110-1301, USA.
-
+/*
+ *      single-inst.c: simple IPC mechanism for single instance app
+ *
+ *      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
+ *
+ *      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.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+ 
 #include "single-inst.h"
 
 #include <string.h>
@@ -26,14 +28,14 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
+#include <stdio.h>
 
 typedef struct _SingleInstClient SingleInstClient;
 struct _SingleInstClient
 {
     GIOChannel* channel;
-    GByteArray* buffer;
-    gint cmd;
-    gsize chunk_size;
+    char* cwd;
+    GPtrArray* argv;
     guint watch;
 };
 
@@ -43,7 +45,8 @@ static guint io_watch = 0;
 static char* prog_name = NULL;
 
 static GList* clients;
-static SingleInstCallback server_cmd_cb = NULL;
+static SingleInstCallback callback = NULL;
+static GOptionEntry* opt_entries = NULL;
 
 static void get_socket_name(char* buf, int len);
 static gboolean on_server_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer data);
@@ -54,12 +57,74 @@ static void single_inst_client_free(SingleInstClient* client)
     g_io_channel_shutdown(client->channel, FALSE, NULL);
     g_io_channel_unref(client->channel);
     g_source_remove(client->watch);
-    g_byte_array_free(client->buffer, TRUE);
+    g_free(client->cwd);
+    g_ptr_array_foreach(client->argv, (GFunc)g_free, NULL);
+    g_ptr_array_free(client->argv, TRUE);
     g_slice_free(SingleInstClient, client);
     /* g_debug("free client"); */
 }
 
-SingleInstResult single_inst_init(const char* _prog_name, SingleInstCallback _server_cmd_cb)
+static void pass_args_to_existing_instance()
+{
+    GOptionEntry* ent;
+    FILE* f = fdopen(sock, "w");
+
+    char* cwd = g_get_current_dir();
+    /* pass cwd */
+    fprintf(f, "%s\n", cwd);
+    g_free(cwd);
+
+    for(ent = opt_entries; ent->long_name; ++ent)
+    {
+        switch(ent->arg)
+        {
+        case G_OPTION_ARG_NONE:
+            if(*(gboolean*)ent->arg_data)
+                fprintf(f, "--%s\n", ent->long_name);
+            break;
+        case G_OPTION_ARG_STRING:
+        case G_OPTION_ARG_FILENAME:
+        {
+            /* FIXME: handle strings has -- prefix */
+            char* str = *(char**)ent->arg_data;
+            if(str && *str)
+                fprintf(f, "--%s\n%s\n", ent->long_name, str);
+            break;
+        }
+        case G_OPTION_ARG_INT:
+            fprintf(f, "--%s\n%d\n", ent->long_name, *(gint*)ent->arg_data);
+            break;
+        case G_OPTION_ARG_STRING_ARRAY:
+        case G_OPTION_ARG_FILENAME_ARRAY:
+        {
+            /* FIXME: handle strings has -- prefix */
+            char** strv = *(char***)ent->arg_data;
+            if(strv && *strv)
+            {
+                if(*ent->long_name) /* G_OPTION_REMAINING = "" */
+                    fprintf(f, "--%s\n", ent->long_name);
+                for(; *strv; ++strv)
+                {
+                    fprintf(f, "%s\n", *strv);
+                }
+            }
+            break;
+        }
+        case G_OPTION_ARG_DOUBLE:
+            fprintf(f, "--%s\n%lf\n", ent->long_name, *(gdouble*)ent->arg_data);
+            break;
+        case G_OPTION_ARG_INT64:
+            fprintf(f, "--%s\n%lld\n", ent->long_name, *(gint64*)ent->arg_data);
+            break;
+        case G_OPTION_ARG_CALLBACK:
+            /* Not supported */
+            break;
+        }
+    }
+    fclose(f);
+}
+
+SingleInstResult single_inst_init(const char* _prog_name, SingleInstCallback cb, GOptionEntry* _opt_entries)
 {
     struct sockaddr_un addr;
     int addr_len;
@@ -70,7 +135,7 @@ SingleInstResult single_inst_init(const char* _prog_name, SingleInstCallback _se
         return SINGLE_INST_ERROR;
 
     prog_name = g_strdup(_prog_name);
-    server_cmd_cb = _server_cmd_cb;
+    opt_entries = _opt_entries;
 
     /* FIXME: use abstract socket? */
     addr.sun_family = AF_UNIX;
@@ -84,7 +149,8 @@ SingleInstResult single_inst_init(const char* _prog_name, SingleInstCallback _se
     /* try to connect to existing instance */
     if(connect(sock, (struct sockaddr*)&addr, addr_len) == 0)
     {
-        /* connected successfully */
+        /* connected successfully, pass args in opt_entries to server process as argv and exit. */
+        pass_args_to_existing_instance(_opt_entries);
         return SINGLE_INST_CLIENT;
     }
 
@@ -100,6 +166,8 @@ SingleInstResult single_inst_init(const char* _prog_name, SingleInstCallback _se
         return SINGLE_INST_ERROR;
     }
 
+    callback = cb;
+
     io_channel = g_io_channel_unix_new(sock);
     g_io_channel_set_encoding(io_channel, NULL, NULL);
     g_io_channel_set_buffered(io_channel, FALSE);
@@ -142,86 +210,55 @@ void single_inst_finalize()
             /* remove the file */
             get_socket_name(sock_path, 256);
             unlink(sock_path);
+            callback = NULL;
+            opt_entries = NULL;
         }
     }
     g_free(prog_name);
     prog_name = NULL;
 }
 
-/* Format of data chunk:
- * gsize chunk_size = sizeof(chunk_size) + sizeof(cmd) + sizeof(data_type) + sizeof(data)
- * int cmd;
- * int data_type;
- * char data[n];
- */
-
-static void dispatch_command(char* data, int data_len)
-{
-    int cmd;
-    SingleInstCmdData cmd_data;
-
-    /* read the command id */
-    memcpy(&cmd, data, sizeof(cmd));
-    data += sizeof(cmd);
-
-    /* read data type */
-    memcpy(&cmd_data.type, data, sizeof(cmd_data.type));
-    data += sizeof(cmd_data.type);
-
-    /* g_debug("cmd = %d, data_len=%d", cmd, data_len); */
-    /* data should points to the real data now */
-    cmd_data.len = data_len - sizeof(cmd) - sizeof(cmd_data.type);
-    cmd_data.data = data;
-
-    if(server_cmd_cb)
-        server_cmd_cb(cmd, &cmd_data);
-}
-
 gboolean on_client_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer user_data)
 {
     SingleInstClient* client = (SingleInstClient*)user_data;
 
     if ( cond & (G_IO_IN|G_IO_PRI) )
     {
-        char buf[4096];
-        int r;
         GIOStatus status;
+        char *line;
+        gsize term;
 
-        _read_again:
-        status = g_io_channel_read_chars(ioc, buf, sizeof(buf), &r, NULL);
-        if(status == G_IO_STATUS_AGAIN) /* FIXME: how many times should we retry? */
-            goto _read_again;
-        g_byte_array_append( client->buffer, (guint8*)buf, r);
-
-        /* we don't know the size of data chunk yet. */
-        if(G_UNLIKELY(client->chunk_size == 0))
-        {
-            if(client->buffer->len > 0) /* read from it. */
-                memcpy(&client->chunk_size, client->buffer->data, sizeof(gsize));
-        }
-        while(G_LIKELY(client->chunk_size > 0))
+        while(g_io_channel_read_line(ioc, &line, NULL, &term, NULL) == G_IO_STATUS_NORMAL)
         {
-            /* g_debug("chunk_size = %d, buf_len = %d", client->chunk_size, client->buffer->len); */
-            if(client->buffer->len >= client->chunk_size)
+            if(line)
             {
-                /* unpack the data chunk */
-                char* data = (char*)client->buffer->data + sizeof(client->chunk_size);
-                int data_len = client->chunk_size - sizeof(client->chunk_size);
-                dispatch_command(data, data_len);
-
-                g_byte_array_remove_range(client->buffer, 0, client->chunk_size);
-                if(client->buffer->len > 0)
-                    memcpy(&client->chunk_size, client->buffer->data, sizeof(gsize));
+                line[term] = '\0';
+                g_debug("line = %s", line);
+                if(!client->cwd)
+                    client->cwd = line;
                 else
-                    client->chunk_size = 0;
+                    g_ptr_array_add(client->argv, line);
             }
-            else
-                break;
         }
     }
 
     if(cond & (G_IO_ERR|G_IO_HUP))
     {
+        if(! (cond & G_IO_ERR) ) /* if there is no error */
+        {
+            /* try to parse argv */
+            GOptionContext* ctx = g_option_context_new("");
+            int argc = client->argv->len;
+            char** argv = g_new(char*, argc + 1);
+            memcpy(argv, client->argv->pdata, sizeof(char*) * argc);
+            argv[argc] = NULL;
+            g_option_context_add_main_entries(ctx, opt_entries, NULL);
+            g_option_context_parse(ctx, &argc, &argv, NULL);
+            g_free(argv);
+            g_option_context_free(ctx);
+            if(callback)
+                callback(client->cwd, 0, 0);
+        }
         single_inst_client_free(client);
         clients = g_list_remove(clients, client);
         return FALSE;
@@ -240,8 +277,8 @@ gboolean on_server_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer dat
             SingleInstClient* client = g_slice_new0(SingleInstClient);
             client->channel = g_io_channel_unix_new(client_sock);
             g_io_channel_set_encoding(client->channel, NULL, NULL);
-            g_io_channel_set_buffered(client->channel, FALSE);
-            client->buffer = g_byte_array_sized_new(4096);
+            client->argv = g_ptr_array_new();
+            g_ptr_array_add(client->argv, g_strdup(g_get_prgname()));
             client->watch = g_io_add_watch(client->channel, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP,
                                            on_client_socket_event, client);
             clients = g_list_prepend(clients, client);
@@ -254,10 +291,9 @@ gboolean on_server_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer dat
     if(cond & (G_IO_ERR|G_IO_HUP))
     {
         char* _prog_name = prog_name;
-        SingleInstCallback cb = server_cmd_cb;
         prog_name = NULL;
         single_inst_finalize();
-        single_inst_init(_prog_name, cb);
+        single_inst_init(_prog_name, callback, opt_entries);
         g_free(_prog_name);
         return FALSE;
     }
@@ -286,159 +322,3 @@ void get_socket_name(char* buf, int len)
                 g_get_user_name());
 }
 
-static GByteArray* send_buf_new(int cmd, SingleInstDataType type, int data_len)
-{
-    GByteArray* buf = g_byte_array_sized_new(1024);
-    gsize chunk_size = sizeof(gsize) + sizeof(cmd) + sizeof(type) + data_len;
-    g_byte_array_append(buf, (guint8*)&chunk_size, sizeof(chunk_size));
-    g_byte_array_append(buf, (guint8*)&cmd, sizeof(cmd));
-    g_byte_array_append(buf, (guint8*)&type, sizeof(type));
-    return buf;
-}
-
-static void send_and_free_buf(GByteArray* buf)
-{
-    char* pdata;
-    int len;
-    pdata = (char*)buf->data;
-    len = buf->len;
-    while( len > 0)
-    {
-        int r = write(sock, pdata, len);
-        if(r == -1)
-            break;
-        len -= r;
-        pdata += r;
-    }
-    g_byte_array_free(buf, TRUE);
-}
-
-inline static void send_data(int cmd, SingleInstDataType type, gpointer data, int len)
-{
-    GByteArray* buf = send_buf_new(cmd, type, len);
-    if(data)
-        g_byte_array_append(buf, (guint8*)data, len);
-    send_and_free_buf(buf);
-}
-
-void single_inst_send_bytes(int cmd, const char* data, int len)
-{
-    send_data(cmd, SID_BYTES, data, len);
-}
-
-void single_inst_send_str(int cmd, const char* str)
-{
-    send_data(cmd, SID_STR, str, str ? strlen(str) + 1 : 0);
-}
-
-void single_inst_send_strv(int cmd, const char** strv)
-{
-    GByteArray* buf;
-    int old_buf_len = 0;
-    gsize chunk_size;
-    int i, n;
-    buf = send_buf_new(cmd, SID_STRV, 0);
-    /* store old chunk size and original buf len */
-    memcpy(&chunk_size, buf->data, sizeof(chunk_size));
-    old_buf_len = buf->len;
-
-    n = strv ? g_strv_length(strv) : 0;
-    /* write number of strings in the vector */
-    g_byte_array_append(buf, &n, sizeof(n));
-    for( i = 0; i < n; ++i )
-    {
-        char* str = strv[i];
-        int slen = strlen(str) + 1;
-        /* write length of the string including '\0' */
-        g_byte_array_append(buf, &slen, sizeof(slen));
-        g_byte_array_append(buf, str, slen); /* write the string */
-    }
-
-    /* update chunk size */
-    chunk_size += (buf->len - old_buf_len);
-    memcpy(buf->data, &chunk_size, sizeof(chunk_size));
-
-    send_and_free_buf(buf);
-}
-
-void single_inst_send_int(int cmd, int val)
-{
-    send_data(cmd, SID_INT, &val, sizeof(val));
-}
-
-void single_inst_send_bool(int cmd, gboolean val)
-{
-    send_data(cmd, SID_BOOL, &val, sizeof(val));
-}
-
-char* single_inst_get_str(SingleInstCmdData* data, int* len)
-{
-    char* ret;
-    if(data->type != SID_STR)
-        return NULL;
-    if(data->len == 0) /* NULL string */
-        return NULL;
-    ret = g_new0(char, data->len);
-    memcpy(ret, data->data, data->len);
-    if(len)
-        *len = data->len - 1;
-    return ret;
-}
-
-char* single_inst_get_strv(SingleInstCmdData* data, int* len)
-{
-    int i, n;
-    char* pdata, *pend;
-    int data_len = data->len; /* length of the raw data */
-
-    if(data->type != SID_STRV)
-        return NULL;
-
-    pdata = data->data;
-    pend = pdata + data->len; /* end address of data chunk */
-
-    /* read number of strings in the vector */
-    memcpy(&n, pdata, sizeof(n));
-    pdata += sizeof(n);
-
-    if( n > 0)
-    {
-        char** ret = g_new0(char*, n + 1); /* allocate the array */
-        for(i = 0; i < n; ++i)
-        {
-            int slen;
-            char* str;
-            memcpy(&slen, pdata, sizeof(slen)); /* read length of strv[i] */
-            pdata += sizeof(slen);
-            if(pdata + slen > pend) /* out of boundary. an error is found. */
-            {
-                g_strfreev(ret);
-                return NULL;
-            }
-            str = g_new(char, slen);
-            memcpy(str, pdata, slen);
-            ret[i] = str;
-            pdata += slen; /* jump to next string */
-        }
-        if(len)
-            *len = i;
-        return ret;
-    }
-    return NULL;
-}
-
-gboolean single_inst_get_int(SingleInstCmdData* data, int* val)
-{
-    if(data->type != SID_INT)
-        return FALSE;
-    memcpy(val, data->data, sizeof(int));
-    return TRUE;
-}
-
-gboolean single_inst_get_bool(SingleInstCmdData* data, gboolean* val)
-{
-    if(data->type != SID_BOOL)
-        return FALSE;
-    memcpy(val, data->data, sizeof(gboolean));
-    return TRUE;
-}
diff --git a/src/single-inst.h b/src/single-inst.h
index e1a3b36..d372845 100644
--- a/src/single-inst.h
+++ b/src/single-inst.h
@@ -1,22 +1,23 @@
-//      single-inst.h: simple IPC mechanism for single instance app
-//      
-//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
-//      
-//      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.
-//      
-//      You should have received a copy of the GNU General Public License
-//      along with this program; if not, write to the Free Software
-//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-//      MA 02110-1301, USA.
-
+/*
+ *      single-inst.h: simple IPC mechanism for single instance app
+ *
+ *      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
+ *
+ *      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.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
 
 #ifndef __SINGLE_INST_H__
 #define __SINGLE_INST_H__
@@ -27,8 +28,6 @@ G_BEGIN_DECLS
 
 
 typedef enum _SingleInstResult  SingleInstResult;
-typedef enum _SingleInstDataType    SingleInstDataType;
-typedef struct _SingleInstCmdData  SingleInstCmdData;
 
 enum _SingleInstResult
 {
@@ -37,39 +36,11 @@ enum _SingleInstResult
     SINGLE_INST_ERROR
 };
 
-enum _SingleInstDataType
-{
-    SID_INVALID,
-    SID_BYTES,
-    SID_STR,
-    SID_STRV,
-    SID_INT,
-    SID_BOOL
-};
+typedef void (*SingleInstCallback)(const char* cwd, int workspace, int screen);
 
-struct _SingleInstCmdData
-{
-    SingleInstDataType type; /* type of data */
-    char* data; /* raw data */
-    int len; /* length of data */
-};
-
-typedef gboolean (*SingleInstCallback)(int cmd, SingleInstCmdData* data);
-
-SingleInstResult single_inst_init(const char* prog_name, SingleInstCallback _server_cmd_cb);
+SingleInstResult single_inst_init(const char* prog_name, SingleInstCallback cb, GOptionEntry* opt_entries);
 void single_inst_finalize();
 
-void single_inst_send_bytes(int cmd, const char* data, int len);
-void single_inst_send_str(int cmd, const char* str);
-void single_inst_send_strv(int cmd, const char** strv);
-void single_inst_send_int(int cmd, int val);
-void single_inst_send_bool(int cmd, gboolean val);
-
-char* single_inst_get_str(SingleInstCmdData* data, int* len);
-char* single_inst_get_strv(SingleInstCmdData* data, int* len);
-gboolean single_inst_get_int(SingleInstCmdData* data, int* val);
-gboolean single_inst_get_bool(SingleInstCmdData* data, gboolean* val);
-
 G_END_DECLS
 
 #endif /* __SINGLE_INST_H__ */
-- 
1.7.0.1


openSUSE Build Service is sponsored by