Commit 207c4d19 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Associate an event queue with each thread that creates windows and with each window.

parent 3c995bb6
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
@class WineEventQueue;
@interface WineWindow : NSPanel <NSWindowDelegate> @interface WineWindow : NSPanel <NSWindowDelegate>
{ {
NSUInteger normalStyleMask; NSUInteger normalStyleMask;
...@@ -29,6 +32,8 @@ ...@@ -29,6 +32,8 @@
BOOL floating; BOOL floating;
WineWindow* latentParentWindow; WineWindow* latentParentWindow;
WineEventQueue* queue;
void* surface; void* surface;
pthread_mutex_t* surface_mutex; pthread_mutex_t* surface_mutex;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "macdrv_cocoa.h" #include "macdrv_cocoa.h"
#import "cocoa_app.h" #import "cocoa_app.h"
#import "cocoa_event.h"
static NSUInteger style_mask_for_features(const struct macdrv_window_features* wf) static NSUInteger style_mask_for_features(const struct macdrv_window_features* wf)
...@@ -65,6 +66,8 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -65,6 +66,8 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@property (nonatomic) BOOL floating; @property (nonatomic) BOOL floating;
@property (retain, nonatomic) NSWindow* latentParentWindow; @property (retain, nonatomic) NSWindow* latentParentWindow;
@property (retain, nonatomic) WineEventQueue* queue;
@property (nonatomic) void* surface; @property (nonatomic) void* surface;
@property (nonatomic) pthread_mutex_t* surface_mutex; @property (nonatomic) pthread_mutex_t* surface_mutex;
...@@ -159,7 +162,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -159,7 +162,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
@implementation WineWindow @implementation WineWindow
@synthesize disabled, noActivate, floating, latentParentWindow; @synthesize disabled, noActivate, floating, latentParentWindow, queue;
@synthesize surface, surface_mutex; @synthesize surface, surface_mutex;
@synthesize shape, shapeChangedSinceLastDraw; @synthesize shape, shapeChangedSinceLastDraw;
@synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue; @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
...@@ -167,6 +170,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -167,6 +170,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
+ (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)wf + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)wf
windowFrame:(NSRect)window_frame windowFrame:(NSRect)window_frame
queue:(WineEventQueue*)queue
{ {
WineWindow* window; WineWindow* window;
WineContentView* contentView; WineContentView* contentView;
...@@ -191,6 +195,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -191,6 +195,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[window setHasShadow:wf->shadow]; [window setHasShadow:wf->shadow];
[window setColorSpace:[NSColorSpace genericRGBColorSpace]]; [window setColorSpace:[NSColorSpace genericRGBColorSpace]];
[window setDelegate:window]; [window setDelegate:window];
window.queue = queue;
contentView = [[[WineContentView alloc] initWithFrame:NSZeroRect] autorelease]; contentView = [[[WineContentView alloc] initWithFrame:NSZeroRect] autorelease];
if (!contentView) if (!contentView)
...@@ -204,6 +209,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -204,6 +209,7 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
- (void) dealloc - (void) dealloc
{ {
[queue release];
[latentParentWindow release]; [latentParentWindow release];
[shape release]; [shape release];
[super dealloc]; [super dealloc];
...@@ -441,13 +447,14 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens) ...@@ -441,13 +447,14 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
* title bar, close box, etc.). * title bar, close box, etc.).
*/ */
macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf, macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf,
CGRect frame) CGRect frame, macdrv_event_queue queue)
{ {
__block WineWindow* window; __block WineWindow* window;
OnMainThread(^{ OnMainThread(^{
window = [[WineWindow createWindowWithFeatures:wf window = [[WineWindow createWindowWithFeatures:wf
windowFrame:NSRectFromCGRect(frame)] retain]; windowFrame:NSRectFromCGRect(frame)
queue:(WineEventQueue*)queue] retain];
}); });
return (macdrv_window)window; return (macdrv_window)window;
...@@ -463,6 +470,7 @@ void macdrv_destroy_cocoa_window(macdrv_window w) ...@@ -463,6 +470,7 @@ void macdrv_destroy_cocoa_window(macdrv_window w)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
WineWindow* window = (WineWindow*)w; WineWindow* window = (WineWindow*)w;
[window.queue discardEventsMatchingMask:-1 forWindow:window];
[window close]; [window close];
[window release]; [window release];
......
...@@ -80,6 +80,21 @@ enum macdrv_window_messages ...@@ -80,6 +80,21 @@ enum macdrv_window_messages
WM_MACDRV_SET_WIN_REGION = 0x80001000, WM_MACDRV_SET_WIN_REGION = 0x80001000,
}; };
struct macdrv_thread_data
{
macdrv_event_queue queue;
};
extern DWORD thread_data_tls_index DECLSPEC_HIDDEN;
extern struct macdrv_thread_data *macdrv_init_thread_data(void) DECLSPEC_HIDDEN;
static inline struct macdrv_thread_data *macdrv_thread_data(void)
{
return TlsGetValue(thread_data_tls_index);
}
/* macdrv private window data */ /* macdrv private window data */
struct macdrv_win_data struct macdrv_win_data
{ {
......
...@@ -161,8 +161,9 @@ struct macdrv_window_state { ...@@ -161,8 +161,9 @@ struct macdrv_window_state {
}; };
extern macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf, extern macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf,
CGRect frame) DECLSPEC_HIDDEN; CGRect frame, macdrv_event_queue queue) DECLSPEC_HIDDEN;
extern void macdrv_destroy_cocoa_window(macdrv_window w) DECLSPEC_HIDDEN; extern void macdrv_destroy_cocoa_window(macdrv_window w) DECLSPEC_HIDDEN;
extern void* macdrv_get_window_hwnd(macdrv_window w) DECLSPEC_HIDDEN;
extern void macdrv_set_cocoa_window_features(macdrv_window w, extern void macdrv_set_cocoa_window_features(macdrv_window w,
const struct macdrv_window_features* wf) DECLSPEC_HIDDEN; const struct macdrv_window_features* wf) DECLSPEC_HIDDEN;
extern void macdrv_set_cocoa_window_state(macdrv_window w, extern void macdrv_set_cocoa_window_state(macdrv_window w,
......
...@@ -22,32 +22,119 @@ ...@@ -22,32 +22,119 @@
#include "config.h" #include "config.h"
#include "macdrv.h" #include "macdrv.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(macdrv); WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
DWORD thread_data_tls_index = TLS_OUT_OF_INDEXES;
/***********************************************************************
* process_attach
*/
static BOOL process_attach(void)
{
if ((thread_data_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) return FALSE;
macdrv_err_on = ERR_ON(macdrv);
if (macdrv_start_cocoa_app())
{
ERR("Failed to start Cocoa app main loop\n");
return FALSE;
}
return TRUE;
}
/***********************************************************************
* thread_detach
*/
static void thread_detach(void)
{
struct macdrv_thread_data *data = macdrv_thread_data();
if (data)
{
macdrv_destroy_event_queue(data->queue);
HeapFree(GetProcessHeap(), 0, data);
}
}
/*********************************************************************** /***********************************************************************
* MACDRV initialisation routine * set_queue_display_fd
*
* Store the event queue fd into the message queue
*/ */
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) static void set_queue_display_fd(int fd)
{
HANDLE handle;
int ret;
if (wine_server_fd_to_handle(fd, GENERIC_READ | SYNCHRONIZE, 0, &handle))
{
MESSAGE("macdrv: Can't allocate handle for event queue fd\n");
ExitProcess(1);
}
SERVER_START_REQ(set_queue_fd)
{
req->handle = wine_server_obj_handle(handle);
ret = wine_server_call(req);
}
SERVER_END_REQ;
if (ret)
{
MESSAGE("macdrv: Can't store handle for event queue fd\n");
ExitProcess(1);
}
CloseHandle(handle);
}
/***********************************************************************
* macdrv_init_thread_data
*/
struct macdrv_thread_data *macdrv_init_thread_data(void)
{
struct macdrv_thread_data *data = macdrv_thread_data();
if (data) return data;
if (!(data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data))))
{
ERR("could not create data\n");
ExitProcess(1);
}
if (!(data->queue = macdrv_create_event_queue()))
{
ERR("macdrv: Can't create event queue.\n");
ExitProcess(1);
}
set_queue_display_fd(macdrv_get_event_queue_fd(data->queue));
TlsSetValue(thread_data_tls_index, data);
return data;
}
/***********************************************************************
* DllMain
*/
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
{ {
BOOL ret = TRUE; BOOL ret = TRUE;
switch(reason) switch(reason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
macdrv_err_on = ERR_ON(macdrv); ret = process_attach();
if (macdrv_start_cocoa_app())
{
ERR("Failed to start Cocoa app main loop\n");
ret = FALSE;
}
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
/* do thread detach */ thread_detach();
break;
case DLL_PROCESS_DETACH:
/* do detach */
break; break;
} }
return ret; return ret;
......
...@@ -478,6 +478,7 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE ...@@ -478,6 +478,7 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE
*/ */
static void create_cocoa_window(struct macdrv_win_data *data) static void create_cocoa_window(struct macdrv_win_data *data)
{ {
struct macdrv_thread_data *thread_data = macdrv_init_thread_data();
WCHAR text[1024]; WCHAR text[1024];
struct macdrv_window_features wf; struct macdrv_window_features wf;
CGRect frame; CGRect frame;
...@@ -510,7 +511,7 @@ static void create_cocoa_window(struct macdrv_win_data *data) ...@@ -510,7 +511,7 @@ static void create_cocoa_window(struct macdrv_win_data *data)
TRACE("creating %p window %s whole %s client %s\n", data->hwnd, wine_dbgstr_rect(&data->window_rect), TRACE("creating %p window %s whole %s client %s\n", data->hwnd, wine_dbgstr_rect(&data->window_rect),
wine_dbgstr_rect(&data->whole_rect), wine_dbgstr_rect(&data->client_rect)); wine_dbgstr_rect(&data->whole_rect), wine_dbgstr_rect(&data->client_rect));
data->cocoa_window = macdrv_create_cocoa_window(&wf, frame); data->cocoa_window = macdrv_create_cocoa_window(&wf, frame, thread_data->queue);
if (!data->cocoa_window) goto done; if (!data->cocoa_window) goto done;
set_cocoa_window_properties(data); set_cocoa_window_properties(data);
...@@ -565,7 +566,10 @@ static struct macdrv_win_data *macdrv_create_win_data(HWND hwnd, const RECT *win ...@@ -565,7 +566,10 @@ static struct macdrv_win_data *macdrv_create_win_data(HWND hwnd, const RECT *win
if (GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId()) return NULL; if (GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId()) return NULL;
if (!(parent = GetAncestor(hwnd, GA_PARENT))) /* desktop */ if (!(parent = GetAncestor(hwnd, GA_PARENT))) /* desktop */
{
macdrv_init_thread_data();
return NULL; return NULL;
}
/* don't create win data for HWND_MESSAGE windows */ /* don't create win data for HWND_MESSAGE windows */
if (parent != GetDesktopWindow() && !GetAncestor(parent, GA_PARENT)) return NULL; if (parent != GetDesktopWindow() && !GetAncestor(parent, GA_PARENT)) return NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment