From 4e83d2fca0861906f40eae8c4ed7afe8513833a2 Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Mon, 21 Jan 2013 00:08:08 -0600 Subject: [PATCH] winemac: Implement MsgWaitForMultipleObjectsEx and infrastructure for processing events. --- dlls/winemac.drv/Makefile.in | 1 + dlls/winemac.drv/event.c | 125 ++++++++++++++++++++++++++++++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/winemac.drv.spec | 1 + 4 files changed, 128 insertions(+) create mode 100644 dlls/winemac.drv/event.c diff --git a/dlls/winemac.drv/Makefile.in b/dlls/winemac.drv/Makefile.in index 0dfcbc42410..1de19ef7f36 100644 --- a/dlls/winemac.drv/Makefile.in +++ b/dlls/winemac.drv/Makefile.in @@ -4,6 +4,7 @@ EXTRALIBS = -framework AppKit C_SRCS = \ display.c \ + event.c \ gdi.c \ macdrv_main.c \ surface.c \ diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c new file mode 100644 index 00000000000..fcef5500829 --- /dev/null +++ b/dlls/winemac.drv/event.c @@ -0,0 +1,125 @@ +/* + * MACDRV event driver + * + * Copyright 1993 Alexandre Julliard + * 1999 Noel Borthwick + * Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc. + * + * 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 "macdrv.h" +#include "winuser.h" + +WINE_DEFAULT_DEBUG_CHANNEL(event); + + +/* return the name of an Mac event */ +static const char *dbgstr_event(int type) +{ + return wine_dbg_sprintf("Unknown event %d", type); +} + + +/*********************************************************************** + * get_event_mask + */ +static macdrv_event_mask get_event_mask(DWORD mask) +{ + if ((mask & QS_ALLINPUT) == QS_ALLINPUT) return -1; + return 0; +} + + +/*********************************************************************** + * macdrv_handle_event + */ +void macdrv_handle_event(macdrv_event *event) +{ + HWND hwnd = macdrv_get_window_hwnd(event->window); + const macdrv_event *prev; + struct macdrv_thread_data *thread_data = macdrv_thread_data(); + + TRACE("%s for hwnd/window %p/%p\n", dbgstr_event(event->type), hwnd, + event->window); + + prev = thread_data->current_event; + thread_data->current_event = event; + + switch (event->type) + { + default: + TRACE(" ignoring\n"); + break; + } + + thread_data->current_event = prev; +} + + +/*********************************************************************** + * process_events + */ +static int process_events(macdrv_event_queue queue, macdrv_event_mask mask) +{ + macdrv_event event; + int count = 0; + + while (macdrv_get_event_from_queue(queue, mask, &event)) + { + count++; + macdrv_handle_event(&event); + macdrv_cleanup_event(&event); + } + if (count) TRACE("processed %d events\n", count); + return count; +} + + +/*********************************************************************** + * MsgWaitForMultipleObjectsEx (MACDRV.@) + */ +DWORD CDECL macdrv_MsgWaitForMultipleObjectsEx(DWORD count, const HANDLE *handles, + DWORD timeout, DWORD mask, DWORD flags) +{ + DWORD ret; + struct macdrv_thread_data *data = macdrv_thread_data(); + macdrv_event_mask event_mask = get_event_mask(mask); + + TRACE("count %d, handles %p, timeout %u, mask %x, flags %x\n", count, + handles, timeout, mask, flags); + + if (!data) + { + if (!count && !timeout) return WAIT_TIMEOUT; + return WaitForMultipleObjectsEx(count, handles, flags & MWMO_WAITALL, + timeout, flags & MWMO_ALERTABLE); + } + + if (data->current_event) event_mask = 0; /* don't process nested events */ + + if (process_events(data->queue, event_mask)) ret = count - 1; + else if (count || timeout) + { + ret = WaitForMultipleObjectsEx(count, handles, flags & MWMO_WAITALL, + timeout, flags & MWMO_ALERTABLE); + if (ret == count - 1) process_events(data->queue, event_mask); + } + else ret = WAIT_TIMEOUT; + + return ret; +} diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index dee2fd8d210..7fe41095f2c 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -83,6 +83,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) struct macdrv_thread_data { macdrv_event_queue queue; + const macdrv_event *current_event; }; extern DWORD thread_data_tls_index DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec index 53b978598ef..f2ffffc69e0 100644 --- a/dlls/winemac.drv/winemac.drv.spec +++ b/dlls/winemac.drv/winemac.drv.spec @@ -9,6 +9,7 @@ @ cdecl DestroyWindow(long) macdrv_DestroyWindow @ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors @ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo +@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) macdrv_MsgWaitForMultipleObjectsEx @ cdecl SetLayeredWindowAttributes(long long long long) macdrv_SetLayeredWindowAttributes @ cdecl SetParent(long long long) macdrv_SetParent @ cdecl SetWindowRgn(long long long) macdrv_SetWindowRgn