Support and ignore fconfigure -translation ...
[jimtcl.git] / jim-win32.c
blobe5acf41d4db55dfd73e798de2b70beecd04e83da
1 /* WIN32 extension
3 * Copyright (C) 2005 Pat Thoyts <patthoyts@users.sourceforge.net>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * A copy of the license is also included in the source distribution
12 * of Jim, as a TXT file name called LICENSE.
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
21 #include "jim.h"
22 #include "jimautoconf.h"
24 /* Apparently windows.h and cygwin don't mix, but we seem to get
25 * away with it here. Use at your own risk under cygwin
27 #if defined(__CYGWIN__)
28 #define WIN32_LEAN_AND_MEAN
29 #include <windows.h>
30 #endif
32 #include <shellapi.h>
33 #include <lmcons.h>
34 #include <psapi.h>
35 #include <ctype.h>
37 #if _MSC_VER >= 1000
38 #pragma comment(lib, "shell32")
39 #pragma comment(lib, "user32")
40 #pragma comment(lib, "advapi32")
41 #pragma comment(lib, "psapi")
42 #endif /* _MSC_VER >= 1000 */
44 static Jim_Obj *
45 Win32ErrorObj(Jim_Interp *interp, const char * szPrefix, DWORD dwError)
47 Jim_Obj *msgObj = NULL;
48 char * lpBuffer = NULL;
49 DWORD dwLen = 0;
51 dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
52 | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, LANG_NEUTRAL,
53 (char *)&lpBuffer, 0, NULL);
54 if (dwLen < 1) {
55 dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
56 | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
57 "code 0x%1!08X!%n", 0, LANG_NEUTRAL,
58 (char *)&lpBuffer, 0, (va_list *)&dwError);
61 msgObj = Jim_NewStringObj(interp, szPrefix, -1);
62 if (dwLen > 0) {
63 char *p = lpBuffer + dwLen - 1; /* remove cr-lf at end */
64 for ( ; p && *p && isspace(UCHAR(*p)); p--)
66 *++p = 0;
67 Jim_AppendString(interp, msgObj, ": ", 2);
68 Jim_AppendString(interp, msgObj, lpBuffer, -1);
70 LocalFree((HLOCAL)lpBuffer);
71 return msgObj;
74 /* win32.ShellExecute verb file args */
75 static int
76 Win32_ShellExecute(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
78 int r;
79 const char *verb, *file, *parm = NULL;
80 char cwd[MAX_PATH + 1];
82 if (objc < 3 || objc > 4) {
83 Jim_WrongNumArgs(interp, 1, objv, "verb path ?parameters?");
84 return JIM_ERR;
86 verb = Jim_String(objv[1]);
87 file = Jim_String(objv[2]);
88 GetCurrentDirectoryA(MAX_PATH + 1, cwd);
89 if (objc == 4)
90 parm = Jim_String(objv[3]);
91 r = (int)ShellExecuteA(NULL, verb, file, parm, cwd, SW_SHOWNORMAL);
92 if (r < 33)
93 Jim_SetResult(interp,
94 Win32ErrorObj(interp, "ShellExecute", GetLastError()));
95 return (r < 33) ? JIM_ERR : JIM_OK;
99 /* win32.FindWindow title ?class? */
100 static int
101 Win32_FindWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
103 const char *title = NULL, *class = NULL;
104 HWND hwnd = NULL;
105 int r = JIM_OK;
107 if (objc < 2 || objc > 3) {
108 Jim_WrongNumArgs(interp, 1, objv, "title ?class?");
109 return JIM_ERR;
111 title = Jim_String(objv[1]);
112 if (objc == 3)
113 class = Jim_String(objv[2]);
114 hwnd = FindWindowA(class, title);
116 if (hwnd == NULL) {
117 Jim_SetResult(interp,
118 Win32ErrorObj(interp, "FindWindow", GetLastError()));
119 r = JIM_ERR;
120 } else {
121 Jim_SetResult(interp, Jim_NewIntObj(interp, (long)hwnd));
123 return r;
126 /* win32.CloseWindow windowHandle */
127 static int
128 Win32_CloseWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
130 long hwnd;
132 if (objc != 2) {
133 Jim_WrongNumArgs(interp, 1, objv, "?windowHandle?");
134 return JIM_ERR;
136 if (Jim_GetLong(interp, objv[1], &hwnd) != JIM_OK)
137 return JIM_ERR;
138 if (!CloseWindow((HWND)hwnd)) {
139 Jim_SetResult(interp,
140 Win32ErrorObj(interp, "CloseWindow", GetLastError()));
141 return JIM_ERR;
143 return JIM_OK;
146 static int
147 Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
149 Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)GetActiveWindow()));
150 return JIM_OK;
153 static int
154 Win32_SetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
156 HWND hwnd, old;
157 int r = JIM_OK;
159 if (objc != 2) {
160 Jim_WrongNumArgs(interp, 1, objv, "windowHandle");
161 return JIM_ERR;
163 r = Jim_GetLong(interp, objv[1], (long *)&hwnd);
164 if (r == JIM_OK) {
165 old = SetActiveWindow(hwnd);
166 if (old == NULL) {
167 Jim_SetResult(interp,
168 Win32ErrorObj(interp, "SetActiveWindow", GetLastError()));
169 r = JIM_ERR;
170 } else {
171 Jim_SetResult(interp, Jim_NewIntObj(interp, (long)old));
174 return r;
177 static int
178 Win32_SetForegroundWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
180 HWND hwnd;
181 int r = JIM_OK;
183 if (objc != 2) {
184 Jim_WrongNumArgs(interp, 1, objv, "windowHandle");
185 return JIM_ERR;
187 r = Jim_GetLong(interp, objv[1], (long *)&hwnd);
188 if (r == JIM_OK) {
189 if (!SetForegroundWindow(hwnd)) {
190 Jim_SetResult(interp,
191 Win32ErrorObj(interp, "SetForegroundWindow", GetLastError()));
192 r = JIM_ERR;
195 return r;
198 static int
199 Win32_Beep(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
201 long freq, duration;
202 int r = JIM_OK;
204 if (objc != 3) {
205 Jim_WrongNumArgs(interp, 1, objv, "freq duration");
206 return JIM_ERR;
208 r = Jim_GetLong(interp, objv[1], &freq);
209 if (r == JIM_OK)
210 r = Jim_GetLong(interp, objv[2], &duration);
211 if (freq < 0x25) freq = 0x25;
212 if (freq > 0x7fff) freq = 0x7fff;
213 if (r == JIM_OK) {
214 if (!Beep(freq, duration)) {
215 Jim_SetResult(interp,
216 Win32ErrorObj(interp, "Beep", GetLastError()));
217 r = JIM_ERR;
220 return r;
223 static int
224 Win32_GetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
226 char name[MAX_COMPUTERNAME_LENGTH + 1];
227 DWORD size = MAX_COMPUTERNAME_LENGTH;
228 int r = JIM_OK;
230 if (objc != 1) {
231 Jim_WrongNumArgs(interp, 1, objv, "");
232 return JIM_ERR;
235 if (GetComputerNameA(name, &size)) {
236 Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size);
237 Jim_SetResult(interp, nameObj);
238 } else {
239 Jim_SetResult(interp,
240 Win32ErrorObj(interp, "GetComputerName", GetLastError()));
241 r = JIM_ERR;
244 return r;
247 static int
248 Win32_GetUserName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
250 char name[UNLEN + 1];
251 DWORD size = UNLEN;
252 int r = JIM_OK;
254 if (objc != 1) {
255 Jim_WrongNumArgs(interp, 1, objv, "");
256 return JIM_ERR;
259 if (GetUserNameA(name, &size)) {
260 Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size);
261 Jim_SetResult(interp, nameObj);
262 } else {
263 Jim_SetResult(interp,
264 Win32ErrorObj(interp, "GetUserName", GetLastError()));
265 r = JIM_ERR;
268 return r;
271 static int
272 Win32_GetModuleFileName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
274 HMODULE hModule = NULL;
275 char path[MAX_PATH];
276 DWORD len = 0;
278 if (objc > 2) {
279 Jim_WrongNumArgs(interp, 1, objv, "?moduleid?");
280 return JIM_ERR;
283 if (objc == 2) {
284 if (Jim_GetLong(interp, objv[1], (long *)&hModule) != JIM_OK) {
285 return JIM_ERR;
289 len = GetModuleFileNameA(hModule, path, MAX_PATH);
290 if (len != 0) {
291 Jim_Obj *pathObj = Jim_NewStringObj(interp, path, len);
292 Jim_SetResult(interp, pathObj);
293 } else {
294 Jim_SetResult(interp,
295 Win32ErrorObj(interp, "GetModuleFileName", GetLastError()));
296 return JIM_ERR;
299 return JIM_OK;
302 static int
303 Win32_GetVersion(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
305 Jim_SetResult(interp, Jim_NewIntObj(interp, GetVersion()));
306 return JIM_OK;
309 static int
310 Win32_GetTickCount(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
312 Jim_SetResult(interp, Jim_NewIntObj(interp, GetTickCount()));
313 return JIM_OK;
316 static int
317 Win32_GetSystemTime(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
319 Jim_Obj *a[16];
320 size_t n = 0;
321 SYSTEMTIME t;
322 GetSystemTime(&t);
324 #define JIMADD(name) \
325 a[n++] = Jim_NewStringObj(interp, #name, -1); \
326 a[n++] = Jim_NewIntObj(interp, t.w ## name )
328 JIMADD(Year);
329 JIMADD(Month);
330 JIMADD(DayOfWeek);
331 JIMADD(Day);
332 JIMADD(Hour);
333 JIMADD(Minute);
334 JIMADD(Second);
335 JIMADD(Milliseconds);
336 #undef JIMADD
338 Jim_SetResult(interp, Jim_NewListObj(interp, a, n));
339 return JIM_OK;
342 /* function not available on mingw or cygwin */
343 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
344 // FIX ME: win2k+ so should do version checks really.
345 static int
346 Win32_GetPerformanceInfo(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
348 Jim_Obj *a[26];
349 size_t n = 0;
350 PERFORMANCE_INFORMATION pi;
352 if (!GetPerformanceInfo(&pi, sizeof(pi))) {
353 Jim_SetResult(interp,
354 Win32ErrorObj(interp, "GetPerformanceInfo", GetLastError()));
355 return JIM_ERR;
358 #define JIMADD(name) \
359 a[n++] = Jim_NewStringObj(interp, #name, -1); \
360 a[n++] = Jim_NewIntObj(interp, pi. name )
362 JIMADD(CommitTotal);
363 JIMADD(CommitLimit);
364 JIMADD(CommitPeak);
365 JIMADD(PhysicalTotal);
366 JIMADD(PhysicalAvailable);
367 JIMADD(SystemCache);
368 JIMADD(KernelTotal);
369 JIMADD(KernelPaged);
370 JIMADD(KernelNonpaged);
371 JIMADD(PageSize);
372 JIMADD(HandleCount);
373 JIMADD(ProcessCount);
374 JIMADD(ThreadCount);
375 #undef JIMADD
377 Jim_SetResult(interp, Jim_NewListObj(interp, a, n));
378 return JIM_OK;
380 #endif
382 static int
383 Win32_SetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
385 int r = JIM_OK;
386 const char *name;
387 if (objc != 2) {
388 Jim_WrongNumArgs(interp, 1, objv, "computername");
389 return JIM_ERR;
391 name = Jim_String(objv[1]);
392 if (!SetComputerNameA(name)) {
393 Jim_SetResult(interp,
394 Win32ErrorObj(interp, "SetComputerName", GetLastError()));
395 r = JIM_ERR;
397 return r;
400 static int
401 Win32_GetModuleHandle(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
403 HMODULE hModule = NULL;
404 const char *name = NULL;
406 if (objc < 1 || objc > 2) {
407 Jim_WrongNumArgs(interp, 1, objv, "?name?");
408 return JIM_ERR;
410 if (objc == 2)
411 name = Jim_String(objv[1]);
412 hModule = GetModuleHandleA(name);
413 if (hModule == NULL) {
414 Jim_SetResult(interp,
415 Win32ErrorObj(interp, "GetModuleHandle", GetLastError()));
416 return JIM_ERR;
418 Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hModule));
419 return JIM_OK;
422 static int
423 Win32_LoadLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
425 HMODULE hLib = NULL;
426 if (objc != 2) {
427 Jim_WrongNumArgs(interp, 1, objv, "path");
428 return JIM_ERR;
430 hLib = LoadLibraryA(Jim_String(objv[1]));
431 if (hLib == NULL) {
432 Jim_SetResult(interp,
433 Win32ErrorObj(interp, "LoadLibrary", GetLastError()));
434 return JIM_ERR;
436 Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hLib));
437 return JIM_OK;
440 static int
441 Win32_FreeLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
443 HMODULE hModule = NULL;
444 int r = JIM_OK;
446 if (objc != 2) {
447 Jim_WrongNumArgs(interp, 1, objv, "hmodule");
448 return JIM_ERR;
451 r = Jim_GetLong(interp, objv[1], (long *)&hModule);
452 if (r == JIM_OK) {
453 if (!FreeLibrary(hModule)) {
454 Jim_SetResult(interp,
455 Win32ErrorObj(interp, "FreeLibrary", GetLastError()));
456 r = JIM_ERR;
460 return r;
464 /* ---------------------------------------------------------------------- */
467 Jim_win32Init(Jim_Interp *interp)
469 if (Jim_PackageProvide(interp, "win32", "1.0", JIM_ERRMSG))
470 return JIM_ERR;
472 #define CMD(name) \
473 Jim_CreateCommand(interp, "win32." #name , Win32_ ## name , NULL, NULL)
475 CMD(ShellExecute);
476 CMD(FindWindow);
477 CMD(CloseWindow);
478 CMD(GetActiveWindow);
479 CMD(SetActiveWindow);
480 CMD(SetForegroundWindow);
481 CMD(Beep);
482 CMD(GetComputerName);
483 CMD(SetComputerName);
484 CMD(GetUserName);
485 CMD(GetModuleFileName);
486 CMD(GetVersion);
487 CMD(GetTickCount);
488 CMD(GetSystemTime);
489 #if !defined(__MINGW32__) && !defined(__CYGWIN__)
490 CMD(GetPerformanceInfo);
491 #endif
492 CMD(GetModuleHandle);
493 CMD(LoadLibrary);
494 CMD(FreeLibrary);
496 return JIM_OK;