winemac: Convert main thread to Cocoa main loop on process attach.
This commit is contained in:
parent
daf0fd75e6
commit
35319684d3
|
@ -10,6 +10,7 @@ C_SRCS = \
|
||||||
|
|
||||||
OBJC_SRCS = \
|
OBJC_SRCS = \
|
||||||
cocoa_app.m \
|
cocoa_app.m \
|
||||||
cocoa_display.m
|
cocoa_display.m \
|
||||||
|
cocoa_main.m
|
||||||
|
|
||||||
@MAKE_DLL_RULES@
|
@MAKE_DLL_RULES@
|
||||||
|
|
|
@ -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
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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 */
|
/* display */
|
||||||
extern int macdrv_get_displays(struct macdrv_display** displays, int* count) DECLSPEC_HIDDEN;
|
extern int macdrv_get_displays(struct macdrv_display** displays, int* count) DECLSPEC_HIDDEN;
|
||||||
extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDEN;
|
extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright 1998 Patrik Stridvall
|
* Copyright 1998 Patrik Stridvall
|
||||||
* Copyright 2000 Alexandre Julliard
|
* Copyright 2000 Alexandre Julliard
|
||||||
|
* Copyright 2011, 2012, 2013 Ken Thomases for CodeWeavers Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -20,11 +21,10 @@
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#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
|
* MACDRV initialisation routine
|
||||||
|
@ -36,7 +36,11 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
|
||||||
switch(reason)
|
switch(reason)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
/* Do 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 */
|
/* do thread detach */
|
||||||
|
|
Loading…
Reference in New Issue