summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-02-18 10:01:47 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-02-18 10:01:47 +0000
commit9c1657f302d0d0e5b8eefa2a70f73bdb57d5fcd6 (patch)
treeebac1b974c7c9a60b995c57b95e25e4a0ab3ca21 /ext
parenta9662810df18371af7492dd8298cc0cccc13c7c7 (diff)
cygwin patches
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@83 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/Setup1
-rw-r--r--ext/Win32API/MANIFEST7
-rw-r--r--ext/Win32API/Win32API.c223
-rw-r--r--ext/Win32API/extconf.rb7
-rw-r--r--ext/Win32API/getch.rb5
-rw-r--r--ext/Win32API/point.rb18
-rw-r--r--ext/cygwin32_ld.rb90
7 files changed, 351 insertions, 0 deletions
diff --git a/ext/Setup b/ext/Setup
index 9e3a2474c3..d772f65d9a 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -11,3 +11,4 @@
#tkutil
#tcltklib
#gtk
+mandel
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 <windows.h>
+#include <stdio.h>
+
+#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..78b5f6a1e8
--- /dev/null
+++ b/ext/Win32API/extconf.rb
@@ -0,0 +1,7 @@
+if PLATFORM =~ /win32/i
+ $:.unshift '../..'
+ require 'rbconfig'
+ include Config
+ $CFLAGS = "-fno-defer-pop" if /gcc/ =~ CONFIG['CC']
+ 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
diff --git a/ext/cygwin32_ld.rb b/ext/cygwin32_ld.rb
new file mode 100644
index 0000000000..a9c8e21cb0
--- /dev/null
+++ b/ext/cygwin32_ld.rb
@@ -0,0 +1,90 @@
+#!/usr/local/bin/ruby
+require '../../rbconfig'
+include Config
+
+args = ARGV.join(" ")
+
+objs = []
+flags = []
+libname = ''
+Init = "../init"
+
+path = ''
+
+def writeInit
+ out = open("#{Init}.c", "w")
+
+ out.print %q@
+#include <windows.h>
+#include <stdio.h>
+
+extern struct _reent *__imp_reent_data;
+WINAPI dll_entry(int a, int b, int c)
+{
+ _impure_ptr =__imp_reent_data;
+ return 1;
+}
+main(){}
+//void impure_setup(struct _reent *_impure_ptrMain)
+//{
+// _impure_ptr =__imp_reent_data;
+//}
+@
+ out.close
+end
+
+def xsystem cmd
+ print cmd, "\n"
+ system cmd
+end
+
+if args =~ /-o (\w+)\.dll/i
+ libname = $1
+ # Check for path:
+ if libname =~ /(\w+\/)(\w+)$/
+ path = $1
+ libname = $2
+ end
+ for arg in ARGV
+ case arg
+ when /\.[oa]$/i
+ objs.push(arg)
+ when /-o/, /\w+\.dll/i
+ ;
+ else
+ flags << arg
+ end
+ end
+
+ writeInit unless FileTest.exist?("#{Init}.c")
+ unless FileTest.exist?("#{Init}.o") and
+ File.mtime("#{Init}.c") < File.mtime("#{Init}.o")
+ xsystem "gcc -c #{Init}.c -o #{Init}.o"
+ end
+
+ command = "echo EXPORTS > #{libname}.def"
+ xsystem command
+# xsystem "echo impure_setup >> #{libname}.def"
+ xsystem "nm --extern-only " + objs.join(" ") +
+ " | sed -n '/^........ [CDT] _/s///p' >> #{libname}.def"
+
+ command = "gcc -nostdlib -o junk.o -Wl,--base-file,#{libname}.base,--dll " +
+ objs.join(" ") + " #{Init}.o "
+ command.concat(flags.join(" ") +
+ " -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a")
+ xsystem command
+
+ command = "dlltool --as=as --dllname #{libname}.dll --def #{libname}.def --base-file #{libname}.base --output-exp #{libname}.exp"
+ xsystem command
+
+ command = "gcc -s -nostdlib -o #{libname}.dll -Wl,--dll #{libname}.exp " +
+ objs.join(" ") + " #{Init}.o "
+ command.concat(flags.join(" ") +
+ " -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a")
+ xsystem command
+ File.unlink "junk.o" if FileTest.exist? "junk.o"
+
+else
+ # no special processing, just call ld
+ xsystem "ld #{args}"
+end