Sun, 09 Oct 2005 23:20:42 +0000
[gaim-migrate @ 13907]
Some people use really slow computers.
Some people use fairly slow computers and gdb.
Some people use faster computers with lots of other things going on.
Idiots like me use valgrind.
Give the docklet some time, it needs it.
Good things come to those who wait.
| 6209 | 1 | /* |
| 2 | * System tray icon (aka docklet) plugin for Gaim | |
| 3 | * | |
| 4 | * Copyright (C) 2002-3 Robert McQueen <robot101@debian.org> | |
| 5 | * Copyright (C) 2003 Herman Bloggs <hermanator12002@yahoo.com> | |
| 6 | * Inspired by a similar plugin by: | |
| 7 | * John (J5) Palmieri <johnp@martianrock.com> | |
| 8 | * | |
| 9 | * This program is free software; you can redistribute it and/or | |
| 10 | * modify it under the terms of the GNU General Public License as | |
| 11 | * published by the Free Software Foundation; either version 2 of the | |
| 12 | * License, or (at your option) any later version. | |
| 13 | * | |
| 14 | * This program is distributed in the hope that it will be useful, but | |
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 17 | * General Public License for more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU General Public License | |
| 20 | * along with this program; if not, write to the Free Software | |
| 21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
| 22 | * 02111-1307, USA. | |
| 23 | */ | |
| 24 | ||
| 25 | #include "internal.h" | |
| 9791 | 26 | #include "gtkgaim.h" |
| 6209 | 27 | #include "debug.h" |
|
10297
b36800725b7a
[gaim-migrate @ 11480]
Evan Schoenberg <evands@pidgin.im>
parents:
10268
diff
changeset
|
28 | #include "gtkstock.h" |
| 6209 | 29 | |
| 30 | #include "gaim.h" | |
|
9709
2e73f176cc80
[gaim-migrate @ 10570]
Mark Doliner <markdoliner@pidgin.im>
parents:
9229
diff
changeset
|
31 | #include "gtkdialogs.h" |
| 6209 | 32 | |
| 33 | #include "eggtrayicon.h" | |
| 34 | #include "docklet.h" | |
| 35 | ||
|
11631
622bca9bfe33
[gaim-migrate @ 13907]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10771
diff
changeset
|
36 | #define EMBED_TIMEOUT 10000 |
| 10491 | 37 | |
| 6209 | 38 | /* globals */ |
| 39 | static EggTrayIcon *docklet = NULL; | |
| 40 | static GtkWidget *image = NULL; | |
|
6894
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
41 | static GdkPixbuf *blank_icon = NULL; |
| 10491 | 42 | static int embed_timeout = 0; |
| 6209 | 43 | |
| 44 | /* protos */ | |
| 45 | static void docklet_x11_create(); | |
| 46 | ||
| 47 | static gboolean | |
| 48 | docklet_x11_create_cb() | |
| 49 | { | |
| 50 | docklet_x11_create(); | |
| 51 | ||
| 52 | return FALSE; /* for when we're called by the glib idle handler */ | |
| 53 | } | |
| 54 | ||
| 55 | static void | |
| 56 | docklet_x11_embedded_cb(GtkWidget *widget, void *data) | |
| 57 | { | |
| 58 | gaim_debug(GAIM_DEBUG_INFO, "tray icon", "embedded\n"); | |
| 10491 | 59 | |
| 60 | g_source_remove(embed_timeout); | |
| 61 | embed_timeout = 0; | |
| 6209 | 62 | } |
| 63 | ||
| 64 | static void | |
| 65 | docklet_x11_destroyed_cb(GtkWidget *widget, void *data) | |
| 66 | { | |
| 67 | gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); | |
| 68 | ||
| 69 | docklet_remove(TRUE); | |
| 70 | ||
| 71 | g_object_unref(G_OBJECT(docklet)); | |
| 72 | docklet = NULL; | |
| 73 | ||
| 74 | g_idle_add(docklet_x11_create_cb, &handle); | |
| 75 | } | |
| 76 | ||
| 77 | static void | |
| 78 | docklet_x11_clicked_cb(GtkWidget *button, GdkEventButton *event, void *data) | |
| 79 | { | |
| 80 | if (event->type != GDK_BUTTON_PRESS) | |
| 81 | return; | |
| 82 | ||
| 83 | docklet_clicked(event->button); | |
| 84 | } | |
| 85 | ||
| 86 | static void | |
| 87 | docklet_x11_update_icon(enum docklet_status icon) | |
| 88 | { | |
| 89 | const gchar *icon_name = NULL; | |
| 90 | ||
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
91 | g_return_if_fail(image != NULL); |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
92 | |
| 6209 | 93 | switch (icon) { |
| 94 | case offline: | |
| 95 | icon_name = GAIM_STOCK_ICON_OFFLINE; | |
| 96 | break; | |
| 97 | case offline_connecting: | |
| 98 | case online_connecting: | |
| 99 | icon_name = GAIM_STOCK_ICON_CONNECT; | |
| 100 | break; | |
| 101 | case online: | |
| 102 | icon_name = GAIM_STOCK_ICON_ONLINE; | |
| 103 | break; | |
| 104 | case online_pending: | |
| 105 | icon_name = GAIM_STOCK_ICON_ONLINE_MSG; | |
| 106 | break; | |
| 107 | case away: | |
| 108 | icon_name = GAIM_STOCK_ICON_AWAY; | |
| 109 | break; | |
| 110 | case away_pending: | |
| 111 | icon_name = GAIM_STOCK_ICON_AWAY_MSG; | |
| 112 | break; | |
| 113 | } | |
| 114 | ||
| 10771 | 115 | gtk_image_set_from_stock(GTK_IMAGE(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR); |
| 116 | ||
| 10766 | 117 | #if 0 |
| 118 | GdkPixbuf *p; | |
| 119 | GdkBitmap *mask = NULL; | |
| 120 | ||
| 10765 | 121 | p = gtk_widget_render_icon(GTK_WIDGET(image), icon_name, GTK_ICON_SIZE_LARGE_TOOLBAR, NULL); |
| 122 | ||
| 123 | if (p && (gdk_pixbuf_get_colorspace(p) == GDK_COLORSPACE_RGB) && (gdk_pixbuf_get_bits_per_sample(p) == 8) | |
| 124 | && (gdk_pixbuf_get_has_alpha(p)) && (gdk_pixbuf_get_n_channels(p) == 4)) { | |
| 125 | int len = gdk_pixbuf_get_width(p) * gdk_pixbuf_get_height(p); | |
| 126 | guchar *data = gdk_pixbuf_get_pixels(p); | |
| 127 | guchar *bitmap = g_malloc((len / 8) + 1); | |
| 128 | int i; | |
| 129 | ||
| 130 | for (i = 0; i < len; i++) | |
| 10766 | 131 | if (data[i*4 + 3] > 55) |
| 10765 | 132 | bitmap[i/8] |= 1 << i % 8; |
| 133 | else | |
| 134 | bitmap[i/8] &= ~(1 << i % 8); | |
| 135 | ||
| 136 | mask = gdk_bitmap_create_from_data(GDK_DRAWABLE(GTK_WIDGET(image)->window), bitmap, gdk_pixbuf_get_width(p), gdk_pixbuf_get_height(p)); | |
| 137 | g_free(bitmap); | |
| 138 | } | |
| 139 | ||
| 140 | if (mask) | |
| 141 | gdk_window_shape_combine_mask(image->window, mask, 0, 0); | |
| 142 | ||
| 143 | g_object_unref(G_OBJECT(p)); | |
| 10766 | 144 | #endif |
| 6209 | 145 | } |
| 146 | ||
| 147 | static void | |
|
6894
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
148 | docklet_x11_blank_icon() |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
149 | { |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
150 | if (!blank_icon) { |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
151 | gint width, height; |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
152 | |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
153 | gtk_icon_size_lookup(GTK_ICON_SIZE_LARGE_TOOLBAR, &width, &height); |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
154 | blank_icon = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
155 | gdk_pixbuf_fill(blank_icon, 0); |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
156 | } |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
157 | |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
158 | gtk_image_set_from_pixbuf(GTK_IMAGE(image), blank_icon); |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
159 | } |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
160 | |
|
10505
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
161 | #if GTK_CHECK_VERSION(2,2,0) |
|
6894
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
162 | static void |
|
10268
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
163 | docklet_x11_position_menu(GtkMenu *menu, int *x, int *y, gboolean *push_in, |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
164 | gpointer user_data) |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
165 | { |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
166 | GtkWidget *widget = GTK_WIDGET(docklet); |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
167 | GtkRequisition req; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
168 | gint menu_xpos, menu_ypos; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
169 | |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
170 | gtk_widget_size_request(GTK_WIDGET(menu), &req); |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
171 | gdk_window_get_origin(widget->window, &menu_xpos, &menu_ypos); |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
172 | |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
173 | menu_xpos += widget->allocation.x; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
174 | menu_ypos += widget->allocation.y; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
175 | |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
176 | if (menu_ypos > gdk_screen_get_height(gtk_widget_get_screen(widget)) / 2) |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
177 | menu_ypos -= req.height; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
178 | else |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
179 | menu_ypos += widget->allocation.height; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
180 | |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
181 | *x = menu_xpos; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
182 | *y = menu_ypos; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
183 | |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
184 | *push_in = TRUE; |
|
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
185 | } |
|
10505
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
186 | #endif |
|
10268
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
187 | |
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
188 | static void |
| 6209 | 189 | docklet_x11_destroy() |
| 190 | { | |
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
191 | g_return_if_fail(docklet != NULL); |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
192 | |
| 6209 | 193 | docklet_remove(GTK_WIDGET_VISIBLE(docklet)); |
| 194 | ||
| 195 | g_signal_handlers_disconnect_by_func(G_OBJECT(docklet), G_CALLBACK(docklet_x11_destroyed_cb), NULL); | |
| 196 | gtk_widget_destroy(GTK_WIDGET(docklet)); | |
| 197 | ||
| 198 | g_object_unref(G_OBJECT(docklet)); | |
| 199 | docklet = NULL; | |
| 200 | ||
|
6894
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
201 | if (blank_icon) |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
202 | g_object_unref(G_OBJECT(blank_icon)); |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
203 | blank_icon = NULL; |
|
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
204 | |
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
205 | image = NULL; |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
206 | |
| 6209 | 207 | gaim_debug(GAIM_DEBUG_INFO, "tray icon", "destroyed\n"); |
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
208 | } |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
209 | |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
210 | static gboolean |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
211 | docklet_x11_embed_timeout_cb() |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
212 | { |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
213 | docklet_unload(); |
|
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
214 | |
| 10491 | 215 | return FALSE; |
| 6209 | 216 | } |
| 217 | ||
| 218 | static void | |
| 219 | docklet_x11_create() | |
| 220 | { | |
| 221 | GtkWidget *box; | |
| 222 | ||
| 223 | if (docklet) { | |
| 224 | /* if this is being called when a tray icon exists, it's because | |
| 225 | something messed up. try destroying it before we proceed, | |
| 226 | although docklet_refcount may be all hosed. hopefully won't happen. */ | |
| 227 | gaim_debug(GAIM_DEBUG_WARNING, "tray icon", "trying to create icon but it already exists?\n"); | |
| 228 | docklet_x11_destroy(); | |
| 229 | } | |
| 230 | ||
| 231 | docklet = egg_tray_icon_new("Gaim"); | |
| 232 | box = gtk_event_box_new(); | |
| 233 | image = gtk_image_new(); | |
| 234 | ||
| 235 | g_signal_connect(G_OBJECT(docklet), "embedded", G_CALLBACK(docklet_x11_embedded_cb), NULL); | |
| 236 | g_signal_connect(G_OBJECT(docklet), "destroy", G_CALLBACK(docklet_x11_destroyed_cb), NULL); | |
| 237 | g_signal_connect(G_OBJECT(box), "button-press-event", G_CALLBACK(docklet_x11_clicked_cb), NULL); | |
| 238 | ||
| 239 | gtk_container_add(GTK_CONTAINER(box), image); | |
| 240 | gtk_container_add(GTK_CONTAINER(docklet), box); | |
| 9229 | 241 | |
| 242 | if(!gtk_check_version(2,4,0)) | |
| 243 | g_object_set(G_OBJECT(box), "visible-window", FALSE, NULL); | |
| 244 | ||
| 6209 | 245 | gtk_widget_show_all(GTK_WIDGET(docklet)); |
| 246 | ||
| 247 | /* ref the docklet before we bandy it about the place */ | |
| 248 | g_object_ref(G_OBJECT(docklet)); | |
| 10491 | 249 | docklet_embedded(); |
|
10504
eae130eefbfe
[gaim-migrate @ 11796]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10491
diff
changeset
|
250 | embed_timeout = g_timeout_add(EMBED_TIMEOUT, docklet_x11_embed_timeout_cb, NULL); |
| 6209 | 251 | |
| 252 | gaim_debug(GAIM_DEBUG_INFO, "tray icon", "created\n"); | |
| 253 | } | |
| 254 | ||
| 255 | static struct docklet_ui_ops ui_ops = | |
| 256 | { | |
| 257 | docklet_x11_create, | |
| 258 | docklet_x11_destroy, | |
|
6894
8c6e286b079d
[gaim-migrate @ 7441]
Herman Bloggs <herman@bluedigits.com>
parents:
6371
diff
changeset
|
259 | docklet_x11_update_icon, |
|
10268
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
260 | docklet_x11_blank_icon, |
|
10505
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
261 | #if GTK_CHECK_VERSION(2,2,0) |
|
10268
862ed5d3f227
[gaim-migrate @ 11414]
Christian Hammond <chipx86@chipx86.com>
parents:
9791
diff
changeset
|
262 | docklet_x11_position_menu |
|
10505
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
263 | #else |
|
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
264 | NULL |
|
4c063ce8ed62
[gaim-migrate @ 11799]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
10504
diff
changeset
|
265 | #endif |
| 6209 | 266 | }; |
| 267 | ||
| 268 | void | |
| 269 | docklet_ui_init() | |
| 270 | { | |
| 271 | docklet_set_ui_ops(&ui_ops); | |
| 272 | } |