winequartz.drv: Add mouse events handling and stub window creation support. (take2)

Pierre d'Herbemont pdherbemont at free.fr
Mon Nov 20 09:48:52 CST 2006


As suggested I removed the locking functions that were previously needed 
because of the use of the old Carbon function MacFindWindows which 
wasn't thread safe. Now that it is removed there is no locking needed.

I removed the per-thread data, though used in event.c for event 
processing as in x11drv. But as advised I guess don't really need it at 
this stage.

The GetProp call was removed and replaced with a CFDictionary.

And last, I am sorry for the fprintf and french languages that subsisted 
in the carbon import file. And I moved the header to quartzdrv_carbon.c 
as advised.

Thanks for the feedback,

Pierre.
---
  dlls/winequartz.drv/Makefile.in         |    8 +-
  dlls/winequartz.drv/event.c             |   64 +++++++
  dlls/winequartz.drv/mouse.c             |  242 +++++++++++++++++++++++++
  dlls/winequartz.drv/quartzdrv.h         |   82 +++++++++
  dlls/winequartz.drv/quartzdrv_carbon.c  |  302 
+++++++++++++++++++++++++++++++
  dlls/winequartz.drv/quartzdrv_main.c    |   49 +++++-
  dlls/winequartz.drv/window.c            |  278 
++++++++++++++++++++++++++++
  dlls/winequartz.drv/winequartz.drv.spec |   19 ++-
  dlls/winequartz.drv/winpos.c            |   69 +++++++
  9 files changed, 1106 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/event.c b/dlls/winequartz.drv/event.c
new file mode 100644
index 0000000..f0738a8
--- /dev/null
+++ b/dlls/winequartz.drv/event.c
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+    /* check whether only server queue handle was passed in */
+    if (count < 2) flags &= ~MWMO_WAITALL;
+
+    if (count || timeout)
+    {
+        ret = WaitForMultipleObjectsEx( count, handles, flags & MWMO_WAITALL,
+                                        timeout, flags & MWMO_ALERTABLE );
+    }
+    else ret = WAIT_TIMEOUT;
+
+    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..ae9a894
--- /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
+ */
+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
+ */
+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
+ */
+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..1287ec5
--- /dev/null
+++ b/dlls/winequartz.drv/quartzdrv.h
@@ -0,0 +1,82 @@
+/*
+ * 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
+
+/* ---------------------------------------------------------------------
+   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);
+
+/* ---------------------------------------------------------------------
+   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);
+
+/* ---------------------------------------------------------------------
+   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..7ffb1e4
--- /dev/null
+++ b/dlls/winequartz.drv/quartzdrv_carbon.c
@@ -0,0 +1,302 @@
+/*
+ * 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 <dlfcn.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);
+
+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);
+
+
+/* Import Carbon Function whose name may collide with their Win32 equivalent */
+static void * HIToolBoxDLHandle = NULL;
+
+#define CARBON_FUNCT(fct) \
+	static typeof(fct) * carbonPtr_##fct;
+CARBON_FUNCT(ShowWindow)
+CARBON_FUNCT(HideWindow)
+#undef CARBON_FUNCT
+
+/*----------------------------------------------------------------------
+ *          bind_carbon_functions
+ */
+static inline void * bind_carbon_functions(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;
+}
+
+/***********************************************************************
+ *          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);
+
+    /* 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);
+    
+    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 = bind_carbon_functions();
+    
+    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..63274a2 100644
--- a/dlls/winequartz.drv/quartzdrv_main.c
+++ b/dlls/winequartz.drv/quartzdrv_main.c
@@ -26,8 +26,47 @@
 #include "winbase.h"
 #include "winreg.h"
 
+#include "wine/debug.h"
+
+#include "quartzdrv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(quartzdrv);
+
+/*----------------------------------------------------------------------
+ *           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();
+}
+
 /***********************************************************************
- *           QUARTZDRV initialisation routine
+ *           Dll entry point
  */
 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 {
@@ -36,14 +75,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..29a6fd8
--- /dev/null
+++ b/dlls/winequartz.drv/window.c
@@ -0,0 +1,278 @@
+/*
+ * 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 <CoreFoundation/CoreFoundation.h>
+
+#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 CFMutableDictionaryRef quartzdrv_win_data_from_hwnd = NULL;
+
+/* ---------------------------------------------------------------------
+ *  alloc_quartzdrv_win_data
+ */
+struct quartzdrv_win_data *alloc_quartzdrv_win_data(const 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;
+    if(!quartzdrv_win_data_from_hwnd)
+        quartzdrv_win_data_from_hwnd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    CFDictionaryAddValue(quartzdrv_win_data_from_hwnd, hwnd, 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 *)CFDictionaryGetValue(quartzdrv_win_data_from_hwnd, hwnd);
+}
+
+/* ---------------------------------------------------------------------
+ *  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;
+    QDRV_CarbonGetViewData(view, &ret);
+    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:
+            if(data->carbon_window)
+                CARBON_HideWindow(data->carbon_window);
+            else
+                HIViewSetVisible(data->carbon_view, FALSE);
+	    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 */
+            if(data->carbon_window)
+                CARBON_ShowWindow(data->carbon_window);
+            else if(data->carbon_view)
+                HIViewSetVisible(data->carbon_view, TRUE);
+	    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())
+    {
+        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);
+    }
+    else if(hwnd == GetDesktopWindow())
+        root_window = data;
+    else
+    {
+        struct quartzdrv_win_data *parent_data = get_quartzdrv_win_data_from_hwnd(GetAncestor( hwnd, GA_PARENT ));
+        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);
+    }
+    
+    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;
+                
+                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);
+            }
+        }
+        else
+        {
+            /* make the hwnd a Window instead of a HIView */
+            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);
+        }
+    }
+    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..5fd487d 100644
--- a/dlls/winequartz.drv/winequartz.drv.spec
+++ b/dlls/winequartz.drv/winequartz.drv.spec
@@ -1 +1,18 @@
-# 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
\ No newline at end of file
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