Mercurial > pidgin.yaz
comparison plugins/musicmessaging/musicmessaging.c @ 11200:4295083cf489
[gaim-migrate @ 13328]
Added dbus capabilities to the mm plugin
committer: Tailor Script <tailor@pidgin.im>
author | Christian Muise <christian.muise@gmail.com> |
---|---|
date | Mon, 08 Aug 2005 01:40:41 +0000 |
parents | 778d5464a9b8 |
children | 1b32ad61e114 |
comparison
equal
deleted
inserted
replaced
11199:30a3d97503be | 11200:4295083cf489 |
---|---|
1 /* | |
2 * Music messaging plugin for Gaim | |
3 * | |
4 * Copyright (C) 2005 Christian Muise. | |
5 * | |
6 * This program is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU General Public License as | |
8 * published by the Free Software Foundation; either version 2 of the | |
9 * License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 * 02111-1307, USA. | |
20 */ | |
21 | |
1 #include "internal.h" | 22 #include "internal.h" |
2 #include "gtkgaim.h" | 23 #include "gtkgaim.h" |
3 | 24 |
4 #include "conversation.h" | 25 #include "conversation.h" |
5 | 26 |
7 #include "gtkplugin.h" | 28 #include "gtkplugin.h" |
8 #include "gtkutils.h" | 29 #include "gtkutils.h" |
9 | 30 |
10 #include "notify.h" | 31 #include "notify.h" |
11 #include "version.h" | 32 #include "version.h" |
12 | 33 #include "debug.h" |
13 #define MUSICMESSAGIN_PLUGIN_ID "gtk-hazure-musicmessaging" | 34 |
14 | 35 #define DBUS_API_SUBJECT_TO_CHANGE |
15 static gboolean start_session(void); | 36 #include <dbus/dbus.h> |
16 static void run_editor(void); | 37 #include "dbus-maybe.h" |
17 static void add_button (GaimConversation *conv); | 38 #include "dbus-bindings.h" |
18 static void remove_button (GtkWidget *button); | 39 #include "dbus-server.h" |
19 | 40 |
20 typedef struct { | 41 #define MUSICMESSAGING_PLUGIN_ID "gtk-hazure-musicmessaging" |
21 GaimBuddy *buddy; | 42 #define MUSICMESSAGING_PREFIX "##MM##" |
22 GtkWidget *window; | 43 #define MUSICMESSAGING_START_TAG "<a href=mm-plugin>" |
23 /* Something for the ly file? */ | 44 |
24 | 45 /* Globals */ |
25 /* Anything else needed for a session? */ | |
26 | |
27 } MMSession; | |
28 | |
29 /* List of sessions */ | 46 /* List of sessions */ |
30 GList *sessions; | 47 GList *conversations; |
31 | |
32 /* List of created buttons */ | |
33 GList *widgets; | |
34 | 48 |
35 /* Pointer to this plugin */ | 49 /* Pointer to this plugin */ |
36 GaimPlugin *plugin_pointer; | 50 GaimPlugin *plugin_pointer; |
37 | 51 |
52 /* Define types needed for DBus */ | |
53 | |
54 /* Define the functions to export for use with DBus */ | |
55 DBUS_EXPORT void music_messaging_change_request (const char *command, const char *parameters); | |
56 DBUS_EXPORT void music_messaging_change_confirmed (const char *command, const char *parameters); | |
57 DBUS_EXPORT void music_messaging_change_failed (const char *id, const char *command, const char *parameters); | |
58 DBUS_EXPORT void music_messaging_done_session (void); | |
59 | |
60 /* This file has been generated by the #dbus-analize-functions.py | |
61 script. It contains dbus wrappers for the four functions declared | |
62 above. */ | |
63 #include "music-messaging-bindings.c" | |
64 | |
65 /* Exported functions */ | |
66 void music_messaging_change_request(const char *command, const char *parameters) | |
67 { | |
68 gaim_notify_message(plugin_pointer, GAIM_NOTIFY_MSG_INFO, command, | |
69 parameters, NULL, NULL, NULL); | |
70 } | |
71 | |
72 void music_messaging_change_confirmed(const char *command, const char *parameters) | |
73 { | |
74 gaim_notify_message(plugin_pointer, GAIM_NOTIFY_MSG_INFO, command, | |
75 parameters, NULL, NULL, NULL); | |
76 } | |
77 | |
78 void music_messaging_change_failed(const char *id, const char *command, const char *parameters) | |
79 { | |
80 gaim_notify_message(plugin_pointer, GAIM_NOTIFY_MSG_INFO, command, | |
81 parameters, NULL, NULL, NULL); | |
82 } | |
83 | |
84 void music_messaging_done_session(void) | |
85 { | |
86 gaim_notify_message(plugin_pointer, GAIM_NOTIFY_MSG_INFO, "Session", | |
87 "Session Complete", NULL, NULL, NULL); | |
88 } | |
89 | |
90 typedef struct { | |
91 GaimConversation *conv; /* pointer to the conversation */ | |
92 GtkWidget *seperator; /* seperator in the conversation */ | |
93 GtkWidget *button; /* button in the conversation */ | |
94 GPid pid; /* the pid of the score editor */ | |
95 | |
96 gboolean started; /* session has started and editor run */ | |
97 gboolean originator; /* started the mm session */ | |
98 gboolean requested; /* received a request to start a session */ | |
99 | |
100 } MMConversation; | |
101 | |
102 static gboolean start_session(MMConversation *mmconv); | |
103 static void run_editor(MMConversation *mmconv); | |
104 static void kill_editor(MMConversation *mmconv); | |
105 static void add_button (MMConversation *mmconv); | |
106 static void remove_widget (GtkWidget *button); | |
107 static void init_conversation (GaimConversation *conv); | |
108 static void conv_destroyed(GaimConversation *conv); | |
109 static void intercept_sent(GaimAccount *account, GaimConversation *conv, char **message, void* pData); | |
110 static void intercept_received(GaimAccount *account, char **sender, char **message, GaimConversation *conv, int *flags); | |
111 | |
112 | |
113 G_BEGIN_DECLS | |
114 DBusConnection *gaim_dbus_get_connection(void); | |
115 G_END_DECLS | |
116 | |
117 void send_change_request (const char *id, const char *command, const char *parameters) | |
118 { | |
119 DBusMessage *signal; | |
120 signal = dbus_message_new_signal("/org/gscore/GScoreObject", "org.gscore.GScoreInterface", "gscore_change_request"); | |
121 | |
122 dbus_message_append_args(signal, | |
123 DBUS_TYPE_STRING, &id, | |
124 DBUS_TYPE_STRING, &command, | |
125 DBUS_TYPE_STRING, ¶meters, | |
126 DBUS_TYPE_INVALID); | |
127 | |
128 dbus_connection_send(gaim_dbus_get_connection(), signal, NULL); | |
129 dbus_message_unref(signal); | |
130 } | |
131 | |
132 void send_change_confirmed (const char *command, const char *parameters) | |
133 { | |
134 DBusMessage *signal; | |
135 signal = dbus_message_new_signal("/org/gscore/GScoreObject", "org.gscore.GScoreInterface", "gscore_change_confirmed"); | |
136 | |
137 dbus_message_append_args(signal, | |
138 DBUS_TYPE_STRING, &command, | |
139 DBUS_TYPE_STRING, ¶meters, | |
140 DBUS_TYPE_INVALID); | |
141 | |
142 dbus_connection_send(gaim_dbus_get_connection(), signal, NULL); | |
143 dbus_message_unref(signal); | |
144 } | |
145 | |
146 | |
38 static gboolean | 147 static gboolean |
39 plugin_load(GaimPlugin *plugin) { | 148 plugin_load(GaimPlugin *plugin) { |
40 gaim_notify_message(plugin, GAIM_NOTIFY_MSG_INFO, "Welcome", | 149 /* First, we have to register our four exported functions with the |
150 main gaim dbus loop. Without this statement, the gaim dbus | |
151 code wouldn't know about our functions. */ | |
152 GAIM_DBUS_REGISTER_BINDINGS(plugin); | |
153 | |
154 gaim_notify_message(plugin, GAIM_NOTIFY_MSG_INFO, "Welcome", | |
41 "Welcome to music messaging.", NULL, NULL, NULL); | 155 "Welcome to music messaging.", NULL, NULL, NULL); |
42 /* Keep the plugin for reference (needed for notify's) */ | 156 /* Keep the plugin for reference (needed for notify's) */ |
43 plugin_pointer = plugin; | 157 plugin_pointer = plugin; |
44 | 158 |
45 /* Add the button to all the current conversations */ | 159 /* Add the button to all the current conversations */ |
46 gaim_conversation_foreach (add_button); | 160 gaim_conversation_foreach (init_conversation); |
47 | 161 |
48 /* Listen for any new conversations */ | 162 /* Listen for any new conversations */ |
49 void *conv_list_handle = gaim_conversations_get_handle(); | 163 void *conv_list_handle = gaim_conversations_get_handle(); |
50 | 164 |
51 gaim_signal_connect(conv_list_handle, "conversation-created", | 165 gaim_signal_connect(conv_list_handle, "conversation-created", |
52 plugin, GAIM_CALLBACK(add_button), NULL); | 166 plugin, GAIM_CALLBACK(init_conversation), NULL); |
167 | |
168 /* Listen for conversations that are ending */ | |
169 gaim_signal_connect(conv_list_handle, "deleting-conversation", | |
170 plugin, GAIM_CALLBACK(conv_destroyed), NULL); | |
171 | |
172 /* Listen for sending/receiving messages to replace tags */ | |
173 gaim_signal_connect(conv_list_handle, "writing-im-msg", | |
174 plugin, GAIM_CALLBACK(intercept_sent), NULL); | |
175 gaim_signal_connect(conv_list_handle, "receiving-im-msg", | |
176 plugin, GAIM_CALLBACK(intercept_received), NULL); | |
53 | 177 |
54 return TRUE; | 178 return TRUE; |
55 } | 179 } |
56 | 180 |
57 static gboolean | 181 static gboolean |
58 plugin_unload(GaimPlugin *plugin) { | 182 plugin_unload(GaimPlugin *plugin) { |
59 | 183 |
60 gaim_notify_message(plugin, GAIM_NOTIFY_MSG_INFO, "Unloaded", | 184 gaim_notify_message(plugin, GAIM_NOTIFY_MSG_INFO, "Unloaded", |
61 gaim_prefs_get_string ("/plugins/gtk/musicmessaging/editor_path"), NULL, NULL, NULL); | 185 DATADIR, NULL, NULL, NULL); |
62 | 186 |
63 g_list_foreach(widgets, (GFunc) remove_button, NULL); | 187 MMConversation *mmconv = NULL; |
188 while (g_list_length(conversations) > 0) | |
189 { | |
190 mmconv = g_list_first(conversations)->data; | |
191 conv_destroyed(mmconv->conv); | |
192 } | |
64 return TRUE; | 193 return TRUE; |
65 } | 194 } |
66 | 195 |
196 static void intercept_sent(GaimAccount *account, GaimConversation *conv, char **message, void* pData) | |
197 { | |
198 GaimConvIm *imData = gaim_conversation_get_im_data(conv); | |
199 GaimConnection *connection = gaim_conversation_get_gc(conv); | |
200 const char *convName = gaim_conversation_get_name(conv); | |
201 const char *who = gaim_account_get_username(account); | |
202 | |
203 if (0 == strncmp(*message, MUSICMESSAGING_PREFIX, strlen(MUSICMESSAGING_PREFIX))) | |
204 { | |
205 message = 0; | |
206 gaim_debug(GAIM_DEBUG_MISC, "gaim-musicmessaging", "Received MM Message\n"); | |
207 send_change_confirmed("the command", "the params"); | |
208 } | |
209 else if (0 == strncmp(*message, MUSICMESSAGING_START_TAG, strlen(MUSICMESSAGING_START_TAG))) | |
210 { | |
211 | |
212 } | |
213 else | |
214 { | |
215 serv_send_im(connection, convName, *message, GAIM_MESSAGE_SEND); | |
216 gaim_conv_im_write (imData, NULL, *message, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
217 } | |
218 } | |
219 | |
220 static void intercept_received(GaimAccount *account, char **sender, char **message, GaimConversation *conv, int *flags) | |
221 { | |
222 | |
223 } | |
224 | |
225 | |
67 static gboolean | 226 static gboolean |
68 start_session(void) | 227 start_session(MMConversation *mmconv) |
69 { | 228 { |
70 run_editor(); | 229 mmconv->started = TRUE; |
230 run_editor(mmconv); | |
71 return TRUE; | 231 return TRUE; |
72 } | 232 } |
73 | 233 |
74 static void music_button_toggled (GtkWidget *widget, gpointer data) | 234 static void music_button_toggled (GtkWidget *widget, gpointer data) |
75 { | 235 { |
76 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) | 236 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) |
77 { | 237 { |
78 start_session(); | 238 start_session((MMConversation *) data); |
79 } else { | 239 } else { |
80 | 240 kill_editor((MMConversation *) data); |
81 /* kill program */ | |
82 } | 241 } |
83 } | 242 } |
84 | 243 |
85 static void set_editor_path (GtkWidget *button, GtkWidget *text_field) | 244 static void set_editor_path (GtkWidget *button, GtkWidget *text_field) |
86 { | 245 { |
87 const char * path = gtk_entry_get_text((GtkEntry*)text_field); | 246 const char * path = gtk_entry_get_text((GtkEntry*)text_field); |
88 gaim_prefs_set_string("/plugins/gtk/musicmessaging/editor_path", path); | 247 gaim_prefs_set_string("/plugins/gtk/musicmessaging/editor_path", path); |
89 | 248 |
90 } | 249 } |
91 | 250 |
92 static void run_editor (void) | 251 static void run_editor (MMConversation *mmconv) |
93 { | 252 { |
94 GError *spawn_error = NULL; | 253 GError *spawn_error = NULL; |
95 gchar * args[2]; | 254 gchar * args[2]; |
96 args[0] = (gchar *)gaim_prefs_get_string("/plugins/gtk/musicmessaging/editor_path"); | 255 args[0] = (gchar *)gaim_prefs_get_string("/plugins/gtk/musicmessaging/editor_path"); |
97 args[1] = NULL; | 256 args[1] = NULL; |
98 if (!(g_spawn_async (".", args, NULL, 0, NULL, NULL, NULL, &spawn_error))) | 257 if (!(g_spawn_async (".", args, NULL, 12, NULL, NULL, &(mmconv->pid), &spawn_error))) |
99 { | 258 { |
100 gaim_notify_error(plugin_pointer, "Error Running Editor", | 259 gaim_notify_error(plugin_pointer, "Error Running Editor", |
101 "The following error has occured:", spawn_error->message); | 260 "The following error has occured:", spawn_error->message); |
102 } | 261 } |
103 } | 262 } |
104 | 263 |
105 static void add_button (GaimConversation *conv) | 264 static void kill_editor (MMConversation *mmconv) |
106 { | 265 { |
266 if (mmconv->pid) | |
267 { | |
268 kill(mmconv->pid, SIGINT); | |
269 mmconv->pid = 0; | |
270 } | |
271 } | |
272 | |
273 static void init_conversation (GaimConversation *conv) | |
274 { | |
275 MMConversation *mmconv; | |
276 mmconv = g_malloc(sizeof(MMConversation)); | |
277 | |
278 mmconv->conv = conv; | |
279 mmconv->started = FALSE; | |
280 mmconv->originator = FALSE; | |
281 mmconv->requested = FALSE; | |
282 | |
283 add_button(mmconv); | |
284 | |
285 conversations = g_list_append(conversations, mmconv); | |
286 } | |
287 | |
288 static void conv_destroyed (GaimConversation *conv) | |
289 { | |
290 MMConversation *mmconv_current = NULL; | |
291 MMConversation *mmconv = NULL; | |
292 guint i; | |
293 | |
294 for (i = 0; i < g_list_length(conversations); i++) | |
295 { | |
296 mmconv_current = (MMConversation *)g_list_nth_data(conversations, i); | |
297 if (conv == mmconv_current->conv) | |
298 { | |
299 mmconv = mmconv_current; | |
300 } | |
301 } | |
302 | |
303 remove_widget(mmconv->button); | |
304 remove_widget(mmconv->seperator); | |
305 if (mmconv->started) | |
306 { | |
307 kill_editor(mmconv); | |
308 } | |
309 conversations = g_list_remove(conversations, mmconv); | |
310 } | |
311 | |
312 static void add_button (MMConversation *mmconv) | |
313 { | |
314 GaimConversation *conv = mmconv->conv; | |
315 | |
107 GtkWidget *button, *image, *sep; | 316 GtkWidget *button, *image, *sep; |
108 | 317 |
109 button = gtk_toggle_button_new(); | 318 button = gtk_toggle_button_new(); |
110 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); | 319 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); |
111 | 320 |
112 g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(music_button_toggled), NULL); | 321 g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(music_button_toggled), mmconv); |
113 | 322 |
114 gchar *file_path = g_build_filename (DATADIR, "pixmaps", "gaim", "buttons", "music.png", NULL); | 323 gchar *file_path = g_build_filename (DATADIR, "pixmaps", "gaim", "buttons", "music.png", NULL); |
115 image = gtk_image_new_from_file("/usr/local/share/pixmaps/gaim/buttons/music.png"); | 324 image = gtk_image_new_from_file("/usr/local/share/pixmaps/gaim/buttons/music.png"); |
116 | 325 |
117 gtk_container_add((GtkContainer *)button, image); | 326 gtk_container_add((GtkContainer *)button, image); |
118 | 327 |
119 sep = gtk_vseparator_new(); | 328 sep = gtk_vseparator_new(); |
120 | 329 |
121 g_list_append(widgets, sep); | 330 mmconv->seperator = sep; |
122 g_list_append(widgets, button); | 331 mmconv->button = button; |
123 | 332 |
124 gtk_widget_show(sep); | 333 gtk_widget_show(sep); |
125 gtk_widget_show(image); | 334 gtk_widget_show(image); |
126 gtk_widget_show(button); | 335 gtk_widget_show(button); |
127 | 336 |
128 gtk_box_pack_start(GTK_BOX(GAIM_GTK_CONVERSATION(conv)->toolbar), sep, FALSE, FALSE, 0); | 337 gtk_box_pack_start(GTK_BOX(GAIM_GTK_CONVERSATION(conv)->toolbar), sep, FALSE, FALSE, 0); |
129 gtk_box_pack_start(GTK_BOX(GAIM_GTK_CONVERSATION(conv)->toolbar), button, FALSE, FALSE, 0); | 338 gtk_box_pack_start(GTK_BOX(GAIM_GTK_CONVERSATION(conv)->toolbar), button, FALSE, FALSE, 0); |
130 } | 339 } |
131 | 340 |
132 static void remove_button (GtkWidget *button) | 341 static void remove_widget (GtkWidget *button) |
133 { | 342 { |
134 gtk_widget_hide(button); | 343 gtk_widget_hide(button); |
135 gtk_widget_destroy(button); | 344 gtk_widget_destroy(button); |
136 } | 345 } |
137 | 346 |
184 GAIM_GTK_PLUGIN_TYPE, | 393 GAIM_GTK_PLUGIN_TYPE, |
185 0, | 394 0, |
186 NULL, | 395 NULL, |
187 GAIM_PRIORITY_DEFAULT, | 396 GAIM_PRIORITY_DEFAULT, |
188 | 397 |
189 MUSICMESSAGIN_PLUGIN_ID, | 398 MUSICMESSAGING_PLUGIN_ID, |
190 "Music Messaging", | 399 "Music Messaging", |
191 VERSION, | 400 VERSION, |
192 "Music Messaging Plugin for collabrative composition.", | 401 "Music Messaging Plugin for collabrative composition.", |
193 "The Music Messaging Plugin allows a number of users to simultaniously work on a piece of music by editting a common score in real-time.", | 402 "The Music Messaging Plugin allows a number of users to simultaniously work on a piece of music by editting a common score in real-time.", |
194 "Christian Muise <christian.muise@gmail.com>", | 403 "Christian Muise <christian.muise@gmail.com>", |