From 62e648e148b3cb9f96dcce808c55c02b7ccb4486 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 20 Jan 1999 04:59:39 +0000 Subject: ruby 1.3 cycle git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/RUBY@372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/Win32API/MANIFEST | 7 ++ ext/Win32API/Win32API.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ ext/Win32API/extconf.rb | 7 ++ ext/Win32API/getch.rb | 5 ++ ext/Win32API/point.rb | 18 ++++ 5 files changed, 260 insertions(+) create mode 100644 ext/Win32API/MANIFEST create mode 100644 ext/Win32API/Win32API.c create mode 100644 ext/Win32API/extconf.rb create mode 100644 ext/Win32API/getch.rb create mode 100644 ext/Win32API/point.rb (limited to 'ext/Win32API') diff --git a/ext/Win32API/MANIFEST b/ext/Win32API/MANIFEST new file mode 100644 index 0000000000..7cc9ac445e --- /dev/null +++ b/ext/Win32API/MANIFEST @@ -0,0 +1,7 @@ +MANIFEST +depend +MANIFEST +Win32API.c +extconf.rb +getch.rb +point.rb diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c new file mode 100644 index 0000000000..f4cb5c726f --- /dev/null +++ b/ext/Win32API/Win32API.c @@ -0,0 +1,223 @@ +/* + Win32API - Ruby Win32 API Import Facility +*/ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#define _T_VOID 0 +#define _T_NUMBER 1 +#define _T_POINTER 2 +#define _T_INTEGER 3 + +typedef char *ApiPointer(void); +typedef long ApiNumber(void); +typedef void ApiVoid(void); +typedef int ApiInteger(void); + +#include "ruby.h" + +typedef struct { + HANDLE dll; + HANDLE proc; + VALUE dllname; + VALUE import; + VALUE export; +} Win32API; + +static void +Win32API_FreeLibrary(hdll) + HINSTANCE hdll; +{ + FreeLibrary(hdll); +} + +static VALUE +Win32API_initialize(self, dllname, proc, import, export) + VALUE self; + VALUE dllname; + VALUE proc; + VALUE import; + VALUE export; +{ + HANDLE hproc; + HINSTANCE hdll; + VALUE str; + VALUE a_import; + VALUE *ptr; + int i; + int len; + int ex; + + hdll = GetModuleHandle(RSTRING(dllname)->ptr); + if (!hdll) { + hdll = LoadLibrary(RSTRING(dllname)->ptr); + if (!hdll) + Fail("LoadLibrary: %s\n", RSTRING(dllname)->ptr); + Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll); + } + hproc = GetProcAddress(hdll, RSTRING(proc)->ptr); + if (!hproc) { + str = str_new3(proc); + str = str_cat(str, "A", 1); + hproc = GetProcAddress(hdll, RSTRING(str)->ptr); + if (!hproc) + Fail("GetProcAddress: %s or %s\n", + RSTRING(proc)->ptr, RSTRING(str)->ptr); + } + rb_iv_set(self, "__dll__", INT2NUM((int)hdll)); + rb_iv_set(self, "__dllname__", dllname); + rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); + + a_import = ary_new(); + ptr = RARRAY(import)->ptr; + for (i = 0, len = RARRAY(import)->len; i < len; i++) { + int c = *(char *)RSTRING(ptr[i])->ptr; + switch (c) { + case 'N': case 'n': case 'L': case 'l': + ary_push(a_import, INT2FIX(_T_NUMBER)); + break; + case 'P': case 'p': + ary_push(a_import, INT2FIX(_T_POINTER)); + break; + case 'I': case 'i': + ary_push(a_import, INT2FIX(_T_INTEGER)); + break; + } + } + rb_iv_set(self, "__import__", a_import); + + switch (*RSTRING(export)->ptr) { + case 'V': case 'v': + ex = _T_VOID; + break; + case 'N': case 'n': case 'L': case 'l': + ex = _T_NUMBER; + break; + case 'P': case 'p': + ex = _T_POINTER; + break; + case 'I': case 'i': + ex = _T_INTEGER; + break; + } + rb_iv_set(self, "__export__", INT2FIX(ex)); + + return Qnil; +} + +static VALUE +Win32API_Call(argc, argv, obj) + VALUE argc; + VALUE argv; + VALUE obj; +{ + VALUE args; + + FARPROC ApiFunction; + + ApiPointer *ApiFunctionPointer; + ApiNumber *ApiFunctionNumber; + ApiVoid *ApiFunctionVoid; + ApiInteger *ApiFunctionInteger; + + long lParam; + char *pParam; + + VALUE Return; + + VALUE obj_proc; + VALUE obj_import; + VALUE obj_export; + VALUE import_type; + int nimport, timport, texport, i; + int items; + + items = rb_scan_args(argc, argv, "0*", &args); + + obj_proc = rb_iv_get(obj, "__proc__"); + + ApiFunction = (FARPROC)NUM2INT(obj_proc); + + obj_import = rb_iv_get(obj, "__import__"); + obj_export = rb_iv_get(obj, "__export__"); + nimport = RARRAY(obj_import)->len; + texport = FIX2INT(obj_export); + + if (items != nimport) + Fail("Wrong number of parameters: expected %d, got %d.\n", + nimport, items); + + if (0 < nimport) { + for (i = nimport - 1; 0 <= i; i--) { + VALUE str; + import_type = ary_entry(obj_import, i); + timport = FIX2INT(import_type); + switch (timport) { + case _T_NUMBER: + case _T_INTEGER: + lParam = NUM2INT(ary_entry(args, i)); +#if defined(_MSC_VER) || defined(__LCC__) + _asm { + mov eax, lParam + push eax + } +#elif defined(__CYGWIN32__) || defined(__MINGW32__) + asm volatile ("pushl %0" :: "g" (lParam)); +#else +#error +#endif + break; + case _T_POINTER: + str = ary_entry(args, i); + Check_Type(str, T_STRING); + str_modify(str); + pParam = RSTRING(str)->ptr; +#if defined(_MSC_VER) || defined(__LCC__) + _asm { + mov eax, dword ptr pParam + push eax + } +#elif defined(__CYGWIN32__) || defined(__MINGW32__) + asm volatile ("pushl %0" :: "g" (pParam)); +#else +#error +#endif + break; + } + } + + } + + switch (texport) { + case _T_NUMBER: + ApiFunctionNumber = (ApiNumber *) ApiFunction; + Return = INT2NUM(ApiFunctionNumber()); + break; + case _T_POINTER: + ApiFunctionPointer = (ApiPointer *) ApiFunction; + Return = str_new2((char *)ApiFunctionPointer()); + break; + case _T_INTEGER: + ApiFunctionInteger = (ApiInteger *) ApiFunction; + Return = INT2NUM(ApiFunctionInteger()); + break; + case _T_VOID: + default: + ApiFunctionVoid = (ApiVoid *) ApiFunction; + ApiFunctionVoid(); + Return = INT2NUM(0); + break; + } + return Return; +} + +void +Init_Win32API() +{ + VALUE cWin32API = rb_define_class("Win32API", cObject); + rb_define_method(cWin32API, "initialize", Win32API_initialize, 4); + rb_define_method(cWin32API, "call", Win32API_Call, -1); + rb_define_alias(cWin32API, "Call", "call"); +} diff --git a/ext/Win32API/extconf.rb b/ext/Win32API/extconf.rb new file mode 100644 index 0000000000..5af3243d96 --- /dev/null +++ b/ext/Win32API/extconf.rb @@ -0,0 +1,7 @@ +case PLATFORM +when /cygwin/,/mingw/ + $CFLAGS = "-fno-defer-pop" + create_makefile("Win32API") +when /win32/ + create_makefile("Win32API") +end diff --git a/ext/Win32API/getch.rb b/ext/Win32API/getch.rb new file mode 100644 index 0000000000..c015bbe9bc --- /dev/null +++ b/ext/Win32API/getch.rb @@ -0,0 +1,5 @@ +require 'Win32API' + +getch = Win32API.new("crtdll", "_getch", [], 'L') + +puts getch.Call.chr diff --git a/ext/Win32API/point.rb b/ext/Win32API/point.rb new file mode 100644 index 0000000000..60e265f3ee --- /dev/null +++ b/ext/Win32API/point.rb @@ -0,0 +1,18 @@ +require 'Win32API' + +getCursorPos = Win32API.new("user32", "GetCursorPos", ['P'], 'V') + +lpPoint = " " * 8 # store two LONGs +getCursorPos.Call(lpPoint) +x, y = lpPoint.unpack("LL") # get the actual values + +print "x: ", x, "\n" +print "y: ", y, "\n" + +ods = Win32API.new("kernel32", "OutputDebugString", ['P'], 'V') +ods.Call("Hello, World\n"); + +GetDesktopWindow = Win32API.new("user32", "GetDesktopWindow", [], 'L') +GetActiveWindow = Win32API.new("user32", "GetActiveWindow", [], 'L') +SendMessage = Win32API.new("user32", "SendMessage", ['L'] * 4, 'L') +SendMessage.Call GetDesktopWindow.Call, 274, 0xf140, 0 -- cgit v1.2.3