aboutsummaryrefslogtreecommitdiff
path: root/jim-win32.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2010-10-20 10:55:07 +1000
committerSteve Bennett <steveb@workware.net.au>2010-10-30 20:07:28 +1000
commit8016c1d53332b9ad2af8e49482f7848648995a89 (patch)
treee45d82799d638cdfcc2020e7cc05131b60049384 /jim-win32.c
parentbbd43ee01fce3a2b5284154c50dfc9994c913a29 (diff)
downloadjimtcl-8016c1d53332b9ad2af8e49482f7848648995a89.zip
jimtcl-8016c1d53332b9ad2af8e49482f7848648995a89.tar.gz
jimtcl-8016c1d53332b9ad2af8e49482f7848648995a89.tar.bz2
Allow extensions to be built/installed as modules
This includes C extensions and Tcl extensions Also adds windows support (mingw32 and cygwin) Now the sqlite*, readline and win32 extensions are supported Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-win32.c')
-rw-r--r--jim-win32.c487
1 files changed, 487 insertions, 0 deletions
diff --git a/jim-win32.c b/jim-win32.c
new file mode 100644
index 0000000..2925fb5
--- /dev/null
+++ b/jim-win32.c
@@ -0,0 +1,487 @@
+/* WIN32 extension
+ *
+ * Copyright (C) 2005 Pat Thoyts <patthoyts@users.sourceforge.net>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * A copy of the license is also included in the source distribution
+ * of Jim, as a TXT file name called LICENSE.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jim.h>
+#include <shellapi.h>
+#include <lmcons.h>
+#include <psapi.h>
+#include <ctype.h>
+
+#if _MSC_VER >= 1000
+#pragma comment(lib, "shell32")
+#pragma comment(lib, "user32")
+#pragma comment(lib, "advapi32")
+#pragma comment(lib, "psapi")
+#endif /* _MSC_VER >= 1000 */
+
+static Jim_Obj *
+Win32ErrorObj(Jim_Interp *interp, const char * szPrefix, DWORD dwError)
+{
+ Jim_Obj *msgObj = NULL;
+ char * lpBuffer = NULL;
+ DWORD dwLen = 0;
+
+ dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, LANG_NEUTRAL,
+ (char *)&lpBuffer, 0, NULL);
+ if (dwLen < 1) {
+ dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ "code 0x%1!08X!%n", 0, LANG_NEUTRAL,
+ (char *)&lpBuffer, 0, (va_list *)&dwError);
+ }
+
+ msgObj = Jim_NewStringObj(interp, szPrefix, -1);
+ if (dwLen > 0) {
+ char *p = lpBuffer + dwLen - 1; /* remove cr-lf at end */
+ for ( ; p && *p && isspace((unsigned)*p); p--)
+ ;
+ *++p = 0;
+ Jim_AppendString(interp, msgObj, ": ", 2);
+ Jim_AppendString(interp, msgObj, lpBuffer, -1);
+ }
+ LocalFree((HLOCAL)lpBuffer);
+ return msgObj;
+}
+
+/* win32.ShellExecute verb file args */
+static int
+Win32_ShellExecute(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ int r;
+ const char *verb, *file, *parm = NULL;
+ char cwd[MAX_PATH + 1];
+
+ if (objc < 3 || objc > 4) {
+ Jim_WrongNumArgs(interp, 1, objv, "verb path ?parameters?");
+ return JIM_ERR;
+ }
+ verb = Jim_GetString(objv[1], NULL);
+ file = Jim_GetString(objv[2], NULL);
+ GetCurrentDirectoryA(MAX_PATH + 1, cwd);
+ if (objc == 4)
+ parm = Jim_GetString(objv[3], NULL);
+ r = (int)ShellExecuteA(NULL, verb, file, parm, cwd, SW_SHOWNORMAL);
+ if (r < 33)
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "ShellExecute", GetLastError()));
+ return (r < 33) ? JIM_ERR : JIM_OK;
+}
+
+
+/* win32.FindWindow title ?class? */
+static int
+Win32_FindWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ const char *title = NULL, *class = NULL;
+ HWND hwnd = NULL;
+ int r = JIM_OK;
+
+ if (objc < 2 || objc > 3) {
+ Jim_WrongNumArgs(interp, 1, objv, "title ?class?");
+ return JIM_ERR;
+ }
+ title = Jim_GetString(objv[1], NULL);
+ if (objc == 3)
+ class = Jim_GetString(objv[2], NULL);
+ hwnd = FindWindowA(class, title);
+
+ if (hwnd == NULL) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "FindWindow", GetLastError()));
+ r = JIM_ERR;
+ } else {
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (long)hwnd));
+ }
+ return r;
+}
+
+/* win32.CloseWindow windowHandle */
+static int
+Win32_CloseWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ long hwnd;
+
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "?windowHandle?");
+ return JIM_ERR;
+ }
+ if (Jim_GetLong(interp, objv[1], &hwnd) != JIM_OK)
+ return JIM_ERR;
+ if (!CloseWindow((HWND)hwnd)) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "CloseWindow", GetLastError()));
+ return JIM_ERR;
+ }
+ return JIM_OK;
+}
+
+static int
+Win32_GetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (DWORD)GetActiveWindow()));
+ return JIM_OK;
+}
+
+static int
+Win32_SetActiveWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HWND hwnd, old;
+ int r = JIM_OK;
+
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "windowHandle");
+ return JIM_ERR;
+ }
+ r = Jim_GetLong(interp, objv[1], (long *)&hwnd);
+ if (r == JIM_OK) {
+ old = SetActiveWindow(hwnd);
+ if (old == NULL) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "SetActiveWindow", GetLastError()));
+ r = JIM_ERR;
+ } else {
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (long)old));
+ }
+ }
+ return r;
+}
+
+static int
+Win32_SetForegroundWindow(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HWND hwnd;
+ int r = JIM_OK;
+
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "windowHandle");
+ return JIM_ERR;
+ }
+ r = Jim_GetLong(interp, objv[1], (long *)&hwnd);
+ if (r == JIM_OK) {
+ if (!SetForegroundWindow(hwnd)) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "SetForegroundWindow", GetLastError()));
+ r = JIM_ERR;
+ }
+ }
+ return r;
+}
+
+static int
+Win32_Beep(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ long freq, duration;
+ int r = JIM_OK;
+
+ if (objc != 3) {
+ Jim_WrongNumArgs(interp, 1, objv, "freq duration");
+ return JIM_ERR;
+ }
+ r = Jim_GetLong(interp, objv[1], &freq);
+ if (r == JIM_OK)
+ r = Jim_GetLong(interp, objv[2], &duration);
+ if (freq < 0x25) freq = 0x25;
+ if (freq > 0x7fff) freq = 0x7fff;
+ if (r == JIM_OK) {
+ if (!Beep(freq, duration)) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "Beep", GetLastError()));
+ r = JIM_ERR;
+ }
+ }
+ return r;
+}
+
+static int
+Win32_GetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ char name[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD size = MAX_COMPUTERNAME_LENGTH;
+ int r = JIM_OK;
+
+ if (objc != 1) {
+ Jim_WrongNumArgs(interp, 1, objv, "");
+ return JIM_ERR;
+ }
+
+ if (GetComputerNameA(name, &size)) {
+ Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size);
+ Jim_SetResult(interp, nameObj);
+ } else {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "GetComputerName", GetLastError()));
+ r = JIM_ERR;
+ }
+
+ return r;
+}
+
+static int
+Win32_GetUserName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ char name[UNLEN + 1];
+ DWORD size = UNLEN;
+ int r = JIM_OK;
+
+ if (objc != 1) {
+ Jim_WrongNumArgs(interp, 1, objv, "");
+ return JIM_ERR;
+ }
+
+ if (GetUserNameA(name, &size)) {
+ Jim_Obj *nameObj = Jim_NewStringObj(interp, name, size);
+ Jim_SetResult(interp, nameObj);
+ } else {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "GetUserName", GetLastError()));
+ r = JIM_ERR;
+ }
+
+ return r;
+}
+
+static int
+Win32_GetModuleFileName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HMODULE hModule = NULL;
+ char path[MAX_PATH];
+ DWORD len = 0;
+
+ if (objc > 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "?moduleid?");
+ return JIM_ERR;
+ }
+
+ if (objc == 2) {
+ if (Jim_GetLong(interp, objv[1], (long *)&hModule) != JIM_OK) {
+ return JIM_ERR;
+ }
+ }
+
+ len = GetModuleFileNameA(hModule, path, MAX_PATH);
+ if (len != 0) {
+ Jim_Obj *pathObj = Jim_NewStringObj(interp, path, len);
+ Jim_SetResult(interp, pathObj);
+ } else {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "GetModuleFileName", GetLastError()));
+ return JIM_ERR;
+ }
+
+ return JIM_OK;
+}
+
+static int
+Win32_GetVersion(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ Jim_SetResult(interp, Jim_NewIntObj(interp, GetVersion()));
+ return JIM_OK;
+}
+
+static int
+Win32_GetTickCount(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ Jim_SetResult(interp, Jim_NewIntObj(interp, GetTickCount()));
+ return JIM_OK;
+}
+
+static int
+Win32_GetSystemTime(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ Jim_Obj *a[16];
+ size_t n = 0;
+ SYSTEMTIME t;
+ GetSystemTime(&t);
+
+#define JIMADD(name) \
+ a[n++] = Jim_NewStringObj(interp, #name, -1); \
+ a[n++] = Jim_NewIntObj(interp, t.w ## name )
+
+ JIMADD(Year);
+ JIMADD(Month);
+ JIMADD(DayOfWeek);
+ JIMADD(Day);
+ JIMADD(Hour);
+ JIMADD(Minute);
+ JIMADD(Second);
+ JIMADD(Milliseconds);
+#undef JIMADD
+
+ Jim_SetResult(interp, Jim_NewListObj(interp, a, n));
+ return JIM_OK;
+}
+
+/* function not available on mingw or cygwin */
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
+// FIX ME: win2k+ so should do version checks really.
+static int
+Win32_GetPerformanceInfo(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ Jim_Obj *a[26];
+ size_t n = 0;
+ PERFORMANCE_INFORMATION pi;
+
+ if (!GetPerformanceInfo(&pi, sizeof(pi))) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "GetPerformanceInfo", GetLastError()));
+ return JIM_ERR;
+ }
+
+#define JIMADD(name) \
+ a[n++] = Jim_NewStringObj(interp, #name, -1); \
+ a[n++] = Jim_NewIntObj(interp, pi. name )
+
+ JIMADD(CommitTotal);
+ JIMADD(CommitLimit);
+ JIMADD(CommitPeak);
+ JIMADD(PhysicalTotal);
+ JIMADD(PhysicalAvailable);
+ JIMADD(SystemCache);
+ JIMADD(KernelTotal);
+ JIMADD(KernelPaged);
+ JIMADD(KernelNonpaged);
+ JIMADD(PageSize);
+ JIMADD(HandleCount);
+ JIMADD(ProcessCount);
+ JIMADD(ThreadCount);
+#undef JIMADD
+
+ Jim_SetResult(interp, Jim_NewListObj(interp, a, n));
+ return JIM_OK;
+}
+#endif
+
+static int
+Win32_SetComputerName(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ int r = JIM_OK;
+ const char *name;
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "computername");
+ return JIM_ERR;
+ }
+ name = Jim_GetString(objv[1], NULL);
+ if (!SetComputerNameA(name)) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "SetComputerName", GetLastError()));
+ r = JIM_ERR;
+ }
+ return r;
+}
+
+static int
+Win32_GetModuleHandle(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HMODULE hModule = NULL;
+ const char *name = NULL;
+
+ if (objc < 1 || objc > 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "?name?");
+ return JIM_ERR;
+ }
+ if (objc == 2)
+ name = Jim_GetString(objv[1], NULL);
+ hModule = GetModuleHandleA(name);
+ if (hModule == NULL) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "GetModuleHandle", GetLastError()));
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hModule));
+ return JIM_OK;
+}
+
+static int
+Win32_LoadLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HMODULE hLib = NULL;
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "path");
+ return JIM_ERR;
+ }
+ hLib = LoadLibraryA(Jim_GetString(objv[1], NULL));
+ if (hLib == NULL) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "LoadLibrary", GetLastError()));
+ return JIM_ERR;
+ }
+ Jim_SetResult(interp, Jim_NewIntObj(interp, (unsigned long)hLib));
+ return JIM_OK;
+}
+
+static int
+Win32_FreeLibrary(Jim_Interp *interp, int objc, Jim_Obj * const *objv)
+{
+ HMODULE hModule = NULL;
+ int r = JIM_OK;
+
+ if (objc != 2) {
+ Jim_WrongNumArgs(interp, 1, objv, "hmodule");
+ return JIM_ERR;
+ }
+
+ r = Jim_GetLong(interp, objv[1], (long *)&hModule);
+ if (r == JIM_OK) {
+ if (!FreeLibrary(hModule)) {
+ Jim_SetResult(interp,
+ Win32ErrorObj(interp, "FreeLibrary", GetLastError()));
+ r = JIM_ERR;
+ }
+ }
+
+ return r;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+int
+Jim_win32Init(Jim_Interp *interp)
+{
+ if (Jim_PackageProvide(interp, "win32", "1.0", JIM_ERRMSG))
+ return JIM_ERR;
+
+#define CMD(name) \
+ Jim_CreateCommand(interp, "win32." #name , Win32_ ## name , NULL, NULL)
+
+ CMD(ShellExecute);
+ CMD(FindWindow);
+ CMD(CloseWindow);
+ CMD(GetActiveWindow);
+ CMD(SetActiveWindow);
+ CMD(SetForegroundWindow);
+ CMD(Beep);
+ CMD(GetComputerName);
+ CMD(SetComputerName);
+ CMD(GetUserName);
+ CMD(GetModuleFileName);
+ CMD(GetVersion);
+ CMD(GetTickCount);
+ CMD(GetSystemTime);
+#if !defined(__MINGW32__) && !defined(__CYGWIN__)
+ CMD(GetPerformanceInfo);
+#endif
+ CMD(GetModuleHandle);
+ CMD(LoadLibrary);
+ CMD(FreeLibrary);
+
+ return JIM_OK;
+}