comparison libgaim/win32/win32dep.c @ 14224:ab8a105eff62

[gaim-migrate @ 16905] First step of getting wingaim working again. libgaim and gtk are compiling. The protocols aren't compiling yet. There are a number of things that are compiling, but should be cleaned up. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Sun, 20 Aug 2006 16:49:37 +0000
parents
children d1cb45dec12f
comparison
equal deleted inserted replaced
14223:7c560c01b8f9 14224:ab8a105eff62
1 /*
2 * gaim
3 *
4 * File: win32dep.c
5 * Date: June, 2002
6 * Description: Windows dependant code for Gaim
7 *
8 * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25 #define _WIN32_IE 0x500
26 #include <windows.h>
27 #include <io.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <winuser.h>
31
32 #include <glib.h>
33 #include <glib/gstdio.h>
34
35 #include "gaim.h"
36 #include "debug.h"
37 #include "notify.h"
38
39 #include <libintl.h>
40
41 #include "win32dep.h"
42
43 /*
44 * DEFINES & MACROS
45 */
46 #define _(x) gettext(x)
47
48 /*
49 * DATA STRUCTS
50 */
51
52 /* For shfolder.dll */
53 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR);
54 typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR);
55
56 /*
57 * LOCALS
58 */
59 static char *app_data_dir, *install_dir, *lib_dir, *locale_dir;
60
61 /*
62 * GLOBALS
63 */
64 HINSTANCE libgaimdll_hInstance = 0;
65
66 /*
67 * PROTOS
68 */
69
70 FARPROC wgaim_find_and_loadproc(char*, char*);
71 char* wgaim_data_dir(void);
72
73 /*
74 * STATIC CODE
75 */
76
77 static void wgaim_debug_print(GaimDebugLevel level, const char *category, const char *format, va_list args) {
78 char *str = NULL;
79 if (args != NULL) {
80 str = g_strdup_vprintf(format, args);
81 } else {
82 str = g_strdup(format);
83 }
84 printf("%s%s%s", category ? category : "", category ? ": " : "", str);
85 g_free(str);
86 }
87
88 static GaimDebugUiOps ops = {
89 wgaim_debug_print
90 };
91
92 /*
93 * PUBLIC CODE
94 */
95
96 /* Escape windows dir separators. This is needed when paths are saved,
97 and on being read back have their '\' chars used as an escape char.
98 Returns an allocated string which needs to be freed.
99 */
100 char* wgaim_escape_dirsep(char* filename) {
101 int sepcount = 0;
102 char* ret = NULL;
103 int cnt = 0;
104
105 ret = filename;
106 while(*ret) {
107 if(*ret == '\\')
108 sepcount++;
109 ret++;
110 }
111 ret = g_malloc0(strlen(filename) + sepcount + 1);
112 while(*filename) {
113 ret[cnt] = *filename;
114 if(*filename == '\\')
115 ret[++cnt] = '\\';
116 filename++;
117 cnt++;
118 }
119 ret[cnt] = '\0';
120 return ret;
121 }
122
123 /* Determine whether the specified dll contains the specified procedure.
124 If so, load it (if not already loaded). */
125 FARPROC wgaim_find_and_loadproc(char* dllname, char* procedure) {
126 HMODULE hmod;
127 BOOL did_load = FALSE;
128 FARPROC proc = 0;
129
130 if(!(hmod = GetModuleHandle(dllname))) {
131 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "%s not already loaded; loading it...\n", dllname);
132 if(!(hmod = LoadLibrary(dllname))) {
133 gaim_debug(GAIM_DEBUG_ERROR, "wgaim", "Could not load: %s\n", dllname);
134 return NULL;
135 }
136 else
137 did_load = TRUE;
138 }
139
140 if((proc = GetProcAddress(hmod, procedure))) {
141 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "This version of %s contains %s\n",
142 dllname, procedure);
143 return proc;
144 }
145 else {
146 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Function %s not found in dll %s\n",
147 procedure, dllname);
148 if(did_load) {
149 /* unload dll */
150 FreeLibrary(hmod);
151 }
152 return NULL;
153 }
154 }
155
156 /* Determine Gaim Paths during Runtime */
157
158 /* Get paths to special Windows folders. */
159 char *wgaim_get_special_folder(int folder_type) {
160 static LPFNSHGETFOLDERPATHA MySHGetFolderPathA = NULL;
161 static LPFNSHGETFOLDERPATHW MySHGetFolderPathW = NULL;
162 char *retval = NULL;
163
164 if (!MySHGetFolderPathW) {
165 MySHGetFolderPathW = (LPFNSHGETFOLDERPATHW)
166 wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathW");
167 }
168
169 if (MySHGetFolderPathW) {
170 wchar_t utf_16_dir[MAX_PATH + 1];
171
172 if (SUCCEEDED(MySHGetFolderPathW(NULL, folder_type, NULL,
173 SHGFP_TYPE_CURRENT, utf_16_dir))) {
174 retval = g_utf16_to_utf8(utf_16_dir, -1, NULL, NULL, NULL);
175 }
176 }
177
178 if (!retval) {
179 if (!MySHGetFolderPathA) {
180 MySHGetFolderPathA = (LPFNSHGETFOLDERPATHA)
181 wgaim_find_and_loadproc("shfolder.dll", "SHGetFolderPathA");
182 }
183 if (MySHGetFolderPathA) {
184 char locale_dir[MAX_PATH + 1];
185
186 if (SUCCEEDED(MySHGetFolderPathA(NULL, folder_type, NULL,
187 SHGFP_TYPE_CURRENT, locale_dir))) {
188 retval = g_locale_to_utf8(locale_dir, -1, NULL, NULL, NULL);
189 }
190 }
191 }
192
193 return retval;
194 }
195
196 char* wgaim_install_dir(void) {
197 static gboolean initialized = FALSE;
198
199 if (!initialized) {
200 char *tmp = NULL;
201 if (G_WIN32_HAVE_WIDECHAR_API()) {
202 wchar_t winstall_dir[MAXPATHLEN];
203 if (GetModuleFileNameW(NULL, winstall_dir,
204 MAXPATHLEN) > 0) {
205 tmp = g_utf16_to_utf8(winstall_dir, -1,
206 NULL, NULL, NULL);
207 }
208 } else {
209 gchar cpinstall_dir[MAXPATHLEN];
210 if (GetModuleFileNameA(NULL, cpinstall_dir,
211 MAXPATHLEN) > 0) {
212 tmp = g_locale_to_utf8(cpinstall_dir,
213 -1, NULL, NULL, NULL);
214 }
215 }
216
217 if (tmp == NULL) {
218 tmp = g_win32_error_message(GetLastError());
219 gaim_debug(GAIM_DEBUG_ERROR, "wgaim",
220 "GetModuleFileName error: %s\n", tmp);
221 g_free(tmp);
222 return NULL;
223 } else {
224 install_dir = g_path_get_dirname(tmp);
225 g_free(tmp);
226 initialized = TRUE;
227 }
228 }
229
230 return install_dir;
231 }
232
233 char* wgaim_lib_dir(void) {
234 static gboolean initialized = FALSE;
235
236 if (!initialized) {
237 char *inst_dir = wgaim_install_dir();
238 if (inst_dir != NULL) {
239 lib_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "plugins", inst_dir);
240 initialized = TRUE;
241 } else {
242 return NULL;
243 }
244 }
245
246 return lib_dir;
247 }
248
249 char* wgaim_locale_dir(void) {
250 static gboolean initialized = FALSE;
251
252 if (!initialized) {
253 char *inst_dir = wgaim_install_dir();
254 if (inst_dir != NULL) {
255 locale_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "locale", inst_dir);
256 initialized = TRUE;
257 } else {
258 return NULL;
259 }
260 }
261
262 return locale_dir;
263 }
264
265 char* wgaim_data_dir(void) {
266 return app_data_dir;
267 }
268
269 /* Miscellaneous */
270
271 gboolean wgaim_read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) {
272 HKEY hkey;
273 gboolean ret = FALSE;
274
275 if(ERROR_SUCCESS == RegOpenKeyEx(key, sub_key, 0, KEY_QUERY_VALUE,
276 &hkey)) {
277 if(ERROR_SUCCESS == RegQueryValueEx(hkey, val_name, 0, NULL,
278 data, data_len))
279 ret = TRUE;
280 RegCloseKey(key);
281 }
282 return ret;
283 }
284
285 void wgaim_init(void) {
286 WORD wVersionRequested;
287 WSADATA wsaData;
288 const char *perlenv;
289 char *newenv;
290
291 gaim_debug_set_ui_ops(&ops);
292 gaim_debug_info("wgaim", "wgaim_init start\n");
293
294 gaim_debug_info("wgaim", "Glib:%u.%u.%u\n",
295 glib_major_version, glib_minor_version, glib_micro_version);
296
297 /* Winsock init */
298 wVersionRequested = MAKEWORD(2, 2);
299 WSAStartup(wVersionRequested, &wsaData);
300
301 /* Confirm that the winsock DLL supports 2.2 */
302 /* Note that if the DLL supports versions greater than
303 2.2 in addition to 2.2, it will still return 2.2 in
304 wVersion since that is the version we requested. */
305 if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
306 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "Could not find a usable WinSock DLL. Oh well.\n");
307 WSACleanup();
308 }
309
310 /* Set Environmental Variables */
311 /* Tell perl where to find Gaim's perl modules */
312 perlenv = g_getenv("PERL5LIB");
313 newenv = g_strdup_printf("PERL5LIB=%s%s%s" G_DIR_SEPARATOR_S "perlmod;",
314 perlenv ? perlenv : "",
315 perlenv ? ";" : "",
316 wgaim_install_dir());
317 if (putenv(newenv) < 0)
318 gaim_debug(GAIM_DEBUG_WARNING, "wgaim", "putenv failed\n");
319 g_free(newenv);
320
321 /* Set app data dir, used by gaim_home_dir */
322 newenv = (char*) g_getenv("GAIMHOME");
323 if (newenv) {
324 app_data_dir = g_strdup(newenv);
325 } else {
326 app_data_dir = wgaim_get_special_folder(CSIDL_APPDATA);
327 if (!app_data_dir) {
328 app_data_dir = g_strdup("C:");
329 }
330 }
331
332 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "Gaim settings dir: %s\n", app_data_dir);
333
334 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_init end\n");
335 }
336
337 /* Windows Cleanup */
338
339 void wgaim_cleanup(void) {
340 gaim_debug(GAIM_DEBUG_INFO, "wgaim", "wgaim_cleanup\n");
341
342 /* winsock cleanup */
343 WSACleanup();
344
345 g_free(app_data_dir);
346 }
347
348 /* DLL initializer */
349 BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
350 libgaimdll_hInstance = hinstDLL;
351 return TRUE;
352 }