/* * This file part of gsopcast - A gtk front-end of p2p tv sopcast. * http://gsopcast.googlecode.com * Copyright (C) 2008 Ha Shao * * 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Handle remote command for the unique instance. * * Basically, we create a clipboard, say uniq_clipboard, as the inter-process * communication channel. * * At start up, check if we can get anything from the clipboard. * * If not, we are the first instance, we set the clipboard content to "NONE". * We then connect to the "owner-change" signal of the clipboard. remote * commands will come from the clipboard. When we receive a new command from * the clipboard, we reset the clipboard content back to "NONE". * * If yes, there is a instance running. We paste a command to the clipboard * from the new instance. Then we sit on the new instance and wait the clipboard * content change to "NONE" again, i.e. the first instance handled our request * already. Once the command is handled, we quit the remote instance. * * There might be some race-conditions, but we are creating a *simple* unique * instance function. Big deal. * * If we want a complete solution, we will use gtkunique when it is widely spead. */ #include #include #include "unique.h" #include "callbacks.h" // Return the selection/clipboard for our unique instance atom. GtkClipboard* get_unique_clip(){ GdkAtom atom; GtkClipboard *clip; #if GTK_CHECK_VERSION(2,10,0) atom = gdk_atom_intern_static_string(unique_clipboard_name); #else atom = gdk_atom_intern(unique_clipboard_name, FALSE); #endif clip = gtk_clipboard_get(atom); return clip; } // Check if there is already a instance running. gboolean is_running(){ GdkAtom atom; GtkClipboard *clip; gboolean ret = FALSE; clip = get_unique_clip(); if(gtk_clipboard_wait_is_text_available(clip)){ ret = TRUE; } return ret; } // For the main instance, setup clipboard to accept uri remote command. void setup_unique(void){ GtkClipboard *clip; clip = get_unique_clip(); g_signal_connect(clip, "owner-change", G_CALLBACK(remote_call), NULL); } // Set a text to the clipboard void unique_set_text(const gchar *text, gboolean store){ GtkClipboard *clip; clip = get_unique_clip(); gtk_clipboard_set_text(clip, text, strlen(text)); } //------------------------------------------------------ //Dealing with remote instance. /* Wait for the remote changed the clipboard to NONE before we quit. */ gboolean timeout_me(void *data){ gchar *text; GtkClipboard *clip = GTK_CLIPBOARD(data); text = gtk_clipboard_wait_for_text(clip); if (text && (strcmp(text, "NONE") == 0)){ gtk_main_quit(); return FALSE; } if (text) g_free(text); return TRUE; } // Some bridge function. void quit_on_owner_change(GtkClipboard *clip, GdkEvent *event, gpointer data){ g_timeout_add(200, timeout_me, clip); } /* Paste uri to clipboard and quit. * Cannot quit immediately because the remote instance need us to get the * uri from the clipboard. If we quit, the clipboard will be reset immediately. */ void unique_paste_uri(const gchar *text){ GtkClipboard *clip; clip = get_unique_clip(); gtk_clipboard_clear(clip); gtk_clipboard_set_text(clip, text, strlen(text)); g_signal_connect(clip, "owner-change", G_CALLBACK(quit_on_owner_change), NULL); gtk_main(); }