Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4
pcmanfm
pcmanfm-0.9.8-fixbnc648882.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor