Add a mono_binary_search () function.
[mono.git] / support / supportw.c
1 /*
2  * Helper routines for some of the common methods that people P/Invoke
3  * on their applications.
4  *
5  * Authors:
6  *   Gonzalo Paniagua (gonzalo@ximian.com)
7  *   Miguel de Icaza  (miguel@novell.com)
8  *
9  * (C) 2005 Novell, Inc.
10  *
11  */
12 #include <glib.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include "supportw.h"
17 #include "mono/metadata/assembly.h"
18 #include "mono/metadata/class.h"
19 #include "mono/metadata/object.h"
20 #include "mono/metadata/tabledefs.h"
21 #include "mono/io-layer/wapi.h"
22 #include "mono/utils/bsearch.h"
23
24 typedef struct {
25         const char *fname;
26         void *fnptr;
27 } FnPtr;
28
29 gpointer FindWindowExW        (gpointer hwndParent, gpointer hwndChildAfter,
30                                const char *classw, const char *window);
31
32 gpointer GetProcessHeap       (void);
33
34 static FnPtr functions [] = {
35         { "FindWindowExW", NULL }, /* user32 */
36 };
37 #define NFUNCTIONS      (sizeof (functions)/sizeof (FnPtr))
38
39 static int swf_registered;
40
41 static int
42 compare_names (const void *key, const void *p)
43 {
44         FnPtr *ptr = (FnPtr *) p;
45         return strcmp (key, ptr->fname);
46 }
47
48 static gpointer
49 get_function (const char *name)
50 {
51         FnPtr *ptr;
52
53         ptr = mono_binary_search (name, functions, NFUNCTIONS, sizeof (FnPtr),
54                         compare_names);
55
56         if (ptr == NULL) {
57                 g_warning ("Function '%s' not not found.", name);
58                 return NULL;
59         }
60
61         return ptr->fnptr;
62 }
63
64 gboolean
65 supportw_register_delegate (const char *function_name, void *fnptr)
66 {
67         FnPtr *ptr;
68
69         g_return_val_if_fail (function_name && fnptr, FALSE);
70
71         ptr = mono_binary_search (function_name, functions, NFUNCTIONS, sizeof (FnPtr),
72                         compare_names);
73
74         if (ptr == NULL) {
75                 g_warning ("Function '%s' not supported.", function_name);
76                 return FALSE;
77         }
78
79         ptr->fnptr = fnptr;
80         return TRUE;
81 }
82
83 #define M_ATTRS (METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_STATIC)
84 static gboolean
85 register_assembly (const char *name, int *registered)
86 {
87 /* we can't use mono or wapi funcions in a support lib */
88 #if 0
89         MonoAssembly *assembly;
90         MonoImageOpenStatus status;
91         MonoImage *image;
92         MonoClass *klass;
93         MonoMethod *method;
94         MonoObject *exc;
95
96         if (*registered)
97                 return TRUE;
98
99         assembly = mono_assembly_load_with_partial_name (name, &status);
100         if (assembly == NULL) {
101                 g_warning ("Cannot load assembly '%s'.", name);
102                 return FALSE;
103         }
104
105         image = mono_assembly_get_image (assembly);
106         klass = mono_class_from_name (image, name, "LibSupport");
107         if (klass == NULL) {
108                 g_warning ("Cannot load class %s.LibSupport", name);
109                 mono_assembly_close (assembly);
110                 return FALSE;
111         }
112
113         method = mono_class_get_method_from_name_flags (klass, "Register", 0, M_ATTRS);
114         if (klass == NULL) {
115                 g_warning ("Cannot load method Register from klass %s.LibSupport", name);
116                 mono_assembly_close (assembly);
117                 return FALSE;
118         }
119
120         exc = NULL;
121         mono_runtime_invoke (method, NULL, NULL, &exc);
122         if (exc != NULL) {
123                 mono_assembly_close (assembly);
124                 mono_print_unhandled_exception (exc);
125                 return FALSE;
126         }
127         *registered = 1;
128         mono_assembly_close (assembly);
129         return TRUE;
130 #else
131         return FALSE;
132 #endif
133 }
134
135 void
136 supportw_test_all ()
137 {
138         int i;
139
140         register_assembly ("System.Windows.Forms", &swf_registered);
141         for (i = 0; i < NFUNCTIONS; i++) {
142                 FnPtr *ptr = &functions [i];
143                 if (ptr->fnptr == NULL)
144                         g_warning ("%s wasn't registered.", ptr->fname);
145         }
146 }
147
148 gpointer
149 FindWindowExW (gpointer hwndParent, gpointer hwndChildAfter, const char *classw, const char *window)
150 {
151         typedef gpointer (*func_type) (gpointer hwndParent, gpointer hwndChildAfter,
152                                         const char *classw, const char *window);
153         static func_type func;
154
155         g_return_val_if_fail (register_assembly ("System.Windows.Forms", &swf_registered), NULL);
156         if (func == NULL)
157                 func = (func_type) get_function ("FindWindowExW");
158
159         return func (hwndParent, hwndChildAfter, classw, window);
160 }
161
162 int
163 SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags)
164 {
165         fprintf (stderr, "SetWindowPos %p %p to [%d,%dx%d,%d] %d\n", hwnd, hwndInsertAfter, x, y, cx, cy, flags);
166         return 1;
167 }
168
169 int
170 SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam)
171 {
172         fprintf (stderr, "SendMessage (%d, 0x%x, %p, %p)\n", (int) GPOINTER_TO_INT (hwnd), msg, wparam, lparam);
173         return 0;
174 }
175
176 int
177 GetWindowLongA (gpointer hwnd, int a)
178 {
179         return 0;
180 }