comparison plugins/win32/winprefs/winprefs.c @ 11003:2b772e7094ef

[gaim-migrate @ 12858] Kevin Stange made this patch to remove the win32 flashing from the gaim core and put it the winprefs plugin. He also cleaned up the winprefs plugin quite a bit. Blame him if it doesn't work ;) committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Sat, 11 Jun 2005 23:29:56 +0000
parents a1eddb973f42
children 50224ac8184d
comparison
equal deleted inserted replaced
11002:bf03a5271395 11003:2b772e7094ef
1 /* 1 /*
2 * gaim - WinGaim Options Plugin 2 * gaim - WinGaim Options Plugin
3 * 3 *
4 * File: winprefs.c 4 * Gaim is the legal property of its developers, whose names are too numerous
5 * Date: December 12, 2002 5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
6 * 7 *
7 * copyright (c) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com> 8 * This program is free software; you can redistribute it and/or modify
8 * 9 * it under the terms of the GNU General Public License as published by
9 * this program is free software; you can redistribute it and/or modify 10 * the Free Software Foundation; either version 2 of the License, or
10 * it under the terms of the gnu general public license as published by
11 * the free software foundation; either version 2 of the license, or
12 * (at your option) any later version. 11 * (at your option) any later version.
13 * 12 *
14 * this program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but without any warranty; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * merchantability or fitness for a particular purpose. see the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * gnu general public license for more details. 16 * GNU General Public License for more details.
18 * 17 *
19 * you should have received a copy of the gnu general public license 18 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the free software 19 * along with this program; if not, write to the Free Software
21 * foundation, inc., 59 temple place, suite 330, boston, ma 02111-1307 usa 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * 21 *
23 */ 22 */
23
24 #include <gdk/gdkwin32.h> 24 #include <gdk/gdkwin32.h>
25 25
26 #include "internal.h" 26 #include "internal.h"
27 27
28 #include "core.h" 28 #include "core.h"
29 #include "debug.h"
29 #include "prefs.h" 30 #include "prefs.h"
30 #include "debug.h"
31 #include "signals.h" 31 #include "signals.h"
32 #include "version.h" 32 #include "version.h"
33 33
34 #include "gtkappbar.h"
35 #include "gtkblist.h"
36 #include "gtkconv.h"
34 #include "gtkplugin.h" 37 #include "gtkplugin.h"
38 #include "gtkprefs.h"
35 #include "gtkutils.h" 39 #include "gtkutils.h"
36 #include "gtkblist.h"
37 #include "gtkappbar.h"
38 40
39 /* 41 /*
40 * MACROS & DEFINES 42 * MACROS & DEFINES
41 */ 43 */
42 #define WINPREFS_PLUGIN_ID "gtk-win-prefs" 44 #define WINPREFS_PLUGIN_ID "gtk-win-prefs"
43 45
44 /* 46 /*
45 * LOCALS 47 * LOCALS
46 */ 48 */
47 static const char *OPT_WINPREFS_DBLIST_DOCKABLE = "/plugins/gtk/win32/winprefs/dblist_dockable"; 49 static const char *PREF_DBLIST_DOCKABLE = "/plugins/gtk/win32/winprefs/dblist_dockable";
48 static const char *OPT_WINPREFS_DBLIST_DOCKED = "/plugins/gtk/win32/winprefs/dblist_docked"; 50 static const char *PREF_DBLIST_DOCKED = "/plugins/gtk/win32/winprefs/dblist_docked";
49 static const char *OPT_WINPREFS_DBLIST_HEIGHT = "/plugins/gtk/win32/winprefs/dblist_height"; 51 static const char *PREF_DBLIST_HEIGHT = "/plugins/gtk/win32/winprefs/dblist_height";
50 static const char *OPT_WINPREFS_DBLIST_SIDE = "/plugins/gtk/win32/winprefs/dblist_side"; 52 static const char *PREF_DBLIST_SIDE = "/plugins/gtk/win32/winprefs/dblist_side";
51 static const char *OPT_WINPREFS_DBLIST_ON_TOP = "/plugins/gtk/win32/winprefs/dblist_on_top"; 53 static const char *PREF_BLIST_ON_TOP = "/plugins/gtk/win32/winprefs/blist_on_top";
52 static const char *OPT_WINPREFS_BLIST_ON_TOP = "/plugins/gtk/win32/winprefs/blist_on_top"; 54 static const char *PREF_IM_BLINK = "/plugins/gtk/win32/winprefs/im_blink";
53 static const char *OPT_WINPREFS_IM_BLINK = "/plugins/gtk/win32/winprefs/im_blink"; 55 /* Deprecated */
54 56 static const char *PREF_DBLIST_ON_TOP = "/plugins/gtk/win32/winprefs/dblist_on_top";
55 static GaimPlugin *plugin_id = NULL; 57
58 static GaimPlugin *handle = NULL;
56 static GtkAppBar *blist_ab = NULL; 59 static GtkAppBar *blist_ab = NULL;
57 static GtkWidget *blist = NULL; 60 static GtkWidget *blist = NULL;
58 61
59 /* 62 /* flash info */
60 * PROTOS 63
61 */ 64 struct _WGAIM_FLASH_INFO {
62 static void blist_create_cb(GaimBuddyList *blist, void *data); 65 guint t_handle;
66 guint sig_handler;
67 };
68
69 enum {
70 BLIST_TOP_NEVER = 0,
71 BLIST_TOP_ALWAYS,
72 BLIST_TOP_DOCKED,
73 };
74
75 typedef struct _WGAIM_FLASH_INFO WGAIM_FLASH_INFO;
76
77 typedef BOOL (CALLBACK* LPFNFLASHWINDOWEX)(PFLASHWINFO);
78
79 static LPFNFLASHWINDOWEX MyFlashWindowEx = NULL;
63 80
64 /* 81 /*
65 * CODE 82 * CODE
66 */ 83 */
67 84
68 /* UTIL */
69
70 static GtkWidget *wgaim_button(const char *text, GtkWidget *page) {
71 GtkWidget *button;
72 button = gtk_check_button_new_with_mnemonic(text);
73 gtk_box_pack_start(GTK_BOX(page), button, FALSE, FALSE, 0);
74 gtk_widget_show(button);
75 return button;
76 }
77
78 /* BLIST DOCKING */ 85 /* BLIST DOCKING */
79 86
80 static void blist_save_state() { 87 static void blist_save_state() {
81 if(blist_ab) { 88 if(blist_ab) {
82 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKABLE) && blist_ab->docked) { 89 if(gaim_prefs_get_bool(PREF_DBLIST_DOCKABLE) && blist_ab->docked) {
83 gaim_prefs_set_int(OPT_WINPREFS_DBLIST_HEIGHT, blist_ab->undocked_height); 90 gaim_prefs_set_int(PREF_DBLIST_HEIGHT, blist_ab->undocked_height);
84 gaim_prefs_set_int(OPT_WINPREFS_DBLIST_SIDE, blist_ab->side); 91 gaim_prefs_set_int(PREF_DBLIST_SIDE, blist_ab->side);
85 gaim_prefs_set_bool(OPT_WINPREFS_DBLIST_DOCKED, blist_ab->docked); 92 gaim_prefs_set_bool(PREF_DBLIST_DOCKED, blist_ab->docked);
86 } 93 } else
87 else 94 gaim_prefs_set_bool(PREF_DBLIST_DOCKED, FALSE);
88 gaim_prefs_set_bool(OPT_WINPREFS_DBLIST_DOCKED, FALSE); 95 }
89 }
90 } 96 }
91 97
92 static void blist_set_ontop(gboolean val) { 98 static void blist_set_ontop(gboolean val) {
93 if(!blist) 99 if (!blist)
94 return; 100 return;
95 if(val) 101
96 SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 102 if (val == TRUE)
97 else 103 SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
98 SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); 104 else
105 SetWindowPos(GDK_WINDOW_HWND(blist->window), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
106
99 } 107 }
100 108
101 static void blist_dock_cb(gboolean val) { 109 static void blist_dock_cb(gboolean val) {
102 if(val) { 110 if (val == TRUE) {
103 gaim_debug_info(WINPREFS_PLUGIN_ID, "Blist Docking..\n"); 111 gaim_debug_info(WINPREFS_PLUGIN_ID, "Blist Docking..\n");
104 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP)) 112 if (gaim_prefs_get_int(PREF_BLIST_ON_TOP) != BLIST_TOP_NEVER)
105 blist_set_ontop(TRUE); 113 blist_set_ontop(TRUE);
106 } 114 } else {
107 else { 115 gaim_debug_info(WINPREFS_PLUGIN_ID, "Blist Undocking..\n");
108 gaim_debug_info(WINPREFS_PLUGIN_ID, "Blist Undocking..\n"); 116 if (gaim_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS)
109 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP) && 117 blist_set_ontop(TRUE);
110 !gaim_prefs_get_bool(OPT_WINPREFS_BLIST_ON_TOP)) 118 else
111 blist_set_ontop(FALSE); 119 blist_set_ontop(FALSE);
112 } 120 }
113 } 121 }
114 122
115 static void blist_set_dockable(gboolean val) { 123 static void blist_set_dockable(gboolean val) {
116 if(val) { 124 if (val == TRUE) {
117 if(!blist_ab && blist) { 125 if (blist_ab == NULL && blist != NULL) {
118 blist_ab = gtk_appbar_add(blist); 126 blist_ab = gtk_appbar_add(blist);
119 gtk_appbar_add_dock_cb(blist_ab, blist_dock_cb); 127 gtk_appbar_add_dock_cb(blist_ab, blist_dock_cb);
120 } 128 }
121 } 129 } else {
122 else { 130 if (blist_ab != NULL) {
123 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP) && 131 gtk_appbar_remove(blist_ab);
124 !gaim_prefs_get_bool(OPT_WINPREFS_BLIST_ON_TOP)) 132 blist_ab = NULL;
125 blist_set_ontop(FALSE); 133 }
126 gtk_appbar_remove(blist_ab); 134
127 blist_ab = NULL; 135 if (gaim_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS)
128 } 136 blist_set_ontop(TRUE);
137 else
138 blist_set_ontop(FALSE);
139 }
129 } 140 }
130 141
131 /* PLUGIN CALLBACKS */ 142 /* PLUGIN CALLBACKS */
132 143
133 /* We need this because the blist destroy cb won't be called before the 144 /* We need this because the blist destroy cb won't be called before the
134 plugin is unloaded, when quitting */ 145 plugin is unloaded, when quitting */
135 static void gaim_quit_cb() { 146 static void gaim_quit_cb() {
136 gaim_debug_info(WINPREFS_PLUGIN_ID, "gaim_quit_cb: removing appbar\n"); 147 gaim_debug_info(WINPREFS_PLUGIN_ID, "gaim_quit_cb: removing appbar\n");
137 blist_save_state(); 148 blist_save_state();
138 blist_set_dockable(FALSE); 149 blist_set_dockable(FALSE);
139 } 150 }
140 151
141 static void blist_create_cb(GaimBuddyList *gaim_blist, void *data) { 152 static void blist_create_cb(GaimBuddyList *gaim_blist, void *data) {
142 gaim_debug_info(WINPREFS_PLUGIN_ID, "buddy list created\n"); 153 gaim_debug_info(WINPREFS_PLUGIN_ID, "buddy list created\n");
143 154
144 blist = GAIM_GTK_BLIST(gaim_blist)->window; 155 blist = GAIM_GTK_BLIST(gaim_blist)->window;
145 156
146 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKABLE)) { 157 if (gaim_prefs_get_bool(PREF_DBLIST_DOCKABLE)) {
147 blist_set_dockable(TRUE); 158 blist_set_dockable(TRUE);
148 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKED)) { 159 if (gaim_prefs_get_bool(PREF_DBLIST_DOCKED)) {
149 blist_ab->undocked_height = gaim_prefs_get_int(OPT_WINPREFS_DBLIST_HEIGHT); 160 blist_ab->undocked_height = gaim_prefs_get_int(PREF_DBLIST_HEIGHT);
150 gtk_appbar_dock(blist_ab, 161 gtk_appbar_dock(blist_ab,
151 gaim_prefs_get_int(OPT_WINPREFS_DBLIST_SIDE)); 162 gaim_prefs_get_int(PREF_DBLIST_SIDE));
152 if(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP)) 163 if (gaim_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_DOCKED)
153 blist_set_ontop(TRUE); 164 blist_set_ontop(TRUE);
154 } 165 }
155 } 166 }
156 if(gaim_prefs_get_bool(OPT_WINPREFS_BLIST_ON_TOP)) { 167
157 blist_set_ontop(TRUE); 168 if (gaim_prefs_get_int(PREF_BLIST_ON_TOP) == BLIST_TOP_ALWAYS)
158 } 169 blist_set_ontop(TRUE);
170
159 } 171 }
160 172
161 /* AUTOSTART */ 173 /* AUTOSTART */
162 174
163 static int open_run_key(PHKEY phKey, REGSAM samDesired) { 175 static int open_run_key(PHKEY phKey, REGSAM samDesired) {
164 /* First try current user key (for WinNT & Win2k +), fall back to local machine */ 176 /* First try current user key (for WinNT & Win2k +), fall back to local machine */
165 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, 177 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,
166 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 178 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
167 0, samDesired, phKey)); 179 0, samDesired, phKey));
168 else if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, 180 else if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
169 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", 181 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
170 0, samDesired, phKey)); 182 0, samDesired, phKey));
171 else { 183 else {
172 gaim_debug_error(WINPREFS_PLUGIN_ID, "open_run_key: Could not open key for writing value\n"); 184 gaim_debug_error(WINPREFS_PLUGIN_ID, "open_run_key: Could not open key for writing value\n");
173 return 0; 185 return 0;
174 } 186 }
175 return 1; 187 return 1;
176 } 188 }
177 189
178 /* WIN PREFS GENERAL */ 190 /* WIN PREFS GENERAL */
179 191
180 static void winprefs_set_autostart(GtkWidget *w) { 192 static void
181 HKEY hKey; 193 winprefs_set_autostart(GtkWidget *w)
182 194 {
183 if(!open_run_key(&hKey, KEY_SET_VALUE)) 195 HKEY hKey;
184 return; 196
185 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { 197 if (!open_run_key(&hKey, KEY_SET_VALUE))
186 char buffer[1024]; 198 return;
187 DWORD size; 199 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) {
188 200 char buffer[1024];
189 if((size = GetModuleFileName(wgaim_hinstance(), 201 DWORD size;
190 (LPBYTE)buffer, 202
191 sizeof(buffer)))==0) { 203 if ((size = GetModuleFileName(wgaim_hinstance(),
192 gaim_debug_error(WINPREFS_PLUGIN_ID, "GetModuleFileName Error.. Could not set Gaim autostart.\n"); 204 (LPBYTE)buffer, sizeof(buffer)))==0) {
193 RegCloseKey(hKey); 205 gaim_debug_error(WINPREFS_PLUGIN_ID, "GetModuleFileName Error.. Could not set Gaim autostart.\n");
194 return; 206 RegCloseKey(hKey);
195 } 207 return;
196 /* Now set value of new key */ 208 }
197 if(ERROR_SUCCESS != RegSetValueEx(hKey, 209
198 "Gaim", 210 /* Now set value of new key */
199 0, 211 if (ERROR_SUCCESS != RegSetValueEx(hKey, "Gaim", 0, REG_SZ, buffer, size))
200 REG_SZ, 212 gaim_debug_error(WINPREFS_PLUGIN_ID, "Could not set registry key value\n");
201 buffer, 213 } else {
202 size)) 214 if (ERROR_SUCCESS != RegDeleteValue(hKey, "Gaim"))
203 gaim_debug_error(WINPREFS_PLUGIN_ID, "Could not set registry key value\n"); 215 gaim_debug_error(WINPREFS_PLUGIN_ID, "Could not delete registry key value\n");
204 } 216 }
205 else { 217 RegCloseKey(hKey);
206 if(ERROR_SUCCESS != RegDeleteValue(hKey, "Gaim")) 218 }
207 gaim_debug_error(WINPREFS_PLUGIN_ID, "Could not delete registry key value\n"); 219
208 } 220 static void
209 RegCloseKey(hKey); 221 winprefs_set_blist_dockable (const char *pref, GaimPrefType type,
210 } 222 gpointer value, gpointer user_data)
211 223 {
212 static void winprefs_set_blist_dockable(GtkWidget *w, GtkWidget *w1) { 224 blist_set_dockable(GPOINTER_TO_INT(value));
213 gaim_prefs_set_bool(OPT_WINPREFS_DBLIST_DOCKABLE, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); 225 }
214 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { 226
215 blist_set_dockable(TRUE); 227 static void
216 gtk_widget_set_sensitive(w1, TRUE); 228 winprefs_set_blist_ontop (const char *pref, GaimPrefType type,
217 } 229 gpointer value, gpointer user_data)
218 else { 230 {
219 blist_set_dockable(FALSE); 231 gint setting = gaim_prefs_get_int(PREF_BLIST_ON_TOP);
220 gtk_widget_set_sensitive(w1, FALSE); 232 if ((setting == BLIST_TOP_DOCKED && blist_ab && blist_ab->docked)
221 } 233 || setting == BLIST_TOP_ALWAYS)
222 } 234 blist_set_ontop(TRUE);
223 235 else
224 static void winprefs_set_blist_ontop(GtkWidget *w) { 236 blist_set_ontop(FALSE);
225 gaim_prefs_set_bool(OPT_WINPREFS_BLIST_ON_TOP, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); 237 }
226 238
227 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { 239 static void load_winver_specific_procs (void) {
228 blist_set_ontop(TRUE); 240 /* Used for Win98+ and WinNT5+ */
229 } 241 MyFlashWindowEx = (LPFNFLASHWINDOWEX)wgaim_find_and_loadproc("user32.dll", "FlashWindowEx" );
230 else { 242 }
231 if(!(gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKABLE) && 243
232 gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP) && 244 /* Window flasher */
233 (blist_ab && blist_ab->docked))) 245 static gboolean flash_window_cb (gpointer data) {
234 blist_set_ontop(FALSE); 246 FlashWindow((HWND)data, TRUE);
235 } 247 return TRUE;
236 } 248 }
237 249
238 static void winprefs_set_dblist_ontop(GtkWidget *w) { 250 static int
239 gaim_prefs_set_bool(OPT_WINPREFS_DBLIST_ON_TOP, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); 251 halt_flash_filter (GtkWidget *widget, GdkEventFocus *event, gpointer data)
240 if(blist && blist_ab) { 252 {
241 if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) { 253 if (MyFlashWindowEx) {
242 if(blist_ab->docked) 254 HWND hWnd = data;
243 blist_set_ontop(TRUE); 255 FLASHWINFO info;
244 } 256
245 else if(!gaim_prefs_get_bool(OPT_WINPREFS_BLIST_ON_TOP)) 257 if (!IsWindow(hWnd))
246 blist_set_ontop(FALSE); 258 return 0;
247 } 259
248 } 260 memset(&info, 0, sizeof(FLASHWINFO));
249 261 info.cbSize = sizeof(FLASHWINFO);
250 static void winprefs_set_im_blink(GtkWidget *w) { 262 info.hwnd = hWnd;
251 gaim_prefs_set_bool(OPT_WINPREFS_IM_BLINK, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); 263 info.dwFlags = FLASHW_STOP;
252 wgaim_conv_im_blink_state(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))); 264 info.dwTimeout = 0;
253 } 265 MyFlashWindowEx(&info);
266
267 } else {
268 WGAIM_FLASH_INFO *finfo = data;
269 /* Stop flashing and remove filter */
270 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Removing timeout\n");
271 gaim_timeout_remove(finfo->t_handle);
272 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Disconnecting signal handler\n");
273 g_signal_handler_disconnect(G_OBJECT(widget),finfo->sig_handler);
274 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "done\n");
275 g_free(finfo);
276 }
277 return 0;
278 }
279
280 /* FlashWindowEx is only supported by Win98+ and WinNT5+. If it's
281 not supported we do it our own way */
282 static void
283 wgaim_conv_im_blink (GaimAccount *account, char *sender, char *message, int flags)
284 {
285 if (gaim_prefs_get_bool(PREF_IM_BLINK) == FALSE)
286 return;
287
288 GaimConversation *conv = gaim_find_conversation_with_account(GAIM_CONV_IM, sender, account);
289 if (conv == NULL) {
290 gaim_debug_info("winprefs", "gar!\n");
291 return;
292 }
293 GaimConvWindow *win = gaim_conversation_get_window(conv);
294 if (win == NULL) {
295 gaim_debug_info("winprefs", "gar2!\n");
296 return;
297 }
298 GtkWidget *window = GAIM_GTK_WINDOW(win)->window;
299
300 if (MyFlashWindowEx) {
301 FLASHWINFO info;
302 if (GetForegroundWindow() == GDK_WINDOW_HWND(window->window))
303 return;
304
305 memset(&info, 0, sizeof(FLASHWINFO));
306 info.cbSize = sizeof(FLASHWINFO);
307 info.hwnd = GDK_WINDOW_HWND(window->window);
308 info.dwFlags = FLASHW_ALL | FLASHW_TIMER;
309 info.dwTimeout = 0;
310 MyFlashWindowEx(&info);
311 /* Stop flashing when window receives focus */
312 g_signal_connect(G_OBJECT(window), "focus-in-event",
313 G_CALLBACK(halt_flash_filter), info.hwnd);
314 } else {
315 WGAIM_FLASH_INFO *finfo = g_new0(WGAIM_FLASH_INFO, 1);
316
317 /* Start Flashing window */
318 finfo->t_handle = gaim_timeout_add(1000, flash_window_cb,
319 GDK_WINDOW_HWND(window->window));
320 finfo->sig_handler = g_signal_connect(G_OBJECT(window),
321 "focus-in-event",
322 G_CALLBACK(halt_flash_filter), finfo);
323 }
324 }
325
254 326
255 /* 327 /*
256 * EXPORTED FUNCTIONS 328 * EXPORTED FUNCTIONS
257 */ 329 */
258 330
259 gboolean plugin_load(GaimPlugin *plugin) { 331 gboolean plugin_load(GaimPlugin *plugin) {
260 plugin_id = plugin; 332 /* Find out how to go blinky */
261 333 load_winver_specific_procs();
262 /* blist docking init */ 334
335 handle = plugin;
336
337 /* blist docking init */
263 if (gaim_get_blist() && GAIM_GTK_BLIST(gaim_get_blist()) && GAIM_GTK_BLIST(gaim_get_blist())->window) { 338 if (gaim_get_blist() && GAIM_GTK_BLIST(gaim_get_blist()) && GAIM_GTK_BLIST(gaim_get_blist())->window) {
264 blist_create_cb(gaim_get_blist(), NULL); 339 blist_create_cb(gaim_get_blist(), NULL);
265 } else { 340 }
266 gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-created", plugin_id, GAIM_CALLBACK(blist_create_cb), NULL); 341
267 } 342 /* This really shouldn't happen anymore generally, but if for some strange
268 343 reason, the blist is recreated, we need to set it up again. */
269 wgaim_conv_im_blink_state(gaim_prefs_get_bool(OPT_WINPREFS_IM_BLINK)); 344 gaim_signal_connect(gaim_gtk_blist_get_handle(), "gtkblist-created", plugin, GAIM_CALLBACK(blist_create_cb), NULL);
270 345
271 gaim_signal_connect((void*)gaim_get_core(), "quitting", plugin, GAIM_CALLBACK(gaim_quit_cb), NULL); 346 gaim_signal_connect(gaim_conversations_get_handle(), "received-im-msg", plugin, GAIM_CALLBACK(wgaim_conv_im_blink), NULL);
272 347
273 return TRUE; 348 gaim_signal_connect((void*)gaim_get_core(), "quitting", plugin, GAIM_CALLBACK(gaim_quit_cb), NULL);
349
350 gaim_prefs_connect_callback(handle, PREF_BLIST_ON_TOP,
351 winprefs_set_blist_ontop, NULL);
352 gaim_prefs_connect_callback(handle, PREF_DBLIST_DOCKABLE,
353 winprefs_set_blist_dockable, NULL);
354
355 return TRUE;
274 } 356 }
275 357
276 gboolean plugin_unload(GaimPlugin *plugin) { 358 gboolean plugin_unload(GaimPlugin *plugin) {
277 blist_set_dockable(FALSE); 359 blist_set_dockable(FALSE);
278 wgaim_conv_im_blink_state(TRUE); 360 blist_set_ontop(FALSE);
279 return TRUE; 361 return TRUE;
280 } 362 }
281 363
282 static GtkWidget* get_config_frame(GaimPlugin *plugin) { 364 static GtkWidget* get_config_frame(GaimPlugin *plugin) {
283 GtkWidget *ret; 365 GtkWidget *ret;
366 GtkWidget *vbox;
284 GtkWidget *button; 367 GtkWidget *button;
285 GtkWidget *dbutton; 368 char* gtk_version = NULL;
286 GtkWidget *vbox; 369 HKEY hKey = HKEY_CURRENT_USER;
287 char* gtk_version = NULL;
288 HKEY hKey = HKEY_CURRENT_USER;
289 370
290 ret = gtk_vbox_new(FALSE, 18); 371 ret = gtk_vbox_new(FALSE, 18);
291 gtk_container_set_border_width (GTK_CONTAINER (ret), 12); 372 gtk_container_set_border_width (GTK_CONTAINER (ret), 12);
292 373
293 while(hKey) { 374 while(hKey) {
294 char version[25]; 375 char version[25];
295 DWORD vlen = 25; 376 DWORD vlen = 25;
296 if(wgaim_read_reg_string(hKey, "SOFTWARE\\GTK\\2.0", "Version", (LPBYTE)&version, &vlen)) { 377 if(wgaim_read_reg_string(hKey, "SOFTWARE\\GTK\\2.0", "Version", (LPBYTE)&version, &vlen)) {
297 char revision[25]; 378 char revision[25];
298 DWORD rlen = 25; 379 DWORD rlen = 25;
299 gboolean gotrev = FALSE; 380 gboolean gotrev = FALSE;
300 if(wgaim_read_reg_string(hKey, "SOFTWARE\\GTK\\2.0", "Revision", (LPBYTE)&revision, &rlen)) { 381 if(wgaim_read_reg_string(hKey, "SOFTWARE\\GTK\\2.0", "Revision", (LPBYTE)&revision, &rlen)) {
301 revision[0] = g_ascii_toupper(revision[0]); 382 revision[0] = g_ascii_toupper(revision[0]);
302 revision[1] = '\0'; 383 revision[1] = '\0';
303 gotrev = TRUE; 384 gotrev = TRUE;
304 } 385 }
305 gtk_version = g_strdup_printf("%s%s%s", 386 gtk_version = g_strdup_printf("%s%s%s", version,
306 version, 387 (gotrev ? " Revision " : ""),
307 gotrev?" Revision ":"", 388 (gotrev ? revision : ""));
308 gotrev?revision:""); 389 hKey = 0;
309 hKey = 0; 390 }
310 } 391 if(hKey == HKEY_CURRENT_USER)
311 if(hKey == HKEY_CURRENT_USER) 392 hKey = HKEY_LOCAL_MACHINE;
312 hKey = HKEY_LOCAL_MACHINE; 393 else if(hKey == HKEY_LOCAL_MACHINE)
313 else if(hKey == HKEY_LOCAL_MACHINE) 394 hKey = 0;
314 hKey = 0; 395 }
315 } 396
316 397 /* Display Installed GTK+ Runtime Version */
317 /* Display Installed GTK+ Runtime Version */ 398 if(gtk_version) {
318 if(gtk_version) { 399 GtkWidget *label;
319 GtkWidget *label; 400 vbox = gaim_gtk_make_frame(ret, _("GTK+ Runtime Version"));
320 vbox = gaim_gtk_make_frame(ret, _("GTK+ Runtime Version")); 401 label = gtk_label_new(gtk_version);
321 label = gtk_label_new(gtk_version); 402 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
322 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 403 gtk_widget_show(label);
323 gtk_widget_show(label); 404 g_free(gtk_version);
324 g_free(gtk_version); 405 }
325 } 406
326 407 /* Autostart */
327 /* Autostart */
328 vbox = gaim_gtk_make_frame (ret, _("Startup")); 408 vbox = gaim_gtk_make_frame (ret, _("Startup"));
329 button = wgaim_button(_("_Start Gaim on Windows startup"), vbox); 409 button = gtk_check_button_new_with_mnemonic(_("_Start Gaim on Windows startup"));
410 gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
330 if(open_run_key(&hKey, KEY_QUERY_VALUE)) { 411 if(open_run_key(&hKey, KEY_QUERY_VALUE)) {
331 if(ERROR_SUCCESS == RegQueryValueEx(hKey, "Gaim", 0, NULL, NULL, NULL)) { 412 if(ERROR_SUCCESS == RegQueryValueEx(hKey, "Gaim", 0, NULL, NULL, NULL)) {
332 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); 413 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
333 } 414 }
334 } 415 }
335 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(winprefs_set_autostart), NULL); 416 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(winprefs_set_autostart), NULL);
336 417 gtk_widget_show(button);
337 /* Buddy List */ 418
419 /* Buddy List */
338 vbox = gaim_gtk_make_frame (ret, _("Buddy List")); 420 vbox = gaim_gtk_make_frame (ret, _("Buddy List"));
339 button = wgaim_button(_("_Dockable Buddy List"), vbox); 421 gaim_gtk_prefs_checkbox(_("_Dockable Buddy List"),
340 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKABLE)); 422 PREF_DBLIST_DOCKABLE, vbox);
341 423
342 /* Docked Blist On Top */ 424 /* Blist On Top */
343 dbutton = wgaim_button(_("Docked _Buddy List is always on top"), vbox); 425 gaim_gtk_prefs_dropdown(vbox, _("_Keep Buddy List window on top:"),
344 gtk_signal_connect(GTK_OBJECT(dbutton), "clicked", GTK_SIGNAL_FUNC(winprefs_set_dblist_ontop), NULL); 426 GAIM_PREF_INT, PREF_BLIST_ON_TOP,
345 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbutton), gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_ON_TOP)); 427 _("Never"), BLIST_TOP_NEVER,
346 if(!gaim_prefs_get_bool(OPT_WINPREFS_DBLIST_DOCKABLE)) 428 _("Always"), BLIST_TOP_ALWAYS,
347 gtk_widget_set_sensitive(GTK_WIDGET(dbutton), FALSE); 429 /* XXX: Did this ever work? */
348 430 _("Only when docked"), BLIST_TOP_DOCKED,
349 /* Connect cb for Dockable option.. passing dblist on top button */ 431 NULL);
350 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(winprefs_set_blist_dockable), dbutton); 432
351 433 /* Conversations */
352 /* Blist On Top */
353 button = wgaim_button(_("_Keep Buddy List window on top"), vbox);
354 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(winprefs_set_blist_ontop), NULL);
355 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), gaim_prefs_get_bool(OPT_WINPREFS_BLIST_ON_TOP));
356
357 /* Conversations */
358 vbox = gaim_gtk_make_frame (ret, _("Conversations")); 434 vbox = gaim_gtk_make_frame (ret, _("Conversations"));
359 button = wgaim_button(_("_Flash Window when messages are received"), vbox); 435 gaim_gtk_prefs_checkbox(_("_Flash window when messages are received"),
360 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(winprefs_set_im_blink), NULL); 436 PREF_IM_BLINK, vbox);
361 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), gaim_prefs_get_bool(OPT_WINPREFS_IM_BLINK));
362 437
363 gtk_widget_show_all(ret); 438 gtk_widget_show_all(ret);
364 return ret; 439 return ret;
365 } 440 }
366 441
381 GAIM_PRIORITY_DEFAULT, 456 GAIM_PRIORITY_DEFAULT,
382 WINPREFS_PLUGIN_ID, 457 WINPREFS_PLUGIN_ID,
383 N_("WinGaim Options"), 458 N_("WinGaim Options"),
384 VERSION, 459 VERSION,
385 N_("Options specific to Windows Gaim."), 460 N_("Options specific to Windows Gaim."),
386 N_("Options specific to Windows Gaim."), 461 N_("Provides options specific to Windows Gaim, such as buddy list docking and conversation flashing."),
387 "Herman Bloggs <hermanator12002@yahoo.com>", 462 "Herman Bloggs <hermanator12002@yahoo.com>",
388 GAIM_WEBSITE, 463 GAIM_WEBSITE,
389 plugin_load, 464 plugin_load,
390 plugin_unload, 465 plugin_unload,
391 NULL, 466 NULL,
396 }; 471 };
397 472
398 static void 473 static void
399 init_plugin(GaimPlugin *plugin) 474 init_plugin(GaimPlugin *plugin)
400 { 475 {
476 gaim_prefs_add_none("/plugins/gtk");
401 gaim_prefs_add_none("/plugins/gtk/win32"); 477 gaim_prefs_add_none("/plugins/gtk/win32");
402 gaim_prefs_add_none("/plugins/gtk/win32/winprefs"); 478 gaim_prefs_add_none("/plugins/gtk/win32/winprefs");
403 gaim_prefs_add_bool(OPT_WINPREFS_DBLIST_DOCKABLE, FALSE); 479 gaim_prefs_add_bool(PREF_DBLIST_DOCKABLE, FALSE);
404 gaim_prefs_add_bool(OPT_WINPREFS_DBLIST_DOCKED, FALSE); 480 gaim_prefs_add_bool(PREF_DBLIST_DOCKED, FALSE);
405 gaim_prefs_add_int(OPT_WINPREFS_DBLIST_HEIGHT, 0); 481 gaim_prefs_add_int(PREF_DBLIST_HEIGHT, 0);
406 gaim_prefs_add_int(OPT_WINPREFS_DBLIST_SIDE, 0); 482 gaim_prefs_add_int(PREF_DBLIST_SIDE, 0);
407 gaim_prefs_add_bool(OPT_WINPREFS_DBLIST_ON_TOP, FALSE); 483 gaim_prefs_add_bool(PREF_IM_BLINK, TRUE);
408 gaim_prefs_add_bool(OPT_WINPREFS_BLIST_ON_TOP, FALSE); 484
409 gaim_prefs_add_bool(OPT_WINPREFS_IM_BLINK, TRUE); 485 /* Convert old preferences */
486 if (gaim_prefs_exists(PREF_DBLIST_ON_TOP)) {
487 gint blist_top = BLIST_TOP_NEVER;
488 if (gaim_prefs_get_bool(PREF_BLIST_ON_TOP))
489 blist_top = BLIST_TOP_ALWAYS;
490 else if (gaim_prefs_get_bool(PREF_DBLIST_ON_TOP))
491 blist_top = BLIST_TOP_DOCKED;
492 gaim_prefs_remove(PREF_BLIST_ON_TOP);
493 gaim_prefs_remove(PREF_DBLIST_ON_TOP);
494 gaim_prefs_add_int(PREF_BLIST_ON_TOP, blist_top);
495 } else
496 gaim_prefs_add_int(PREF_BLIST_ON_TOP, BLIST_TOP_NEVER);
410 } 497 }
411 498
412 GAIM_INIT_PLUGIN(winprefs, init_plugin, info) 499 GAIM_INIT_PLUGIN(winprefs, init_plugin, info)