mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 05:21:29 +00:00
winemac: Convert main thread to Cocoa main loop on process attach.
This commit is contained in:
parent
daf0fd75e6
commit
35319684d3
4 changed files with 138 additions and 7 deletions
|
@ -10,6 +10,7 @@ C_SRCS = \
|
|||
|
||||
OBJC_SRCS = \
|
||||
cocoa_app.m \
|
||||
cocoa_display.m
|
||||
cocoa_display.m \
|
||||
cocoa_main.m
|
||||
|
||||
@MAKE_DLL_RULES@
|
||||
|
|
122
dlls/winemac.drv/cocoa_main.m
Normal file
122
dlls/winemac.drv/cocoa_main.m
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* MACDRV Cocoa initialization code
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
#include "macdrv_cocoa.h"
|
||||
#import "cocoa_app.h"
|
||||
|
||||
|
||||
/* Condition values for an NSConditionLock. Used to signal between run_cocoa_app
|
||||
and macdrv_start_cocoa_app so the latter knows when the former is running
|
||||
the application event loop. */
|
||||
enum {
|
||||
COCOA_APP_NOT_RUNNING,
|
||||
COCOA_APP_RUNNING,
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* run_cocoa_app
|
||||
*
|
||||
* Transforms the main thread from merely idling in its run loop to
|
||||
* being a Cocoa application running its event loop.
|
||||
*
|
||||
* This will be the perform callback of a custom run loop source that
|
||||
* will be scheduled in the main thread's run loop from a secondary
|
||||
* thread by macdrv_start_cocoa_app. This function communicates that
|
||||
* it has successfully started the application by changing the condition
|
||||
* of a shared NSConditionLock, passed in via the info parameter.
|
||||
*
|
||||
* This function never returns. It's the new permanent home of the
|
||||
* main thread.
|
||||
*/
|
||||
static void run_cocoa_app(void* info)
|
||||
{
|
||||
NSConditionLock* lock = info;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[WineApplication sharedApplication];
|
||||
[NSApp setDelegate:(WineApplication*)NSApp];
|
||||
|
||||
/* Retain the lock while we're using it, so macdrv_start_cocoa_app()
|
||||
doesn't deallocate it in the middle of us unlocking it. */
|
||||
[lock retain];
|
||||
[lock lock];
|
||||
[lock unlockWithCondition:COCOA_APP_RUNNING];
|
||||
[lock release];
|
||||
|
||||
[pool release];
|
||||
|
||||
/* Never returns */
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_start_cocoa_app
|
||||
*
|
||||
* Tells the main thread to transform itself into a Cocoa application.
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*/
|
||||
int macdrv_start_cocoa_app(void)
|
||||
{
|
||||
int ret = -1;
|
||||
CFRunLoopSourceRef source;
|
||||
NSConditionLock* lock;
|
||||
NSDate* timeLimit;
|
||||
CFRunLoopSourceContext source_context = { 0 };
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
/* Make sure Cocoa is in multi-threading mode by detaching a
|
||||
do-nothing thread. */
|
||||
[NSThread detachNewThreadSelector:@selector(self)
|
||||
toTarget:[NSThread class]
|
||||
withObject:nil];
|
||||
|
||||
lock = [[NSConditionLock alloc] initWithCondition:COCOA_APP_NOT_RUNNING];
|
||||
timeLimit = [NSDate dateWithTimeIntervalSinceNow:5];
|
||||
|
||||
source_context.info = lock;
|
||||
source_context.perform = run_cocoa_app;
|
||||
source = CFRunLoopSourceCreate(NULL, 0, &source_context);
|
||||
|
||||
if (source && lock && timeLimit)
|
||||
{
|
||||
CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes);
|
||||
CFRunLoopSourceSignal(source);
|
||||
CFRunLoopWakeUp(CFRunLoopGetMain());
|
||||
|
||||
if ([lock lockWhenCondition:COCOA_APP_RUNNING beforeDate:timeLimit])
|
||||
{
|
||||
[lock unlock];
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (source)
|
||||
CFRelease(source);
|
||||
[lock release];
|
||||
[pool release];
|
||||
return ret;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* MACDRV Cocoa interface declarations
|
||||
*
|
||||
* Copyright 2011, 2012 Ken Thomases for CodeWeavers Inc.
|
||||
* 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
|
||||
|
@ -104,6 +104,10 @@
|
|||
};
|
||||
|
||||
|
||||
/* main */
|
||||
extern int macdrv_start_cocoa_app(void) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* display */
|
||||
extern int macdrv_get_displays(struct macdrv_display** displays, int* count) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright 1998 Patrik Stridvall
|
||||
* Copyright 2000 Alexandre Julliard
|
||||
* 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
|
||||
|
@ -20,11 +21,10 @@
|
|||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "macdrv.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(macdrv);
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
|
||||
/***********************************************************************
|
||||
* MACDRV initialisation routine
|
||||
|
@ -36,7 +36,11 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
|||
switch(reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
/* Do attach */
|
||||
if (macdrv_start_cocoa_app())
|
||||
{
|
||||
ERR("Failed to start Cocoa app main loop\n");
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
/* do thread detach */
|
||||
|
|
Loading…
Reference in a new issue