Mercurial > pidgin
annotate plugins/ticker/ticker.c @ 4359:5fb47ec9bfe4
[gaim-migrate @ 4625]
Wow, okay, where to begin with this one ;)
I rewrote the whole conversation backend. It is now core/UI split. Here's
how it works..
Every conversation is represented by a gaim_conversation structure. This
branches out into gaim_im and gaim_chat structures. Every conversation
lives in (well, normally, but it doesn't have to) a gaim_window structure.
This is a _CORE_ representation of a window. There can be multiple
gaim_window structures around.
The gaim_window and gaim_conversation structures have UI-specific operation
structures associated with them. At the moment, the only UI is GTK+, and
this will be for some time. Don't start thinking you can write a QT UI now.
It's just not going to happen.
Everything that is done on a conversation is done through the core API.
This API does core processing and then calls the UI operations for the
rendering and anything else.
Now, what does this give the user?
- Multiple windows.
- Multiple tabs per window.
- Draggable tabs.
- Send As menu is moved to the menubar.
- Menubar for chats.
- Some very cool stuff in the future, like replacing, say, IRC chat windows
with an X-Chat interface, or whatever.
- Later on, customizable window/conversation positioning.
For developers:
- Fully documented API
- Core/UI split
- Variable checking and mostly sane handling of incorrect variables.
- Logical structure to conversations, both core and UI.
- Some very cool stuff in the future, like replacing, say, IRC chat windows
with an X-Chat interface, or whatever.
- Later on, customizable window/conversation positioning.
- Oh yeah, and the beginning of a stock icon system.
Now, there are things that aren't there yet. You will see tabs even if you
have them turned off. This will be fixed in time. Also, the preferences
will change to work with the new structure. I'm starting school in 2 days,
so it may not be done immediately, but hopefully in the next week.
Enjoy!
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Mon, 20 Jan 2003 09:10:23 +0000 |
parents | 0c68d402f59f |
children | 62c1e5e656d0 |
rev | line source |
---|---|
3391 | 1 /* GTK - The GIMP Toolkit |
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald | |
3 * | |
4 * This library is free software; you can redistribute it and/or | |
5 * modify it under the terms of the GNU Library General Public | |
6 * License as published by the Free Software Foundation; either | |
7 * version 2 of the License, or (at your option) any later version. | |
8 * | |
9 * This library is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 * Library General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU Library General Public | |
15 * License along with this library; if not, write to the | |
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
17 * Boston, MA 02111-1307, USA. | |
18 */ | |
19 | |
20 /* | |
21 * ticker.c -- Syd Logan, Summer 2000 | |
22 * pluginized- Sean Egan, Summer 2002 | |
23 */ | |
24 | |
25 | |
26 #include <gtk/gtk.h> | |
27 #include "gtkticker.h" | |
28 #include <string.h> | |
29 #include <stdlib.h> | |
30 #include "gaim.h" | |
31 #include "prpl.h" | |
32 #include "pixmaps/no_icon.xpm" | |
3630 | 33 #ifdef _WIN32 |
34 #include "win32dep.h" | |
35 #endif | |
3391 | 36 |
3867 | 37 #ifndef GAIM_PLUGINS |
38 #define GAIM_PLUGINS | |
39 #endif | |
40 | |
3391 | 41 static GtkWidget *tickerwindow = NULL; |
42 static GtkWidget *ticker; | |
43 static GModule *handle; | |
44 | |
45 typedef struct { | |
46 char buddy[ 128 ]; | |
47 char alias[ 388 ]; | |
48 GtkWidget *hbox; | |
49 GtkWidget *ebox; | |
50 GtkWidget *label; | |
51 GtkWidget *pix; | |
52 } TickerData; | |
53 | |
54 GList *tickerbuds = (GList *) NULL; | |
55 gboolean userclose = FALSE; | |
56 GtkWidget *msgw; | |
57 | |
3630 | 58 /* for win32 compatability */ |
59 G_MODULE_IMPORT GSList *connections; | |
60 G_MODULE_IMPORT GtkWidget *blist; | |
61 | |
3391 | 62 void BuddyTickerDestroyWindow( GtkWidget *window ); |
63 void BuddyTickerCreateWindow( void ); | |
64 void BuddyTickerAddUser( char *name, char *alias, GdkPixmap *pm, GdkBitmap *bm ); | |
65 void BuddyTickerRemoveUser( char *name ); | |
66 void BuddyTickerSetPixmap( char *name, GdkPixmap *pm, GdkBitmap *bm ); | |
67 void BuddyTickerClearList( void ); | |
68 void BuddyTickerSignOff( void ); | |
69 GList * BuddyTickerFindUser( char *name ); | |
70 int BuddyTickerMessageRemove( gpointer data ); | |
71 void BuddyTickerShow(); | |
72 | |
73 void | |
74 BuddyTickerDestroyWindow( GtkWidget *window ) | |
75 { | |
76 BuddyTickerClearList(); | |
77 gtk_ticker_stop_scroll( GTK_TICKER( ticker ) ); | |
78 gtk_widget_destroy( window ); | |
79 ticker = tickerwindow = (GtkWidget *) NULL; | |
80 userclose = TRUE; | |
81 } | |
82 | |
3466 | 83 /* static char *msg = "Welcome to Gaim " VERSION ", brought to you by Rob Flynn (maintainer), Eric Warmenhoven, Mark Spencer, Jeramey Crawford, Jim Duchek, Syd Logan, and Sean Egan"; |
84 */ | |
3391 | 85 |
86 void | |
87 BuddyTickerCreateWindow() | |
88 { | |
89 | |
90 if ( tickerwindow != (GtkWidget *) NULL ) | |
91 return; | |
92 debug_printf("Making ticker\n"); | |
93 tickerwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); | |
4165
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4074
diff
changeset
|
94 g_signal_connect (GTK_OBJECT(tickerwindow), "destroy", |
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4074
diff
changeset
|
95 G_CALLBACK (BuddyTickerDestroyWindow), "WM destroy"); |
3391 | 96 gtk_window_set_title (GTK_WINDOW(tickerwindow), "Gaim - Buddy Ticker"); |
4074 | 97 gtk_window_set_role (GTK_WINDOW(tickerwindow), "ticker"); |
3391 | 98 gtk_widget_realize(tickerwindow); |
99 | |
100 ticker = gtk_ticker_new(); | |
101 if (!ticker) | |
102 return; | |
103 gtk_ticker_set_spacing( GTK_TICKER( ticker ), 20 ); | |
104 gtk_widget_set_usize( ticker, 500, -1 ); | |
105 gtk_container_add( GTK_CONTAINER( tickerwindow ), ticker ); | |
106 gtk_ticker_set_interval( GTK_TICKER( ticker ), 500 ); | |
107 gtk_ticker_set_scootch( GTK_TICKER( ticker ), 10 ); | |
108 /* Damned egotists | |
109 msgw = gtk_label_new( msg ); | |
110 gtk_ticker_add( GTK_TICKER( ticker ), msgw ); | |
111 */ | |
112 gtk_ticker_start_scroll( GTK_TICKER( ticker ) ); | |
113 | |
4168 | 114 g_timeout_add( 60000, BuddyTickerMessageRemove, NULL); |
3391 | 115 |
4168 | 116 gtk_widget_show_all (ticker); |
3391 | 117 |
118 } | |
119 | |
120 gint | |
121 ButtonPressCallback( GtkWidget *widget, GdkEvent *event, gpointer callback_data ) | |
122 { | |
123 TickerData *p = (TickerData *) callback_data; | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
124 gaim_conversation_new(GAIM_CONV_IM, p->buddy); |
3391 | 125 |
126 return TRUE; | |
127 } | |
128 | |
129 void | |
130 BuddyTickerAddUser( char *name, char *alias, GdkPixmap *pm, GdkBitmap *bm ) | |
131 { | |
132 TickerData *p; | |
133 GList *q; | |
134 | |
135 if ( userclose == TRUE ) | |
136 return; | |
137 | |
138 debug_printf("Adding %s\n", name); | |
139 | |
140 BuddyTickerCreateWindow(); | |
141 if (!ticker) | |
142 return; | |
143 | |
144 q = (GList *) BuddyTickerFindUser( name ); | |
145 if ( q != (GList *) NULL ) | |
146 return; | |
147 | |
148 p = (TickerData *) malloc( sizeof( TickerData ) ); | |
149 p->hbox = (GtkWidget *) NULL; | |
150 p->label = (GtkWidget *) NULL; | |
151 p->pix = (GtkWidget *) NULL; | |
152 strcpy( p->buddy, name ); | |
153 strcpy( p->alias, alias); | |
154 tickerbuds = g_list_append( tickerbuds, p ); | |
155 | |
156 p->hbox = gtk_hbox_new( FALSE, 0 ); | |
157 gtk_ticker_add( GTK_TICKER( ticker ), p->hbox ); | |
158 gtk_widget_show_all( p->hbox ); | |
159 | |
160 BuddyTickerSetPixmap( name, pm, bm ); | |
161 | |
162 p->ebox = gtk_event_box_new(); | |
163 | |
164 /* click detection */ | |
165 | |
166 gtk_widget_set_events (p->ebox, GDK_BUTTON_PRESS_MASK); | |
4165
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4074
diff
changeset
|
167 g_signal_connect (GTK_OBJECT (p->ebox), "button_press_event", |
07a3d1fae88f
[gaim-migrate @ 4394]
Christian Hammond <chipx86@chipx86.com>
parents:
4074
diff
changeset
|
168 G_CALLBACK(ButtonPressCallback), (gpointer) p); |
3391 | 169 |
170 gtk_box_pack_start_defaults( GTK_BOX( p->hbox ), p->ebox ); | |
171 gtk_widget_show( p->ebox ); | |
172 | |
173 if (im_options & OPT_IM_ALIAS_TAB) | |
174 p->label = gtk_label_new( alias ); | |
175 else | |
176 p->label = gtk_label_new( name ); | |
177 gtk_container_add( GTK_CONTAINER(p->ebox), p->label ); | |
178 | |
179 gtk_widget_show( p->label ); | |
180 | |
181 gtk_widget_show( tickerwindow ); | |
182 } | |
183 | |
184 void | |
185 BuddyTickerRemoveUser( char *name ) | |
186 { | |
187 GList *p = (GList *) BuddyTickerFindUser( name ); | |
188 TickerData *data; | |
189 | |
190 if ( !p ) | |
191 return; | |
192 | |
193 data = (TickerData *) p->data; | |
194 | |
195 if ( userclose == TRUE ) | |
196 return; | |
197 if ( data ) { | |
198 gtk_ticker_remove( GTK_TICKER( ticker ), data->hbox ); | |
199 tickerbuds = g_list_remove( tickerbuds, data ); | |
200 free( data ); | |
201 } | |
202 } | |
203 | |
204 void | |
205 BuddyTickerSetPixmap( char *name, GdkPixmap *pm, GdkBitmap *bm ) | |
206 { | |
207 GList *p; | |
208 TickerData *data; | |
209 | |
210 if ( userclose == TRUE ) | |
211 return; | |
212 p = (GList *) BuddyTickerFindUser( name ); | |
213 if ( p ) | |
214 data = (TickerData *) p->data; | |
215 else | |
216 return; | |
217 if ( data->pix == (GtkWidget *) NULL ) { | |
218 data->pix = gtk_pixmap_new( pm, bm ); | |
219 gtk_box_pack_start_defaults( GTK_BOX( data->hbox ), data->pix ); | |
220 } else { | |
221 gtk_widget_hide( data->pix ); | |
222 gtk_pixmap_set(GTK_PIXMAP(data->pix), pm, bm); | |
223 } | |
224 gtk_widget_show( data->pix ); | |
225 } | |
226 | |
227 void | |
228 BuddyTickerSetAlias( char *name, char *alias) { | |
229 GList *p; | |
230 TickerData *data; | |
231 | |
232 if ( userclose == TRUE ) | |
233 return; | |
234 p = (GList *) BuddyTickerFindUser( name ); | |
235 if ( p ) | |
236 data = (TickerData *) p->data; | |
237 else | |
238 return; | |
239 if (alias) { | |
240 g_snprintf(data->alias, sizeof(data->alias), alias); | |
241 | |
242 if (im_options & OPT_IM_ALIAS_TAB) | |
243 gtk_label_set_text(GTK_LABEL(data->label), alias); | |
244 } | |
245 } | |
246 | |
247 GList * | |
248 BuddyTickerFindUser( char *name ) | |
249 { | |
250 GList *p = tickerbuds; | |
251 | |
252 while ( p ) { | |
253 TickerData *q = (TickerData *) p->data; | |
254 if ( !strcmp( name, q->buddy ) ) | |
255 return( p ); | |
256 p = p->next; | |
257 } | |
258 return (GList *) NULL; | |
259 } | |
260 | |
261 void | |
262 BuddyTickerSetNames() | |
263 { | |
264 GList *p = tickerbuds; | |
265 while ( p ) { | |
266 TickerData *q = (TickerData *) p->data; | |
267 if (im_options & OPT_IM_ALIAS_TAB) | |
268 gtk_label_set_text(GTK_LABEL(q->label), q->alias); | |
269 else | |
270 gtk_label_set_text(GTK_LABEL(q->label), q->buddy); | |
271 p = p->next; | |
272 } | |
273 } | |
274 | |
275 int | |
276 BuddyTickerMessageRemove( gpointer data ) | |
277 { | |
278 if ( userclose == TRUE ) | |
279 return FALSE; | |
280 if ( tickerwindow == NULL ) | |
281 return FALSE; | |
282 gtk_ticker_remove( GTK_TICKER( ticker ), msgw ); | |
283 return FALSE; | |
284 } | |
285 | |
286 int | |
287 BuddyTickerLogonTimeout( gpointer data ) | |
288 { | |
289 return FALSE; | |
290 } | |
291 | |
292 int | |
293 BuddyTickerLogoutTimeout( gpointer data ) | |
294 { | |
295 char *name = (char *) data; | |
296 | |
297 if ( userclose == TRUE ) | |
298 return FALSE; | |
299 BuddyTickerRemoveUser( name ); | |
300 | |
301 return FALSE; | |
302 } | |
303 | |
304 void | |
305 BuddyTickerSignoff( void ) | |
306 { | |
307 GList *p = tickerbuds; | |
308 TickerData *q; | |
309 | |
310 while ( p ) { | |
311 q = (TickerData *) p->data; | |
312 if ( q ) | |
313 BuddyTickerRemoveUser( q->buddy ); | |
314 p = tickerbuds; | |
315 } | |
316 userclose = FALSE; | |
317 if ( tickerwindow ) | |
318 gtk_widget_hide( tickerwindow ); | |
319 } | |
320 | |
321 void | |
322 BuddyTickerClearList( void ) | |
323 { | |
324 GList *p = tickerbuds; | |
325 | |
326 while ( p ) | |
327 p = g_list_remove( p, p->data ); | |
328 tickerbuds = (GList *) NULL; | |
329 } | |
330 | |
331 void BuddyTickerShow() | |
332 { | |
333 GdkPixmap *pm; | |
334 GdkBitmap *bm; | |
335 struct group *g; | |
336 struct buddy *b; | |
4349 | 337 GSList *grps, *buds; |
3391 | 338 char **xpm; |
4349 | 339 |
340 for( grps = groups; grps; grps = grps->next ) { | |
341 g = (struct group *)grps->data; | |
342 for( buds = g->members; buds; buds = buds->next ) { | |
343 b = (struct buddy *)buds->data; | |
344 if( b->present ) { | |
345 xpm = NULL; | |
346 if (b->user->gc->prpl->list_icon) | |
347 xpm = b->user->gc->prpl->list_icon(b->uc); | |
348 if (xpm == NULL) | |
349 xpm = (char **)no_icon_xpm; | |
350 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm); | |
351 BuddyTickerAddUser( b->name, get_buddy_alias(b), pm, bm ); | |
352 gdk_pixmap_unref(pm); | |
353 if (bm) | |
354 gdk_bitmap_unref(bm); | |
3391 | 355 } |
356 } | |
357 } | |
358 } | |
359 | |
360 void signon_cb(struct gaim_connection *gc, char *who) { | |
4349 | 361 struct buddy *b = find_buddy(gc->user, who); |
3391 | 362 char **xpm = NULL; |
363 | |
364 GdkPixmap *pm; | |
365 GdkBitmap *bm; | |
366 | |
367 if (gc->prpl->list_icon) | |
368 xpm = gc->prpl->list_icon(b->uc); | |
369 if (xpm == NULL) | |
370 xpm = (char **)no_icon_xpm; | |
371 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm); | |
372 | |
4227 | 373 BuddyTickerAddUser(who, get_buddy_alias(b), pm, bm); |
3391 | 374 gdk_pixmap_unref(pm); |
375 if (bm) | |
376 gdk_bitmap_unref(bm); | |
377 } | |
378 | |
379 void signoff_cb(struct gaim_connection *gc) { | |
3630 | 380 if (connections && !connections->next) { |
3391 | 381 gtk_widget_destroy(tickerwindow); |
382 tickerwindow = NULL; | |
383 ticker = NULL; | |
384 } | |
385 } | |
386 | |
387 void buddy_signoff_cb(struct gaim_connection *gc, char *who) { | |
388 BuddyTickerRemoveUser(who); | |
389 } | |
390 | |
391 void away_cb(struct gaim_connection *gc, char *who) { | |
4349 | 392 struct buddy *b = find_buddy(gc->user, who); |
3391 | 393 char **xpm = NULL; |
394 | |
395 GdkPixmap *pm; | |
396 GdkBitmap *bm; | |
397 | |
398 if (gc->prpl->list_icon) | |
399 xpm = gc->prpl->list_icon(b->uc); | |
400 if (xpm == NULL) | |
401 xpm = (char **)no_icon_xpm; | |
402 pm = gdk_pixmap_create_from_xpm_d(blist->window, &bm, NULL, xpm); | |
403 BuddyTickerSetPixmap(who, pm, bm); | |
404 gdk_pixmap_unref(pm); | |
405 if (bm) | |
406 gdk_bitmap_unref(bm); | |
407 } | |
408 | |
3630 | 409 /* |
410 * EXPORTED FUNCTIONS | |
411 */ | |
412 | |
413 G_MODULE_EXPORT char *name() { | |
414 return "Buddy Ticker"; | |
415 } | |
416 | |
417 G_MODULE_EXPORT char *description() { | |
418 return "Scrolls online buddies from your buddy list."; | |
419 } | |
420 | |
421 G_MODULE_EXPORT char *gaim_plugin_init(GModule *h) { | |
3391 | 422 handle = h; |
423 | |
424 gaim_signal_connect(h, event_buddy_signon, signon_cb, NULL); | |
425 gaim_signal_connect(h, event_signoff, signoff_cb, NULL); | |
426 gaim_signal_connect(h, event_buddy_signoff, buddy_signoff_cb, NULL); | |
427 gaim_signal_connect(h, event_buddy_away, away_cb, NULL); | |
428 | |
429 if (connections) | |
430 BuddyTickerShow(); | |
431 return NULL; | |
432 } | |
433 | |
3630 | 434 G_MODULE_EXPORT void gaim_plugin_remove() { |
435 BuddyTickerDestroyWindow(tickerwindow); | |
3391 | 436 } |
3551 | 437 struct gaim_plugin_description desc; |
3630 | 438 G_MODULE_EXPORT struct gaim_plugin_description *gaim_plugin_desc() { |
3551 | 439 desc.api_version = PLUGIN_API_VERSION; |
440 desc.name = g_strdup("Ticker"); | |
441 desc.version = g_strdup(VERSION); | |
442 desc.description = g_strdup("A horizontal scrolling version of the buddy list."); | |
443 desc.authors = g_strdup("Syd Logan"); | |
444 desc.url = g_strdup(WEBSITE); | |
445 return &desc; | |
446 } |