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