comparison src/win32.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents
children 0493e9f3c27f
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
1 /* Utility routines for XEmacs on Windows 9x, NT and Cygwin.
2 Copyright (C) 2000 Ben Wing.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to the Free
18 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
20
21 #include <config.h>
22 #include "lisp.h"
23
24 #include "buffer.h"
25 #include "syswindows.h"
26
27 typedef BOOL (WINAPI *pfSwitchToThread_t) (VOID);
28 pfSwitchToThread_t xSwitchToThread;
29
30 typedef HKL (WINAPI *pfGetKeyboardLayout_t) (DWORD);
31 pfGetKeyboardLayout_t xGetKeyboardLayout;
32 typedef BOOL (WINAPI *pfSetMenuDefaultItem_t) (HMENU, UINT, UINT);
33 pfSetMenuDefaultItem_t xSetMenuDefaultItem;
34 typedef BOOL (WINAPI *pfInsertMenuItemA_t)
35 (HMENU, UINT, BOOL, LPCMENUITEMINFOA);
36 pfInsertMenuItemA_t xInsertMenuItemA;
37 typedef BOOL (WINAPI *pfInsertMenuItemW_t)
38 (HMENU, UINT, BOOL, LPCMENUITEMINFOW);
39 pfInsertMenuItemW_t xInsertMenuItemW;
40 typedef HANDLE (WINAPI *pfLoadImageA_t)
41 (HINSTANCE, LPCSTR, UINT, int, int, UINT);
42 pfLoadImageA_t xLoadImageA;
43 typedef HANDLE (WINAPI *pfLoadImageW_t)
44 (HINSTANCE, LPCWSTR, UINT, int, int, UINT);
45 pfLoadImageW_t xLoadImageW;
46 typedef ATOM (WINAPI *pfRegisterClassExA_t) (CONST WNDCLASSEXA *);
47 pfRegisterClassExA_t xRegisterClassExA;
48 typedef ATOM (WINAPI *pfRegisterClassExW_t) (CONST WNDCLASSEXW *);
49 pfRegisterClassExW_t xRegisterClassExW;
50
51 typedef int (WINAPI *pfEnumFontFamiliesExA_t)
52 (HDC, LPLOGFONTA, FONTENUMPROCA, LPARAM, DWORD);
53 pfEnumFontFamiliesExA_t xEnumFontFamiliesExA;
54 typedef int (WINAPI *pfEnumFontFamiliesExW_t)
55 (HDC, LPLOGFONTW, FONTENUMPROCW, LPARAM, DWORD);
56 pfEnumFontFamiliesExW_t xEnumFontFamiliesExW;
57
58 typedef DWORD (WINAPI *pfSHGetFileInfoA_t)
59 (LPCSTR, DWORD, SHFILEINFOA FAR *, UINT, UINT);
60 pfSHGetFileInfoA_t xSHGetFileInfoA;
61 typedef DWORD (WINAPI *pfSHGetFileInfoW_t)
62 (LPCWSTR, DWORD, SHFILEINFOW FAR *, UINT, UINT);
63 pfSHGetFileInfoW_t xSHGetFileInfoW;
64
65 Lisp_Object
66 tstr_to_local_file_format (Extbyte *pathout)
67 {
68 Bufbyte *ttlff;
69 Lisp_Object in;
70
71 EXTERNAL_TO_C_STRING (pathout, ttlff, Qmswindows_tstr);
72 WIN32_TO_LOCAL_FILE_FORMAT (ttlff, in);
73
74 return in;
75 }
76
77 static void
78 init_potentially_nonexistent_functions (void)
79 {
80 HMODULE h_kernel = GetModuleHandle ("kernel32");
81 HMODULE h_user = GetModuleHandle ("user32");
82 HMODULE h_gdi = GetModuleHandle ("gdi32");
83 HMODULE h_shell = GetModuleHandle ("shell32");
84
85 if (h_kernel)
86 {
87 xSwitchToThread =
88 (pfSwitchToThread_t) GetProcAddress (h_kernel, "SwitchToThread");
89 }
90
91 if (h_user)
92 {
93 xGetKeyboardLayout =
94 (pfGetKeyboardLayout_t) GetProcAddress (h_user, "GetKeyboardLayout");
95 xSetMenuDefaultItem =
96 (pfSetMenuDefaultItem_t) GetProcAddress (h_user, "SetMenuDefaultItem");
97 xInsertMenuItemA =
98 (pfInsertMenuItemA_t) GetProcAddress (h_user, "InsertMenuItemA");
99 xInsertMenuItemW =
100 (pfInsertMenuItemW_t) GetProcAddress (h_user, "InsertMenuItemW");
101 xLoadImageA =
102 (pfLoadImageA_t) GetProcAddress (h_user, "LoadImageA");
103 xLoadImageW =
104 (pfLoadImageW_t) GetProcAddress (h_user, "LoadImageW");
105 xRegisterClassExA =
106 (pfRegisterClassExA_t) GetProcAddress (h_user, "RegisterClassExA");
107 xRegisterClassExW =
108 (pfRegisterClassExW_t) GetProcAddress (h_user, "RegisterClassExW");
109 }
110
111 if (h_gdi)
112 {
113 xEnumFontFamiliesExA =
114 (pfEnumFontFamiliesExA_t) GetProcAddress (h_gdi, "EnumFontFamiliesExA");
115 xEnumFontFamiliesExW =
116 (pfEnumFontFamiliesExW_t) GetProcAddress (h_gdi, "EnumFontFamiliesExW");
117 }
118
119 if (h_shell)
120 {
121 xSHGetFileInfoA =
122 (pfSHGetFileInfoA_t) GetProcAddress (h_shell, "SHGetFileInfoA");
123 xSHGetFileInfoW =
124 (pfSHGetFileInfoW_t) GetProcAddress (h_shell, "SHGetFileInfoW");
125 }
126 }
127
128 DEFUN ("mswindows-shell-execute", Fmswindows_shell_execute, 2, 4, 0, /*
129 Get Windows to perform OPERATION on DOCUMENT.
130 This is a wrapper around the ShellExecute system function, which
131 invokes the application registered to handle OPERATION for DOCUMENT.
132 OPERATION is typically \"open\", \"print\" or \"explore\" (but can be
133 nil for the default action), and DOCUMENT is typically the name of a
134 document file or URL, but can also be a program executable to run or
135 a directory to open in the Windows Explorer.
136
137 If DOCUMENT is a program executable, PARAMETERS can be a string
138 containing command line parameters, but otherwise should be nil.
139
140 SHOW-FLAG can be used to control whether the invoked application is hidden
141 or minimized. If SHOW-FLAG is nil, the application is displayed normally,
142 otherwise it is an integer representing a ShowWindow flag:
143
144 0 - start hidden
145 1 - start normally
146 3 - start maximized
147 6 - start minimized
148 */
149 (operation, document, parameters, show_flag))
150 {
151 /* Encode filename and current directory. */
152 Lisp_Object current_dir = Ffile_name_directory (document);
153 char* path = NULL;
154 char* doc = NULL;
155 Extbyte* f=0;
156 int ret;
157 struct gcpro gcpro1, gcpro2;
158
159 CHECK_STRING (document);
160
161 if (NILP (current_dir))
162 current_dir = current_buffer->directory;
163
164 GCPRO2 (current_dir, document);
165
166 /* Use mule and cygwin-safe APIs top get at file data. */
167 if (STRINGP (current_dir))
168 {
169 TO_EXTERNAL_FORMAT (LISP_STRING, current_dir,
170 C_STRING_ALLOCA, f,
171 Qfile_name);
172 #ifdef CYGWIN
173 CYGWIN_WIN32_PATH (f, path);
174 #else
175 path = f;
176 #endif
177 }
178
179 if (STRINGP (document))
180 {
181 TO_EXTERNAL_FORMAT (LISP_STRING, document,
182 C_STRING_ALLOCA, f,
183 Qfile_name);
184 #ifdef CYGWIN
185 CYGWIN_WIN32_PATH (f, doc);
186 #else
187 doc = f;
188 #endif
189 }
190
191 UNGCPRO;
192
193 ret = (int) ShellExecute (NULL,
194 (STRINGP (operation) ?
195 XSTRING_DATA (operation) : NULL),
196 doc,
197 (STRINGP (parameters) ?
198 XSTRING_DATA (parameters) : NULL),
199 path,
200 (INTP (show_flag) ?
201 XINT (show_flag) : SW_SHOWDEFAULT));
202
203 if (ret > 32)
204 return Qt;
205
206 if (ret == ERROR_FILE_NOT_FOUND)
207 signal_simple_error ("file not found", document);
208 else if (ret == ERROR_PATH_NOT_FOUND)
209 signal_simple_error ("path not found", current_dir);
210 else if (ret == ERROR_BAD_FORMAT)
211 signal_simple_error ("bad executable format", document);
212 else
213 error ("internal error");
214
215 return Qnil;
216 }
217
218 void
219 syms_of_win32 (void)
220 {
221 DEFSUBR (Fmswindows_shell_execute);
222 }
223
224 void
225 init_win32 (void)
226 {
227 init_potentially_nonexistent_functions ();
228 }