180 lines
4.1 KiB
C
180 lines
4.1 KiB
C
|
/*
|
||
|
* Helper routines for some of the common methods that people P/Invoke
|
||
|
* on their applications.
|
||
|
*
|
||
|
* Authors:
|
||
|
* Gonzalo Paniagua (gonzalo@ximian.com)
|
||
|
* Miguel de Icaza (miguel@novell.com)
|
||
|
*
|
||
|
* (C) 2005 Novell, Inc.
|
||
|
*
|
||
|
*/
|
||
|
#include <glib.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include "supportw.h"
|
||
|
#include "mono/metadata/assembly.h"
|
||
|
#include "mono/metadata/class.h"
|
||
|
#include "mono/metadata/object.h"
|
||
|
#include "mono/metadata/tabledefs.h"
|
||
|
#include "mono/io-layer/wapi.h"
|
||
|
|
||
|
typedef struct {
|
||
|
const char *fname;
|
||
|
void *fnptr;
|
||
|
} FnPtr;
|
||
|
|
||
|
gpointer FindWindowExW (gpointer hwndParent, gpointer hwndChildAfter,
|
||
|
const char *classw, const char *window);
|
||
|
|
||
|
gpointer GetProcessHeap (void);
|
||
|
|
||
|
static FnPtr functions [] = {
|
||
|
{ "FindWindowExW", NULL }, /* user32 */
|
||
|
};
|
||
|
#define NFUNCTIONS (sizeof (functions)/sizeof (FnPtr))
|
||
|
|
||
|
static int swf_registered;
|
||
|
|
||
|
static int
|
||
|
compare_names (const void *key, const void *p)
|
||
|
{
|
||
|
FnPtr *ptr = (FnPtr *) p;
|
||
|
return strcmp (key, ptr->fname);
|
||
|
}
|
||
|
|
||
|
static gpointer
|
||
|
get_function (const char *name)
|
||
|
{
|
||
|
FnPtr *ptr;
|
||
|
|
||
|
ptr = bsearch (name, functions, NFUNCTIONS, sizeof (FnPtr),
|
||
|
compare_names);
|
||
|
|
||
|
if (ptr == NULL) {
|
||
|
g_warning ("Function '%s' not not found.", name);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return ptr->fnptr;
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
supportw_register_delegate (const char *function_name, void *fnptr)
|
||
|
{
|
||
|
FnPtr *ptr;
|
||
|
|
||
|
g_return_val_if_fail (function_name && fnptr, FALSE);
|
||
|
|
||
|
ptr = bsearch (function_name, functions, NFUNCTIONS, sizeof (FnPtr),
|
||
|
compare_names);
|
||
|
|
||
|
if (ptr == NULL) {
|
||
|
g_warning ("Function '%s' not supported.", function_name);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
ptr->fnptr = fnptr;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
#define M_ATTRS (METHOD_ATTRIBUTE_PUBLIC | METHOD_ATTRIBUTE_STATIC)
|
||
|
static gboolean
|
||
|
register_assembly (const char *name, int *registered)
|
||
|
{
|
||
|
/* we can't use mono or wapi funcions in a support lib */
|
||
|
#if 0
|
||
|
MonoAssembly *assembly;
|
||
|
MonoImageOpenStatus status;
|
||
|
MonoImage *image;
|
||
|
MonoClass *klass;
|
||
|
MonoMethod *method;
|
||
|
MonoObject *exc;
|
||
|
|
||
|
if (*registered)
|
||
|
return TRUE;
|
||
|
|
||
|
assembly = mono_assembly_load_with_partial_name (name, &status);
|
||
|
if (assembly == NULL) {
|
||
|
g_warning ("Cannot load assembly '%s'.", name);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
image = mono_assembly_get_image (assembly);
|
||
|
klass = mono_class_from_name (image, name, "LibSupport");
|
||
|
if (klass == NULL) {
|
||
|
g_warning ("Cannot load class %s.LibSupport", name);
|
||
|
mono_assembly_close (assembly);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
method = mono_class_get_method_from_name_flags (klass, "Register", 0, M_ATTRS);
|
||
|
if (klass == NULL) {
|
||
|
g_warning ("Cannot load method Register from klass %s.LibSupport", name);
|
||
|
mono_assembly_close (assembly);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
exc = NULL;
|
||
|
mono_runtime_invoke (method, NULL, NULL, &exc);
|
||
|
if (exc != NULL) {
|
||
|
mono_assembly_close (assembly);
|
||
|
mono_print_unhandled_exception (exc);
|
||
|
return FALSE;
|
||
|
}
|
||
|
*registered = 1;
|
||
|
mono_assembly_close (assembly);
|
||
|
return TRUE;
|
||
|
#else
|
||
|
return FALSE;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
supportw_test_all ()
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
register_assembly ("System.Windows.Forms", &swf_registered);
|
||
|
for (i = 0; i < NFUNCTIONS; i++) {
|
||
|
FnPtr *ptr = &functions [i];
|
||
|
if (ptr->fnptr == NULL)
|
||
|
g_warning ("%s wasn't registered.", ptr->fname);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gpointer
|
||
|
FindWindowExW (gpointer hwndParent, gpointer hwndChildAfter, const char *classw, const char *window)
|
||
|
{
|
||
|
typedef gpointer (*func_type) (gpointer hwndParent, gpointer hwndChildAfter,
|
||
|
const char *classw, const char *window);
|
||
|
static func_type func;
|
||
|
|
||
|
g_return_val_if_fail (register_assembly ("System.Windows.Forms", &swf_registered), NULL);
|
||
|
if (func == NULL)
|
||
|
func = (func_type) get_function ("FindWindowExW");
|
||
|
|
||
|
return func (hwndParent, hwndChildAfter, classw, window);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags)
|
||
|
{
|
||
|
fprintf (stderr, "SetWindowPos %p %p to [%d,%dx%d,%d] %d\n", hwnd, hwndInsertAfter, x, y, cx, cy, flags);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam)
|
||
|
{
|
||
|
fprintf (stderr, "SendMessage (%d, 0x%x, %p, %p)\n", (int) GPOINTER_TO_INT (hwnd), msg, wparam, lparam);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
GetWindowLongA (gpointer hwnd, int a)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|