📄 winpidgin.c
字号:
/* * winpidgin.c * * Date: June, 2002 * Description: Entry point for win32 pidgin, and various win32 dependant * routines. * * Pidgin is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * source distribution. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * *//* This is for ATTACH_PARENT_PROCESS */#ifndef _WIN32_WINNT#define _WIN32_WINNT 0x501#endif#include <windows.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <stdio.h>/* These will hopefully be in the win32api next time it is updated - at which point, we'll remove them */#ifndef LANG_PERSIAN#define LANG_PERSIAN 0x29#endif#ifndef LANG_BOSNIAN#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08#endif#ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04#endif#ifndef LANG_XHOSA#define LANG_XHOSA 0x34#endiftypedef int (CALLBACK* LPFNPIDGINMAIN)(HINSTANCE, int, char**);typedef void (CALLBACK* LPFNSETDLLDIRECTORY)(LPCTSTR);typedef BOOL (CALLBACK* LPFNATTACHCONSOLE)(DWORD);/* * PROTOTYPES */static LPFNPIDGINMAIN pidgin_main = NULL;static LPFNSETDLLDIRECTORY MySetDllDirectory = NULL;static const char *get_win32_error_message(DWORD err) { static char err_msg[512]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err_msg, sizeof(err_msg), NULL); return err_msg;}static BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) { HKEY hkey; BOOL ret = FALSE; LONG retv; if (ERROR_SUCCESS == (retv = RegOpenKeyEx(key, sub_key, 0, KEY_QUERY_VALUE, &hkey))) { if (ERROR_SUCCESS == (retv = RegQueryValueEx(hkey, val_name, NULL, NULL, data, data_len))) ret = TRUE; else { const char *err_msg = get_win32_error_message(retv); printf("Could not read reg key '%s' subkey '%s' value: '%s'.\nMessage: (%ld) %s\n", ((key == HKEY_LOCAL_MACHINE) ? "HKLM" : (key == HKEY_CURRENT_USER) ? "HKCU" : "???"), sub_key, val_name, retv, err_msg); } RegCloseKey(hkey); } else { TCHAR szBuf[80]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, retv, 0, (LPTSTR) &szBuf, sizeof(szBuf), NULL); printf("Could not open reg subkey: %s\nError: (%ld) %s\n", sub_key, retv, szBuf); } return ret;}static void dll_prep() { char path[MAX_PATH + 1]; HMODULE hmod; HKEY hkey;#ifdef PORTABLE /* We assume that GTK+ is installed under \\path\to\Pidgin\..\GTK * First we find \\path\to */ if (GetModuleFileName(NULL, path, MAX_PATH) != 0) { char *tmp = path; char *prev = NULL; char *prev2 = NULL; while ((tmp = strchr(tmp, '\\'))) { prev2 = prev; prev = tmp; tmp++; } if (prev2) { prev2[0] = '\0'; } } else { printf("Unable to determine current executable path. \n" "This will prevent the settings dir from being set.\n" "Assuming GTK+ is in the PATH.\n"); } if (path) { /* Set up the settings dir base to be \\path\to * The actual settings dir will be \\path\to\.purple */ char settingsdir[strlen(path) + strlen("PURPLEHOME=") + 1]; char aspelldir[strlen(path) + strlen("PIDGIN_ASPELL_DIR=\\Aspell\\bin") + 1]; snprintf(settingsdir, sizeof(settingsdir), "PURPLEHOME=%s", path); printf("Setting settings dir: %s\n", settingsdir); putenv(settingsdir); snprintf(aspelldir, sizeof(aspelldir), "PIDGIN_ASPELL_DIR=%s\\Aspell\\bin", path); printf("%s\n", aspelldir); putenv(aspelldir); /* set the GTK+ path to be \\path\to\GTK\bin */ strcat(path, "\\GTK\\bin"); } else return;#else /* PORTABLE */ char gtkpath[MAX_PATH + 1]; DWORD plen; plen = sizeof(gtkpath); hkey = HKEY_CURRENT_USER; if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE) >kpath, &plen)) { hkey = HKEY_LOCAL_MACHINE; if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", (LPBYTE) >kpath, &plen)) { printf("GTK+ Path Registry Key not found. " "Assuming GTK+ is in the PATH.\n"); return; } } /* this value is replaced during a successful RegQueryValueEx() */ plen = sizeof(path); /* Determine GTK+ dll path .. */ if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "DllPath", (LPBYTE) &path, &plen)) { strcpy(path, gtkpath); strcat(path, "\\bin"); }#endif printf("GTK+ path found: %s\n", path); if ((hmod = GetModuleHandle("kernel32.dll"))) { MySetDllDirectory = (LPFNSETDLLDIRECTORY) GetProcAddress( hmod, "SetDllDirectoryA"); if (!MySetDllDirectory) printf("SetDllDirectory not supported\n"); } else printf("Error getting kernel32.dll module handle\n"); /* For Windows XP SP1+ / Server 2003 we use SetDllDirectory to avoid dll hell */ if (MySetDllDirectory) { printf("Using SetDllDirectory\n"); MySetDllDirectory(path); } /* For the rest, we set the current directory and make sure * SafeDllSearch is set to 0 where needed. */ else { OSVERSIONINFO osinfo; printf("Setting current directory to GTK+ dll directory\n"); SetCurrentDirectory(path); /* For Windows 2000 (SP3+) / WinXP (No SP): * If SafeDllSearchMode is set to 1, Windows system directories are * searched for dlls before the current directory. Therefore we set it * to 0. */ osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osinfo); if ((osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion == 0 && strcmp(osinfo.szCSDVersion, "Service Pack 3") >= 0) || (osinfo.dwMajorVersion == 5 && osinfo.dwMinorVersion == 1 && strcmp(osinfo.szCSDVersion, "") >= 0) ) { DWORD regval = 1; DWORD reglen = sizeof(DWORD); printf("Using Win2k (SP3+) / WinXP (No SP)... Checking SafeDllSearch\n"); read_reg_string(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager", "SafeDllSearchMode", (LPBYTE) ®val, ®len); if (regval != 0) { printf("Trying to set SafeDllSearchMode to 0\n"); regval = 0; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager", 0, KEY_SET_VALUE, &hkey ) == ERROR_SUCCESS) { if (RegSetValueEx(hkey, "SafeDllSearchMode", 0, REG_DWORD, (LPBYTE) ®val, sizeof(DWORD) ) != ERROR_SUCCESS) printf("Error writing SafeDllSearchMode. Error: %u\n", (UINT) GetLastError()); RegCloseKey(hkey); } else printf("Error opening Session Manager key for writing. Error: %u\n", (UINT) GetLastError()); } else printf("SafeDllSearchMode is set to 0\n"); }/*end else*/ }}static char* winpidgin_lcid_to_posix(LCID lcid) { char *posix = NULL; int lang_id = PRIMARYLANGID(lcid); int sub_id = SUBLANGID(lcid); switch (lang_id) { case LANG_ARABIC: posix = "ar"; break; case LANG_AZERI: posix = "az"; break; case LANG_BENGALI: posix = "bn"; break; case LANG_BULGARIAN: posix = "bg"; break; case LANG_CATALAN: posix = "ca"; break; case LANG_CHINESE: switch (sub_id) { case SUBLANG_CHINESE_SIMPLIFIED: posix = "zh_CN"; break; case SUBLANG_CHINESE_TRADITIONAL: posix = "zh_TW"; break; default: posix = "zh"; break; } break; case LANG_CZECH: posix = "cs"; break; case LANG_DANISH: posix = "da"; break; case LANG_ESTONIAN: posix = "et"; break; case LANG_PERSIAN: posix = "fa"; break; case LANG_GERMAN: posix = "de"; break; case LANG_GREEK: posix = "el"; break; case LANG_ENGLISH: switch (sub_id) { case SUBLANG_ENGLISH_UK: posix = "en_GB"; break; case SUBLANG_ENGLISH_AUS: posix = "en_AU"; break; case SUBLANG_ENGLISH_CAN: posix = "en_CA"; break; default: posix = "en"; break; } break; case LANG_SPANISH: posix = "es"; break; case LANG_BASQUE: posix = "eu"; break; case LANG_FINNISH: posix = "fi"; break; case LANG_FRENCH: posix = "fr"; break; case LANG_GALICIAN: posix = "gl"; break; case LANG_GUJARATI: posix = "gu"; break; case LANG_HEBREW: posix = "he"; break; case LANG_HINDI: posix = "hi"; break; case LANG_HUNGARIAN: posix = "hu"; break; case LANG_ICELANDIC: break; case LANG_ITALIAN: posix = "it"; break; case LANG_JAPANESE: posix = "ja"; break; case LANG_GEORGIAN: posix = "ka"; break; case LANG_KOREAN: posix = "ko"; break; case LANG_LITHUANIAN: posix = "lt"; break; case LANG_MACEDONIAN: posix = "mk"; break; case LANG_DUTCH: posix = "nl"; break; case LANG_NEPALI: posix = "ne"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -