winequartz.drv: Add mouse events handling and stub window creation
support.
Pierre d'Herbemont
pdherbemont at free.fr
Sun Nov 19 17:24:01 CST 2006
Hi,
This patch adds very basic window support, and implement mouse events
handling through Carbon Envent Handler.
I have choosen not to send the Win32 messages in the window creation,
because most of the process is the same as winex11.drv. We should
probably move those to user?
Pierre.
---
dlls/winequartz.drv/Makefile.in | 8 +-
dlls/winequartz.drv/carbon_imports.h | 52 ++++++
dlls/winequartz.drv/event.c | 75 ++++++++
dlls/winequartz.drv/mouse.c | 242 +++++++++++++++++++++++++
dlls/winequartz.drv/quartzdrv.h | 107 +++++++++++
dlls/winequartz.drv/quartzdrv_carbon.c | 278
+++++++++++++++++++++++++++++
dlls/winequartz.drv/quartzdrv_main.c | 94 ++++++++++-
dlls/winequartz.drv/window.c | 294
+++++++++++++++++++++++++++++++
dlls/winequartz.drv/winequartz.drv.spec | 23 +++-
dlls/winequartz.drv/winpos.c | 69 +++++++
10 files changed, 1235 insertions(+), 7 deletions(-)
-------------- next part --------------
diff --git a/dlls/winequartz.drv/Makefile.in b/dlls/winequartz.drv/Makefile.in
index b2214b6..9d0ccc0 100644
--- a/dlls/winequartz.drv/Makefile.in
+++ b/dlls/winequartz.drv/Makefile.in
@@ -4,9 +4,15 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = winequartz.drv
IMPORTS = user32 gdi32 advapi32 kernel32 ntdll
+EXTRALIBS = -framework Carbon
C_SRCS = \
- quartzdrv_main.c
+ event.c \
+ mouse.c \
+ quartzdrv_carbon.c \
+ quartzdrv_main.c \
+ window.c \
+ winpos.c
@MAKE_DLL_RULES@
diff --git a/dlls/winequartz.drv/carbon_imports.h b/dlls/winequartz.drv/carbon_imports.h
new file mode 100644
index 0000000..787acc0
--- /dev/null
+++ b/dlls/winequartz.drv/carbon_imports.h
@@ -0,0 +1,52 @@
+/*
+ * Imported Carbon Functions code whose names may conflict with
+ * Win32 equivalents
+ *
+ * Copyright 2006 Emmanuel Maillard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_CARBON_IMPORTS_H
+#define __WINE_CARBON_IMPORTS_H
+
+#include <dlfcn.h>
+
+#define CARBON_FUNCT(fct) \
+ static typeof(fct) * carbonPtr_##fct;
+CARBON_FUNCT(ShowWindow)
+CARBON_FUNCT(HideWindow)
+#undef CARBON_FUNCT
+
+static inline void * BindCarbonFunctions(void)
+{
+ void * HIToolBoxDLHandle = dlopen("/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox", RTLD_LAZY | RTLD_LOCAL);
+
+ if (!HIToolBoxDLHandle) {
+ ERR("can't open HIToolBoxDLHandle\n");
+ return nil;
+ }
+#define LOAD_FUNCTION(f) \
+ if((carbonPtr_##f = dlsym(HIToolBoxDLHandle, #f)) == NULL) \
+ { \
+ ERR("Can't find symbol %s\n", #f); \
+ return nil; \
+ }
+ LOAD_FUNCTION(ShowWindow)
+ LOAD_FUNCTION(HideWindow)
+#undef LOAD_FUNCTION
+ return HIToolBoxDLHandle;
+}
+#endif /* __WINE_CARBON_IMPORTS_H */
diff --git a/dlls/winequartz.drv/event.c b/dlls/winequartz.drv/event.c
new file mode 100644
index 0000000..479cceb
--- /dev/null
+++ b/dlls/winequartz.drv/event.c
@@ -0,0 +1,75 @@
+/*
+ * Quartz event driver
+ *
+ * Copyright 1993 Alexandre Julliard
+ * 1999 Noel Borthwick
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COM_NO_WINDOWS_H
+#include "config.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "shlobj.h" /* DROPFILES */
+
+#include "win.h"
+#include "winreg.h"
+#include "quartzdrv.h"
+#include "shellapi.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(event);
+
+/***********************************************************************
+ * MsgWaitForMultipleObjectsEx (QDRV.@)
+ */
+DWORD QDRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles,
+ DWORD timeout, DWORD mask, DWORD flags )
+{
+ DWORD ret;
+ struct quartzdrv_thread_data *data = TlsGetValue( thread_data_tls_index );
+
+ if (!data || data->process_event_count)
+ {
+ if (!count && !timeout) return WAIT_TIMEOUT;
+ return WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
+ timeout, flags & MWMO_ALERTABLE );
+ }
+
+ /* check whether only server queue handle was passed in */
+ if (count < 2) flags &= ~MWMO_WAITALL;
+
+ data->process_event_count++;
+
+ if (count || timeout)
+ {
+ ret = WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
+ timeout, flags & MWMO_ALERTABLE );
+ }
+ else ret = WAIT_TIMEOUT;
+
+ data->process_event_count--;
+ return ret;
+}
\ No newline at end of file
diff --git a/dlls/winequartz.drv/mouse.c b/dlls/winequartz.drv/mouse.c
new file mode 100644
index 0000000..826c8ff
--- /dev/null
+++ b/dlls/winequartz.drv/mouse.c
@@ -0,0 +1,242 @@
+/*
+ * Quartz (Mac OS X) mouse driver
+ *
+ * Copyright 1998 Ulrich Weigand
+ * Copyright 2006 Emmanuel Maillard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "wine/winuser16.h"
+
+#include "win.h"
+#include "quartzdrv.h"
+#include "wine/server.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(cursor);
+
+/* ---------------------------------------------------------------------
+ * get_button_down_flags
+ */
+static inline UINT get_button_down_flags(int buttons)
+{
+ static const UINT button_down_flags[] =
+ {
+ MOUSEEVENTF_LEFTDOWN,
+ MOUSEEVENTF_MIDDLEDOWN,
+ MOUSEEVENTF_RIGHTDOWN,
+ };
+ return button_down_flags[buttons-1];
+}
+
+/* ---------------------------------------------------------------------
+ * get_button_up_flags
+ */
+static inline UINT get_button_up_flags(int buttons)
+{
+ static const UINT button_up_flags[] =
+ {
+ MOUSEEVENTF_LEFTUP,
+ MOUSEEVENTF_MIDDLEUP,
+ MOUSEEVENTF_RIGHTUP,
+ };
+ return button_up_flags[buttons-1];
+}
+
+/* ---------------------------------------------------------------------
+ * queue_raw_mouse_message
+ */
+static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y,
+ DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
+{
+ MSLLHOOKSTRUCT hook;
+
+ hook.pt.x = x;
+ hook.pt.y = y;
+ hook.mouseData = MAKELONG( 0, data );
+ hook.flags = injected_flags;
+ hook.time = time;
+ hook.dwExtraInfo = extra_info;
+
+ if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return;
+
+ SERVER_START_REQ( send_hardware_message )
+ {
+ req->id = (injected_flags & LLMHF_INJECTED) ? 0 : GetCurrentThreadId();
+ req->win = hwnd;
+ req->msg = message;
+ req->wparam = MAKEWPARAM( MK_CONTROL|MK_SHIFT, data );
+ req->lparam = 0;
+ req->x = x;
+ req->y = y;
+ req->time = time;
+ req->info = extra_info;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+
+}
+
+/* ---------------------------------------------------------------------
+ * send_mouse_input
+ */
+static void send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
+ DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
+{
+ POINT pt;
+
+ pt.x = x;
+ pt.y = y;
+
+ if (flags & MOUSEEVENTF_MOVE)
+ {
+ queue_raw_mouse_message( WM_MOUSEMOVE, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+
+ if (flags & MOUSEEVENTF_LEFTDOWN)
+ {
+ queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
+ hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_LEFTUP)
+ {
+ queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP,
+ hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_RIGHTDOWN)
+ {
+ queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
+ hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_RIGHTUP)
+ {
+ queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP,
+ hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_MIDDLEDOWN)
+ {
+ queue_raw_mouse_message( WM_MBUTTONDOWN, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_MIDDLEUP)
+ {
+ queue_raw_mouse_message( WM_MBUTTONUP, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_WHEEL)
+ {
+ queue_raw_mouse_message( WM_MOUSEWHEEL, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_XDOWN)
+ {
+ queue_raw_mouse_message( WM_XBUTTONDOWN, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+ if (flags & MOUSEEVENTF_XUP)
+ {
+ queue_raw_mouse_message( WM_XBUTTONUP, hwnd, pt.x, pt.y, data, time,
+ extra_info, injected_flags );
+ }
+}
+
+/* ---------------------------------------------------------------------
+ * update_mouse_state
+ *
+ * Update the various window states on a mouse event.
+ */
+static void update_mouse_state( HWND hwnd, ObjectRef window, int x, int y)
+{
+ static int fixme_count = 0;
+ if(fixme_count++ < 2)
+ FIXME("Should check cursor changes here\n");
+
+ /* update the wine server Z-order */
+
+ SERVER_START_REQ( update_window_zorder )
+ {
+ req->window = hwnd;
+ req->rect.left = x;
+ req->rect.top = y;
+ req->rect.right = x + 1;
+ req->rect.bottom = y + 1;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+}
+
+/***********************************************************************
+ * QDRV_ButtonPress (QDRV.@)
+ */
+void QDRV_ButtonPress(ObjectRef view, int x, int y, int button)
+{
+ struct quartzdrv_win_data *data;
+
+ TRACE("win=%p x=%d y=%d button=%d\n", view, x, y, button);
+
+ if (!(data = get_quartzdrv_win_data_from_objref(view)))
+ return;
+
+ update_mouse_state(data->hwnd, view, x, y);
+
+ send_mouse_input( data->hwnd, get_button_up_flags(button),
+ x, y, button, GetTickCount(), 0, 0 );
+}
+
+/***********************************************************************
+ * QDRV_ButtonRelease (QDRV.@)
+ */
+void QDRV_ButtonRelease(ObjectRef view, int x, int y, int button)
+{
+ struct quartzdrv_win_data *data;
+
+ TRACE("win=%p x=%d y=%d button=%d\n", view, x, y, button);
+
+ if (!(data = get_quartzdrv_win_data_from_objref(view)))
+ return;
+
+ update_mouse_state( data->hwnd, view, x, y);
+
+ send_mouse_input( data->hwnd, get_button_down_flags(button),
+ x, y, button, GetTickCount(), 0, 0 );
+}
+
+/***********************************************************************
+ * QDRV_MotionNotify (QDRV.@)
+ */
+void QDRV_MotionNotify(ObjectRef view, int x, int y)
+{
+ struct quartzdrv_win_data *data;
+
+ TRACE("win=%p x=%d y=%d\n", view, x, y);
+
+ if (!(data = get_quartzdrv_win_data_from_objref(view)))
+ return;
+
+ update_mouse_state(data->hwnd, view, x, y);
+
+ send_mouse_input( data->hwnd, MOUSEEVENTF_MOVE,
+ x, y, 0, GetTickCount(), 0, 0 );
+}
\ No newline at end of file
diff --git a/dlls/winequartz.drv/quartzdrv.h b/dlls/winequartz.drv/quartzdrv.h
new file mode 100644
index 0000000..0b3a098
--- /dev/null
+++ b/dlls/winequartz.drv/quartzdrv.h
@@ -0,0 +1,107 @@
+/*
+ * Quartz driver definitions
+ *
+ * Copyright 1996 Alexandre Julliard
+ * Copyright 1999 Patrik Stridvall
+ * Copyright 2006 Emmanuel Maillard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_QUARTZDRV_H
+#define __WINE_QUARTZDRV_H
+
+/* ---------------------------------------------------------------------
+ per-Thread data management
+*/
+struct quartzdrv_thread_data
+{
+ int process_event_count; /* recursion count for event processing */
+};
+
+extern struct quartzdrv_thread_data *quartzdrv_init_thread_data(void);
+extern DWORD thread_data_tls_index;
+
+inline static struct quartzdrv_thread_data *quartzdrv_thread_data(void)
+{
+ struct quartzdrv_thread_data *data = TlsGetValue( thread_data_tls_index );
+ if (!data) data = quartzdrv_init_thread_data();
+ return data;
+}
+
+/* ---------------------------------------------------------------------
+ Window management
+*/
+typedef void * ObjectRef;
+
+struct quartzdrv_win_data
+{
+ HWND hwnd;
+ ObjectRef carbon_view; /* Ptr to the Object HIViewRef
+ that represent the window on Carbon side. if null its the desktop */
+ ObjectRef carbon_window; /* if not NULL, carbon_window represents the WindowRef
+ asssociated with the hwnd */
+ RECT hwnd_rect; /* The position of the hwnd */
+};
+
+/* ---------------------------------------------------------------------
+ Carbon/Carbon.h
+*/
+extern int HIViewSetVisible(ObjectRef inView, BOOL inVisible);
+extern ObjectRef HIViewGetRoot(ObjectRef inWindow);
+extern void CFRelease(ObjectRef obj);
+
+/* ---------------------------------------------------------------------
+ quartzdrv_carbon.c
+*/
+extern unsigned int screen_width;
+extern unsigned int screen_height;
+
+extern void CARBON_ShowWindow(ObjectRef win);
+extern void CARBON_HideWindow(ObjectRef win);
+
+extern void QDRV_CarbonSetViewData(ObjectRef view, const struct quartzdrv_win_data *data);
+extern void QDRV_CarbonGetViewData(ObjectRef view, struct quartzdrv_win_data **data);
+extern void QDRV_CarbonSetWindowFrame(ObjectRef win, int left, int top, int right, int bottom);
+extern void QDRV_CarbonDeleteWindow(ObjectRef win);
+extern ObjectRef QDRV_CarbonCreateNewWindow(int top, int left, int right, int bottom);
+
+extern ObjectRef QDRV_CarbonCreateNewView(ObjectRef parent, int top, int left, int right, int bottom);
+
+extern DWORD WINAPI QDRV_CarbonRunEventLoop(void * args);
+
+extern void QDRV_CarbonInitialize(void);
+extern void QDRV_CarbonFinalize(void);
+
+/* ---------------------------------------------------------------------
+ quartzdrv_main.c
+*/
+extern void wine_quartzdrv_lock(void);
+extern void wine_quartzdrv_unlock(void);
+
+/* ---------------------------------------------------------------------
+ mouse.c
+*/
+void QDRV_ButtonPress(ObjectRef view, int x, int y, int button);
+void QDRV_ButtonRelease(ObjectRef view, int x, int y, int button);
+void QDRV_MotionNotify(ObjectRef view, int x, int y);
+
+/* ---------------------------------------------------------------------
+ window.c
+*/
+struct quartzdrv_win_data *get_quartzdrv_win_data_from_objref(ObjectRef view);
+
+
+#endif /* __WINE_QUARTZDRV_H */
diff --git a/dlls/winequartz.drv/quartzdrv_carbon.c b/dlls/winequartz.drv/quartzdrv_carbon.c
new file mode 100644
index 0000000..3782213
--- /dev/null
+++ b/dlls/winequartz.drv/quartzdrv_carbon.c
@@ -0,0 +1,278 @@
+/*
+ * QUARTZDRV Carbon bridge code
+ *
+ * Copyright 2006 Emmanuel Maillard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "windef.h"
+
+#include "wine/debug.h"
+
+/* Undef those definitions from wine/debug.h as they are redefined in Carbon.h */
+#undef _CDECL
+#undef DPRINTF
+#include <Carbon/Carbon.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartzdrv);
+
+/* Import Carbon Function whose name may collide with their Win32 equivalent */
+#include "carbon_imports.h"
+static void * HIToolBoxDLHandle = NULL;
+
+extern void wine_quartzdrv_lock(void);
+extern void wine_quartzdrv_unlock(void);
+
+static const void* wine_quartzdrv_view_data_key = (void*)'WQVD';
+static EventHandlerUPP wine_event_handler_upp = NULL;
+
+
+unsigned int screen_width;
+unsigned int screen_height;
+WindowRef root_window = NULL;
+
+extern void QDRV_ButtonPress(HIViewRef view, int x, int y, int button);
+extern void QDRV_ButtonRelease(HIViewRef view, int x, int y, int button);
+extern void QDRV_MotionNotify(HIViewRef view, int x, int y);
+
+/***********************************************************************
+ * CARBON_ShowWindow
+ */
+void CARBON_ShowWindow(WindowRef win)
+{
+ if (carbonPtr_ShowWindow) carbonPtr_ShowWindow(win);
+}
+
+/***********************************************************************
+ * CARBON_HideWindow
+ */
+void CARBON_HideWindow(WindowRef win)
+{
+ if (carbonPtr_HideWindow) carbonPtr_HideWindow(win);
+}
+
+/***********************************************************************
+ * QDRV_SetWindowFrame
+ *
+ * Associate the Window bridge data (hwnd mainly) with our
+ * (Carbon) Window
+ */
+void QDRV_CarbonSetWindowFrame(WindowRef win, int left, int top, int right, int bottom)
+{
+ Rect bounds;
+ bounds.left = left;
+ bounds.top = top;
+ bounds.right = right;
+ bounds.bottom = bottom;
+ SetWindowBounds(win, kWindowStructureRgn, &bounds);
+}
+
+/***********************************************************************
+ * QDRV_CarbonSetViewData
+ *
+ * Associate the Window bridge data (hwnd mainly) with our
+ * (Carbon) View
+ */
+void QDRV_CarbonSetViewData(HIViewRef view, const void *data)
+{
+ CFDictionaryRef dict;
+ OSStatus err;
+ dict = CFDictionaryCreate(kCFAllocatorDefault, &wine_quartzdrv_view_data_key, &data, 1, NULL, NULL);
+ err = HIObjectSetCustomArchiveData((HIObjectRef)view, dict);
+ if(err != noErr)
+ ERR("Can't HIObjectSetCustomArchiveData\n");
+}
+
+/***********************************************************************
+ * QDRV_CarbonGetViewData
+ *
+ * Return the Window bridge data (hwnd mainly) associated with
+ * our (Carbon) View
+ */
+void QDRV_CarbonGetViewData(HIViewRef view, const void **data)
+{
+ CFDictionaryRef dict;
+ OSStatus err;
+ err = HIObjectCopyCustomArchiveData((HIObjectRef)view, &dict);
+ if(err != noErr)
+ ERR("Can't HIObjectCopyCustomArchiveData\n");
+ *data = CFDictionaryGetValue(dict, wine_quartzdrv_view_data_key);
+}
+
+/***********************************************************************
+ * QDRV_CarbonDeleteWindow
+ */
+void QDRV_CarbonDeleteWindow(WindowRef win)
+{
+ DisposeWindow(win);
+}
+
+/*----------------------------------------------------------------------
+ * event_handler
+ */
+OSStatus event_handler(EventHandlerCallRef handler, EventRef event, void *arg)
+{
+ UInt32 eventKind = GetEventKind(event);
+ WindowPartCode where;
+ WindowRef window;
+ UInt16 button;
+ Point point;
+
+ GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point);
+
+ wine_quartzdrv_lock();
+ /* window will be set to null if it is none of our window, which correspond to our root_window */
+ GetEventParameter(event, kEventParamWindowRef, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window);
+ GetEventParameter(event, kEventParamWindowPartCode, typeWindowPartCode, NULL, sizeof(WindowPartCode), NULL, &where);
+ wine_quartzdrv_unlock();
+
+ TRACE("event=%p in window=%p where=%x\n", event, window, where);
+
+ switch (eventKind)
+ {
+ case kEventMouseDown:
+ if (where == inMenuBar)
+ {
+ MenuSelect(point);
+ break;
+ }
+ GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(UInt16), NULL, &button);
+ QDRV_ButtonPress(HIViewGetRoot(window), point.h, point.v, (int) button);
+ break;
+ case kEventMouseUp:
+ if (where == inMenuBar)
+ break;
+ GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(UInt16), NULL, &button);
+ QDRV_ButtonRelease(HIViewGetRoot(window), point.h, point.v, (int) button);
+ break;
+ case kEventMouseMoved:
+ if (where == inMenuBar)
+ break;
+ QDRV_MotionNotify(HIViewGetRoot(window), point.h, point.v);
+ break;
+ }
+
+ return noErr;
+}
+
+/*----------------------------------------------------------------------
+ * install_event_handler
+ */
+static void install_event_handler(EventTargetRef target)
+{
+ const EventTypeSpec events[] = {
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseUp }
+ };
+ InstallEventHandler(target, wine_event_handler_upp, GetEventTypeCount(events), events, NULL, NULL );
+}
+
+
+/***********************************************************************
+ * QDRV_CarbonCreateNewWindow
+ */
+WindowRef QDRV_CarbonCreateNewWindow(int top, int left, int right, int bottom)
+{
+ OSStatus err;
+ WindowRef window;
+ Rect bounds;
+ WindowAttributes attrs;
+
+ TRACE("top=%d left=%d right=%d bottom=%d\n", top, left, right, bottom);
+
+ attrs = kWindowStandardHandlerAttribute | kWindowCompositingAttribute | kWindowNoTitleBarAttribute;
+
+ bounds.top = (short)top;
+ bounds.left = (short)left;
+ bounds.right = (short)right;
+ bounds.bottom = (short)bottom;
+
+ err = CreateNewWindow(kDocumentWindowClass, attrs, &bounds, &window);
+ if(err != noErr)
+ return NULL;
+
+ return window;
+}
+
+/***********************************************************************
+ * QDRV_CarbonCreateNewView
+ */
+HIViewRef QDRV_CarbonCreateNewView(HIViewRef parent, int top, int left, int right, int bottom)
+{
+ OSStatus err;
+ HIViewRef view;
+ HIRect frame;
+
+ err = HIImageViewCreate(NULL, &view);
+ if(err != noErr)
+ return nil;
+
+ err = HIViewAddSubview(parent, view);
+ if(err != noErr)
+ return view;
+
+ frame.origin.x = (double)top;
+ frame.origin.y = (double)left;
+ frame.size.width = (double)(right-left);
+ frame.size.height = (double)(bottom-top);
+
+ err = HIViewSetFrame(view, &frame);
+
+ return view;
+}
+
+
+/***********************************************************************
+ * QDRV_CarbonRunEventLoop
+ */
+DWORD WINAPI QDRV_CarbonRunEventLoop(void * args)
+{
+ RunApplicationEventLoop();
+
+ return 0;
+}
+
+/***********************************************************************
+ * QDRV_Initialize
+ */
+void QDRV_CarbonInitialize(void)
+{
+ ProcessSerialNumber psn;
+
+ GetProcessForPID(getpid(), &psn);
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+ SetFrontProcess(&psn);
+
+ screen_width = CGDisplayPixelsWide(CGMainDisplayID());
+ screen_height = CGDisplayPixelsHigh(CGMainDisplayID());
+
+ HIToolBoxDLHandle = BindCarbonFunctions();
+
+ wine_event_handler_upp = NewEventHandlerUPP(event_handler);
+ install_event_handler( (void*)GetApplicationEventTarget() );
+}
+
+/***********************************************************************
+ * QDRV_Finalize
+ */
+void QDRV_CarbonFinalize(void)
+{
+ dlclose(HIToolBoxDLHandle);
+ DisposeEventHandlerUPP(wine_event_handler_upp);
+}
\ No newline at end of file
diff --git a/dlls/winequartz.drv/quartzdrv_main.c b/dlls/winequartz.drv/quartzdrv_main.c
index 88bc6ac..c93e51e 100644
--- a/dlls/winequartz.drv/quartzdrv_main.c
+++ b/dlls/winequartz.drv/quartzdrv_main.c
@@ -26,8 +26,92 @@
#include "winbase.h"
#include "winreg.h"
+#include "wine/debug.h"
+
+#include "quartzdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartzdrv);
+
+DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
+
+static CRITICAL_SECTION QDRV_CritSection;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &QDRV_CritSection,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": QDRV_CritSection") }
+};
+static CRITICAL_SECTION QDRV_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };
+
/***********************************************************************
- * QUARTZDRV initialisation routine
+ * QDRV thread initialisation routine
+ */
+struct quartzdrv_thread_data *quartzdrv_init_thread_data(void)
+{
+ struct quartzdrv_thread_data *data;
+
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) )))
+ {
+ ERR( "could not create data\n" );
+ ExitProcess(1);
+ }
+
+ data->process_event_count = 0;
+
+ TlsSetValue( thread_data_tls_index, data );
+
+ return data;
+}
+
+/***********************************************************************
+ * wine_quartzdrv_lock (QDRV.@)
+ */
+void wine_quartzdrv_lock(void)
+{
+ EnterCriticalSection( &QDRV_CritSection );
+}
+
+/***********************************************************************
+ * wine_quartzdrv_unlock (QDRV.@)
+ */
+void wine_quartzdrv_unlock(void)
+{
+ LeaveCriticalSection( &QDRV_CritSection );
+}
+
+/***********************************************************************
+ * process initialisation routine
+ */
+static BOOL process_attach(void)
+{
+ HANDLE handle;
+ TRACE("\n");
+ QDRV_CarbonInitialize();
+ if(!(handle = CreateThread(NULL, 0, QDRV_CarbonRunEventLoop, NULL, 0, NULL)))
+ return FALSE;
+ CloseHandle(handle);
+ return TRUE;
+}
+
+/***********************************************************************
+ * thread termination routine
+ */
+static void thread_detach(void)
+{
+ TRACE("\n");
+}
+
+/***********************************************************************
+ * process termination routine
+ */
+static void process_detach(void)
+{
+ TRACE("\n");
+ QDRV_CarbonFinalize();
+}
+
+/***********************************************************************
+ * Dll entry point
*/
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{
@@ -36,14 +120,14 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DW
switch(reason)
{
case DLL_PROCESS_ATTACH:
- /* Do attach */
+ ret = process_attach();
break;
case DLL_THREAD_DETACH:
- /* do thread detach */
+ thread_detach();
break;
case DLL_PROCESS_DETACH:
- /* do detach */
+ process_detach();
break;
}
return ret;
-}
+}
\ No newline at end of file
diff --git a/dlls/winequartz.drv/window.c b/dlls/winequartz.drv/window.c
new file mode 100644
index 0000000..ef9c676
--- /dev/null
+++ b/dlls/winequartz.drv/window.c
@@ -0,0 +1,294 @@
+/*
+ * Window related functions
+ *
+ * Copyright 1993, 1994, 1995, 1996, 2001 Alexandre Julliard
+ * Copyright 1993 David Metcalfe
+ * Copyright 1995, 1996 Alex Korobka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winreg.h"
+#include "winuser.h"
+#include "wine/unicode.h"
+#include "win.h"
+
+#include "wine/debug.h"
+#include "wine/server.h"
+
+#include "quartzdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartzdrv);
+
+static struct quartzdrv_win_data * root_window = NULL;
+
+static const char * wine_quartzdrv_win_data = "__wine_quartzdrv_win_data" ;
+
+/* ---------------------------------------------------------------------
+ * alloc_quartzdrv_win_data
+ */
+struct quartzdrv_win_data *alloc_quartzdrv_win_data(HWND hwnd)
+{
+ struct quartzdrv_win_data * data;
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) )))
+ {
+ ERR("Not enough memory\n");
+ return NULL;
+ }
+ data->hwnd = hwnd;
+ data->carbon_window = 0;
+ data->carbon_view = 0;
+ SetPropA(hwnd, wine_quartzdrv_win_data, (HANDLE)data);
+ return data;
+}
+
+/* ---------------------------------------------------------------------
+ * get_quartzdrv_win_data_from_hwnd
+ */
+struct quartzdrv_win_data *get_quartzdrv_win_data_from_hwnd(HWND hwnd)
+{
+ return (struct quartzdrv_win_data *)GetPropA(hwnd, wine_quartzdrv_win_data);
+}
+
+/* ---------------------------------------------------------------------
+ * get_quartzdrv_win_data_from_objref
+ */
+struct quartzdrv_win_data *get_quartzdrv_win_data_from_objref(ObjectRef view)
+{
+ struct quartzdrv_win_data *ret;
+ if(!view)
+ return root_window;
+ wine_quartzdrv_lock();
+ QDRV_CarbonGetViewData(view, &ret);
+ wine_quartzdrv_unlock();
+ return ret;
+}
+
+/***********************************************************************
+ * SetWindowText (QDRV.@)
+ */
+void QDRV_SetWindowText( HWND hwnd, LPCWSTR text )
+{
+ FIXME("stub!\n");
+}
+
+
+/***********************************************************************
+ * CreateDesktopWindow (QDRV.@)
+ */
+BOOL QDRV_CreateDesktopWindow( HWND hwnd )
+{
+ FIXME("stub!\n");
+ return FALSE;
+}
+
+/***********************************************************************
+ * ShowWindow (QDRV.@)
+ */
+BOOL QDRV_ShowWindow( HWND hwnd, INT cmd )
+{
+ struct quartzdrv_win_data *data = get_quartzdrv_win_data_from_hwnd(hwnd);
+
+ /* Quick stub to see the window */
+ FIXME("stub\n");
+
+ if(!data)
+ return FALSE;
+
+ switch(cmd)
+ {
+ case SW_HIDE:
+ wine_quartzdrv_lock();
+ if(data->carbon_window)
+ CARBON_HideWindow(data->carbon_window);
+ else
+ HIViewSetVisible(data->carbon_view, FALSE);
+ wine_quartzdrv_unlock();
+
+ break;
+
+ case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE */
+ case SW_SHOWNA:
+ case SW_SHOW:
+ case SW_SHOWNOACTIVATE:
+ case SW_SHOWNORMAL: /* same as SW_NORMAL: */
+ case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
+ wine_quartzdrv_lock();
+ if(data->carbon_window)
+ CARBON_ShowWindow(data->carbon_window);
+ else if(data->carbon_view)
+ HIViewSetVisible(data->carbon_view, TRUE);
+ wine_quartzdrv_unlock();
+ break;
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * CreateWindow (QDRV.@)
+ */
+BOOL QDRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
+{
+ struct quartzdrv_win_data *data = alloc_quartzdrv_win_data(hwnd);
+
+ TRACE("\n");
+
+ if(!data)
+ return FALSE;
+
+ if (cs->cx > 65535)
+ {
+ ERR( "invalid window width %d\n", cs->cx );
+ cs->cx = 50;
+ }
+ if (cs->cy > 65535)
+ {
+ ERR( "invalid window height %d\n", cs->cy );
+ cs->cy = 50;
+ }
+ if (cs->cx < 0)
+ {
+ ERR( "invalid window width %d\n", cs->cx );
+ cs->cx = 50;
+ }
+ if (cs->cy < 0)
+ {
+ ERR( "invalid window height %d\n", cs->cy );
+ cs->cy = 50;
+ }
+
+ if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
+ {
+ wine_quartzdrv_lock();
+ data->carbon_window = QDRV_CarbonCreateNewWindow(cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy);
+ data->carbon_view = HIViewGetRoot(data->carbon_window);
+ QDRV_CarbonSetViewData(data->carbon_view, data);
+ wine_quartzdrv_unlock();
+ }
+ else if(hwnd == GetDesktopWindow())
+ {
+ wine_quartzdrv_lock();
+ root_window = data;
+ wine_quartzdrv_unlock();
+ }
+ else
+ {
+ struct quartzdrv_win_data *parent_data = get_quartzdrv_win_data_from_hwnd(GetAncestor( hwnd, GA_PARENT ));
+ wine_quartzdrv_lock();
+ data->carbon_window = 0;
+ data->carbon_view = QDRV_CarbonCreateNewView(parent_data->carbon_view, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy);
+ QDRV_CarbonSetViewData(data->carbon_view, data);
+ wine_quartzdrv_unlock();
+ }
+
+ SetRect(&data->hwnd_rect, cs->x, cs->y, cs->cx, cs->cy);
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * SetParent (QDRV.@)
+ */
+HWND QDRV_SetParent( HWND hwnd, HWND parent )
+{
+ HWND old_parent = 0;
+ WND *wndPtr;
+ BOOL ret;
+
+ FIXME("\n");
+
+ /* Get the old parent from the wineserver */
+ wndPtr = WIN_GetPtr( hwnd );
+ if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0;
+
+ SERVER_START_REQ( set_parent )
+ {
+ req->handle = hwnd;
+ req->parent = parent;
+ if ((ret = !wine_server_call( req )))
+ {
+ old_parent = reply->old_parent;
+ wndPtr->parent = parent = reply->full_parent;
+ }
+
+ }
+ SERVER_END_REQ;
+ WIN_ReleasePtr( wndPtr );
+ if (!ret) return 0;
+
+ if (parent != old_parent)
+ {
+ struct quartzdrv_win_data *data = get_quartzdrv_win_data_from_hwnd(hwnd);
+ if(!data)
+ return 0;
+ if (parent != GetDesktopWindow())
+ {
+ if(old_parent == GetDesktopWindow())
+ {
+ /* make the hwnd a HIView instead of a Window */
+ struct quartzdrv_win_data *parent_data = get_quartzdrv_win_data_from_hwnd(parent);
+ ObjectRef parent_view = NULL;
+ if(parent_data)
+ parent_view = parent_data->carbon_view;
+
+ wine_quartzdrv_lock();
+ QDRV_CarbonDeleteWindow(data->carbon_window);
+ data->carbon_window = 0;
+ data->carbon_view = QDRV_CarbonCreateNewView(parent_view, data->hwnd_rect.top, data->hwnd_rect.left, data->hwnd_rect.right, data->hwnd_rect.bottom);
+ QDRV_CarbonSetViewData(data->carbon_view, data);
+ wine_quartzdrv_unlock();
+ }
+ }
+ else
+ {
+ /* make the hwnd a Window instead of a HIView */
+ wine_quartzdrv_lock();
+ CFRelease(data->carbon_view);
+ data->carbon_window = QDRV_CarbonCreateNewWindow(data->hwnd_rect.top, data->hwnd_rect.left, data->hwnd_rect.right, data->hwnd_rect.bottom);
+ data->carbon_view = HIViewGetRoot(data->carbon_window);
+ QDRV_CarbonSetViewData(data->carbon_view, data);
+ wine_quartzdrv_unlock();
+ }
+ }
+ return old_parent;
+}
+
+/***********************************************************************
+ * SetFocus (QDRV.@)
+ */
+void QDRV_SetFocus( HWND hwnd )
+{
+ FIXME("stub!\n");
+}
+
+/***********************************************************************
+ * SetWindowIcon (QDRV.@)
+ */
+void QDRV_SetWindowIcon( HWND hwnd, UINT type, HICON icon )
+{
+ FIXME("stub!\n");
+}
diff --git a/dlls/winequartz.drv/winequartz.drv.spec b/dlls/winequartz.drv/winequartz.drv.spec
index d98d860..c843c1e 100644
--- a/dlls/winequartz.drv/winequartz.drv.spec
+++ b/dlls/winequartz.drv/winequartz.drv.spec
@@ -1 +1,22 @@
-# Nothing Yet
+# Window Functions
+@ cdecl CreateWindow(long ptr long) QDRV_CreateWindow
+@ cdecl ShowWindow(long long) QDRV_ShowWindow
+@ cdecl SetParent(long long) QDRV_SetParent
+
+# Window Functions unimplemented
+@ cdecl CreateDesktopWindow(long) QDRV_CreateDesktopWindow
+@ cdecl SetWindowText(long wstr) QDRV_SetWindowText
+@ cdecl SetFocus(long) QDRV_SetFocus
+@ cdecl SetWindowIcon(long long long) QDRV_SetWindowIcon
+
+@ cdecl SetWindowPos(ptr) QDRV_SetWindowPos
+@ cdecl SysCommandSizeMove(long long) QDRV_SysCommandSizeMove
+@ cdecl SetWindowStyle(ptr long) QDRV_SetWindowStyle
+@ cdecl SetWindowRgn(long long long) QDRV_SetWindowRgn
+
+# Event
+@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) QDRV_MsgWaitForMultipleObjectsEx
+
+# Quartzdrv locks
+@ cdecl -norelay wine_quartzdrv_lock()
+@ cdecl -norelay wine_quartzdrv_unlock()
diff --git a/dlls/winequartz.drv/winpos.c b/dlls/winequartz.drv/winpos.c
new file mode 100644
index 0000000..88d6ac4
--- /dev/null
+++ b/dlls/winequartz.drv/winpos.c
@@ -0,0 +1,69 @@
+/*
+ * Window position related functions.
+ *
+ * Copyright 1993, 1994, 1995, 2001 Alexandre Julliard
+ * Copyright 1995, 1996, 1999 Alex Korobka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "win.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartzdrv);
+
+/***********************************************************************
+ * SetWindowStyle (QDRV.@)
+ */
+void QDRV_SetWindowStyle( HWND hwnd, DWORD old_style )
+{
+ FIXME("stub!\n");
+}
+
+/***********************************************************************
+ * SetWindowPos (QDRV.@)
+ */
+BOOL QDRV_SetWindowPos( WINDOWPOS *winpos )
+{
+ FIXME("stub!\n");
+ return TRUE;
+}
+
+/***********************************************************************
+ * SetWindowRgn (QDRV.@)
+ */
+int QDRV_SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL redraw )
+{
+ FIXME("stub!\n");
+ return 0;
+}
+
+/***********************************************************************
+ * SysCommandSizeMove (QDRV.@)
+ */
+void QDRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
+{
+ FIXME("stub!\n");
+}
\ No newline at end of file
More information about the wine-patches
mailing list