Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
69e631e0
Commit
69e631e0
authored
Mar 10, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Mar 11, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Add support for "query" events which wait for synchronous responses.
parent
bf824ed3
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
313 additions
and
19 deletions
+313
-19
cocoa_app.h
dlls/winemac.drv/cocoa_app.h
+6
-1
cocoa_app.m
dlls/winemac.drv/cocoa_app.m
+77
-9
cocoa_clipboard.m
dlls/winemac.drv/cocoa_clipboard.m
+1
-0
cocoa_event.h
dlls/winemac.drv/cocoa_event.h
+7
-0
cocoa_event.m
dlls/winemac.drv/cocoa_event.m
+161
-6
cocoa_opengl.m
dlls/winemac.drv/cocoa_opengl.m
+1
-1
event.c
dlls/winemac.drv/event.c
+32
-0
macdrv.h
dlls/winemac.drv/macdrv.h
+2
-0
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+25
-1
macdrv_main.c
dlls/winemac.drv/macdrv_main.c
+1
-1
No files found.
dlls/winemac.drv/cocoa_app.h
View file @
69e631e0
...
...
@@ -32,6 +32,10 @@
@interface
WineApplication
:
NSApplication
<
NSApplicationDelegate
>
{
CFRunLoopSourceRef
requestSource
;
NSMutableArray
*
requests
;
dispatch_queue_t
requestsManipQueue
;
NSMutableArray
*
eventQueues
;
NSLock
*
eventQueuesLock
;
...
...
@@ -83,6 +87,8 @@
-
(
void
)
windowGotFocus
:(
WineWindow
*
)
window
;
-
(
BOOL
)
waitUntilQueryDone
:(
int
*
)
done
timeout
:(
NSDate
*
)
timeout
;
-
(
void
)
keyboardSelectionDidChange
;
-
(
void
)
flipRect
:(
NSRect
*
)
rect
;
...
...
@@ -93,7 +99,6 @@
@end
void
OnMainThread
(
dispatch_block_t
block
);
void
OnMainThreadAsync
(
dispatch_block_t
block
);
void
LogError
(
const
char
*
func
,
NSString
*
format
,
...);
...
...
dlls/winemac.drv/cocoa_app.m
View file @
69e631e0
...
...
@@ -26,6 +26,9 @@
#import "cocoa_window.h"
static
NSString
*
const
WineAppWaitQueryResponseMode
=
@"WineAppWaitQueryResponseMode"
;
int
macdrv_err_on
;
...
...
@@ -56,6 +59,8 @@ int macdrv_err_on;
@property
(
copy
,
nonatomic
)
NSArray
*
cursorFrames
;
@property
(
retain
,
nonatomic
)
NSTimer
*
cursorTimer
;
static
void
PerformRequest
(
void
*
info
);
@end
...
...
@@ -70,6 +75,20 @@ int macdrv_err_on;
self
=
[
super
init
];
if
(
self
!=
nil
)
{
CFRunLoopSourceContext
context
=
{
0
};
context
.
perform
=
PerformRequest
;
requestSource
=
CFRunLoopSourceCreate
(
NULL
,
0
,
&
context
);
if
(
!
requestSource
)
{
[
self
release
];
return
nil
;
}
CFRunLoopAddSource
(
CFRunLoopGetMain
(),
requestSource
,
kCFRunLoopCommonModes
);
CFRunLoopAddSource
(
CFRunLoopGetMain
(),
requestSource
,
(
CFStringRef
)
WineAppWaitQueryResponseMode
);
requests
=
[[
NSMutableArray
alloc
]
init
];
requestsManipQueue
=
dispatch_queue_create
(
"org.winehq.WineAppRequestManipQueue"
,
NULL
);
eventQueues
=
[[
NSMutableArray
alloc
]
init
];
eventQueuesLock
=
[[
NSLock
alloc
]
init
];
...
...
@@ -80,8 +99,8 @@ int macdrv_err_on;
warpRecords
=
[[
NSMutableArray
alloc
]
init
];
if
(
!
eventQueues
||
!
eventQueuesLock
||
!
keyWindows
||
!
orderedWineWindows
||
!
originalDisplayModes
||
!
warpRecords
)
if
(
!
requests
||
!
requestsManipQueue
||
!
eventQueues
||
!
eventQueuesLock
||
!
keyWindows
||
!
orderedWineWindows
||
!
originalDisplayModes
||
!
warpRecords
)
{
[
self
release
];
return
nil
;
...
...
@@ -100,6 +119,13 @@ int macdrv_err_on;
[
keyWindows
release
];
[
eventQueues
release
];
[
eventQueuesLock
release
];
if
(
requestsManipQueue
)
dispatch_release
(
requestsManipQueue
);
[
requests
release
];
if
(
requestSource
)
{
CFRunLoopSourceInvalidate
(
requestSource
);
CFRelease
(
requestSource
);
}
[
super
dealloc
];
}
...
...
@@ -146,6 +172,18 @@ int macdrv_err_on;
}
}
-
(
BOOL
)
waitUntilQueryDone
:
(
int
*
)
done
timeout
:
(
NSDate
*
)
timeout
{
PerformRequest
(
NULL
);
do
{
[[
NSRunLoop
currentRunLoop
]
runMode
:
WineAppWaitQueryResponseMode
beforeDate
:
timeout
];
}
while
(
!*
done
&&
[
timeout
timeIntervalSinceNow
]
>=
0
);
return
*
done
;
}
-
(
BOOL
)
registerEventQueue
:
(
WineEventQueue
*
)
queue
{
[
eventQueuesLock
lock
];
...
...
@@ -1102,16 +1140,36 @@ int macdrv_err_on;
}];
}
@end
/***********************************************************************
*
OnMainThread
*
PerformRequest
*
* Run a block on the main thread synchronously.
* Run-loop-source perform callback. Pull request blocks from the
* array of queued requests and invoke them.
*/
void
OnMainThread
(
dispatch_block_t
block
)
static
void
PerformRequest
(
void
*
info
)
{
dispatch_sync
(
dispatch_get_main_queue
(),
block
);
WineApplication
*
app
=
(
WineApplication
*
)
NSApp
;
for
(;;)
{
__block
dispatch_block_t
block
;
dispatch_sync
(
app
->
requestsManipQueue
,
^
{
if
([
app
->
requests
count
])
{
block
=
(
dispatch_block_t
)[[
app
->
requests
objectAtIndex
:
0
]
retain
];
[
app
->
requests
removeObjectAtIndex
:
0
];
}
else
block
=
nil
;
});
if
(
!
block
)
break
;
block
();
[
block
release
];
}
}
/***********************************************************************
...
...
@@ -1121,9 +1179,19 @@ void OnMainThread(dispatch_block_t block)
*/
void
OnMainThreadAsync
(
dispatch_block_t
block
)
{
dispatch_async
(
dispatch_get_main_queue
(),
block
);
WineApplication
*
app
=
(
WineApplication
*
)
NSApp
;
block
=
[
block
copy
];
dispatch_sync
(
app
->
requestsManipQueue
,
^
{
[
app
->
requests
addObject
:
block
];
});
[
block
release
];
CFRunLoopSourceSignal
(
app
->
requestSource
);
CFRunLoopWakeUp
(
CFRunLoopGetMain
());
}
@end
/***********************************************************************
* LogError
*/
...
...
dlls/winemac.drv/cocoa_clipboard.m
View file @
69e631e0
...
...
@@ -20,6 +20,7 @@
#include "macdrv_cocoa.h"
#import "cocoa_app.h"
#import "cocoa_event.h"
static
int
owned_change_count
=
-
1
;
...
...
dlls/winemac.drv/cocoa_event.h
View file @
69e631e0
...
...
@@ -28,9 +28,16 @@
NSLock
*
eventsLock
;
int
fds
[
2
];
/* Pipe signaling when there are events queued. */
int
kq
;
/* kqueue for waiting in OnMainThread(). */
macdrv_event_handler
event_handler
;
}
-
(
void
)
postEvent
:
(
const
macdrv_event
*
)
inEvent
;
-
(
void
)
discardEventsMatchingMask
:(
macdrv_event_mask
)
mask
forWindow
:(
NSWindow
*
)
window
;
-
(
BOOL
)
query
:(
macdrv_query
*
)
query
timeout
:(
NSTimeInterval
)
timeout
;
@end
void
OnMainThread
(
dispatch_block_t
block
);
dlls/winemac.drv/cocoa_event.m
View file @
69e631e0
...
...
@@ -29,6 +29,9 @@
#import "cocoa_window.h"
static
NSString
*
const
WineEventQueueThreadDictionaryKey
=
@"WineEventQueueThreadDictionaryKey"
;
@interface
MacDrvEvent
:
NSObject
{
@public
...
...
@@ -58,11 +61,24 @@
-
(
id
)
init
{
[
self
doesNotRecognizeSelector
:
_cmd
];
[
self
release
];
return
nil
;
}
-
(
id
)
initWithEventHandler
:
(
macdrv_event_handler
)
handler
{
NSParameterAssert
(
handler
!=
nil
);
self
=
[
super
init
];
if
(
self
!=
nil
)
{
fds
[
0
]
=
fds
[
1
]
=
-
1
;
struct
kevent
kev
;
int
rc
;
fds
[
0
]
=
fds
[
1
]
=
kq
=
-
1
;
event_handler
=
handler
;
events
=
[[
NSMutableArray
alloc
]
init
];
eventsLock
=
[[
NSLock
alloc
]
init
];
...
...
@@ -81,6 +97,24 @@
[
self
release
];
return
nil
;
}
kq
=
kqueue
();
if
(
kq
<
0
)
{
[
self
release
];
return
nil
;
}
EV_SET
(
&
kev
,
fds
[
0
],
EVFILT_READ
,
EV_ADD
|
EV_ENABLE
,
0
,
0
,
0
);
do
{
rc
=
kevent
(
kq
,
&
kev
,
1
,
NULL
,
0
,
NULL
);
}
while
(
rc
==
-
1
&&
errno
==
EINTR
);
if
(
rc
==
-
1
)
{
[
self
release
];
return
nil
;
}
}
return
self
;
}
...
...
@@ -90,6 +124,7 @@
[
events
release
];
[
eventsLock
release
];
if
(
kq
!=
-
1
)
close
(
kq
);
if
(
fds
[
0
]
!=
-
1
)
close
(
fds
[
0
]);
if
(
fds
[
1
]
!=
-
1
)
close
(
fds
[
1
]);
...
...
@@ -217,6 +252,69 @@
[
eventsLock
unlock
];
}
-
(
BOOL
)
query
:
(
macdrv_query
*
)
query
timeout
:
(
NSTimeInterval
)
timeout
{
macdrv_event
event
;
NSDate
*
timeoutDate
=
[
NSDate
dateWithTimeIntervalSinceNow
:
timeout
];
BOOL
timedout
;
event
.
type
=
QUERY_EVENT
;
event
.
window
=
(
macdrv_window
)[(
WineWindow
*
)
query
->
window
retain
];
event
.
query_event
.
query
=
macdrv_retain_query
(
query
);
query
->
done
=
FALSE
;
[
self
postEvent
:
&
event
];
timedout
=
!
[
NSApp
waitUntilQueryDone
:
&
query
->
done
timeout
:
timeoutDate
];
return
!
timedout
&&
query
->
status
;
}
/***********************************************************************
* OnMainThread
*
* Run a block on the main thread synchronously.
*/
void
OnMainThread
(
dispatch_block_t
block
)
{
NSAutoreleasePool
*
pool
=
[[
NSAutoreleasePool
alloc
]
init
];
NSMutableDictionary
*
threadDict
=
[[
NSThread
currentThread
]
threadDictionary
];
WineEventQueue
*
queue
=
[
threadDict
objectForKey
:
WineEventQueueThreadDictionaryKey
];
__block
BOOL
finished
;
if
(
!
queue
)
{
/* Fall back to synchronous dispatch without handling query events. */
dispatch_sync
(
dispatch_get_main_queue
(),
block
);
[
pool
release
];
return
;
}
finished
=
FALSE
;
OnMainThreadAsync
(
^
{
block
();
finished
=
TRUE
;
[
queue
signalEventAvailable
];
});
while
(
!
finished
)
{
MacDrvEvent
*
macDrvEvent
;
struct
kevent
kev
;
while
(
!
finished
&&
(
macDrvEvent
=
[
queue
getEventMatchingMask
:
event_mask_for_type
(
QUERY_EVENT
)]))
{
queue
->
event_handler
(
&
macDrvEvent
->
event
);
macdrv_cleanup_event
(
&
macDrvEvent
->
event
);
}
if
(
!
finished
)
kevent
(
queue
->
kq
,
NULL
,
0
,
&
kev
,
1
,
NULL
);
}
[
pool
release
];
}
/***********************************************************************
* macdrv_create_event_queue
...
...
@@ -224,16 +322,23 @@
* Register this thread with the application on the main thread, and set
* up an event queue on which it can deliver events to this thread.
*/
macdrv_event_queue
macdrv_create_event_queue
(
void
)
macdrv_event_queue
macdrv_create_event_queue
(
macdrv_event_handler
handler
)
{
NSAutoreleasePool
*
pool
=
[[
NSAutoreleasePool
alloc
]
init
];
NSMutableDictionary
*
threadDict
=
[[
NSThread
currentThread
]
threadDictionary
];
WineEventQueue
*
queue
=
[[
WineEventQueue
alloc
]
init
];
if
(
queue
&&
!
[
NSApp
registerEventQueue
:
queue
])
WineEventQueue
*
queue
=
[
threadDict
objectForKey
:
WineEventQueueThreadDictionaryKey
];
if
(
!
queue
)
{
queue
=
[[[
WineEventQueue
alloc
]
initWithEventHandler
:
handler
]
autorelease
];
if
(
queue
)
{
[
queue
release
];
if
([
NSApp
registerEventQueue
:
queue
])
[
threadDict
setObject
:
queue
forKey
:
WineEventQueueThreadDictionaryKey
];
else
queue
=
nil
;
}
}
[
pool
release
];
return
(
macdrv_event_queue
)
queue
;
...
...
@@ -249,9 +354,10 @@ void macdrv_destroy_event_queue(macdrv_event_queue queue)
{
NSAutoreleasePool
*
pool
=
[[
NSAutoreleasePool
alloc
]
init
];
WineEventQueue
*
q
=
(
WineEventQueue
*
)
queue
;
NSMutableDictionary
*
threadDict
=
[[
NSThread
currentThread
]
threadDictionary
];
[
NSApp
unregisterEventQueue
:
q
];
[
q
release
];
[
threadDict
removeObjectForKey
:
WineEventQueueThreadDictionaryKey
];
[
pool
release
];
}
...
...
@@ -308,6 +414,9 @@ void macdrv_cleanup_event(macdrv_event *event)
case
KEYBOARD_CHANGED
:
CFRelease
(
event
->
keyboard_changed
.
uchr
);
break
;
case
QUERY_EVENT
:
macdrv_release_query
(
event
->
query_event
.
query
);
break
;
case
WINDOW_GOT_FOCUS
:
[(
NSMutableSet
*
)
event
->
window_got_focus
.
tried_windows
release
];
break
;
...
...
@@ -318,4 +427,50 @@ void macdrv_cleanup_event(macdrv_event *event)
[
pool
release
];
}
/***********************************************************************
* macdrv_create_query
*/
macdrv_query
*
macdrv_create_query
(
void
)
{
macdrv_query
*
query
;
query
=
calloc
(
1
,
sizeof
(
*
query
));
query
->
refs
=
1
;
return
query
;
}
/***********************************************************************
* macdrv_retain_query
*/
macdrv_query
*
macdrv_retain_query
(
macdrv_query
*
query
)
{
OSAtomicIncrement32Barrier
(
&
query
->
refs
);
return
query
;
}
/***********************************************************************
* macdrv_release_query
*/
void
macdrv_release_query
(
macdrv_query
*
query
)
{
if
(
OSAtomicDecrement32Barrier
(
&
query
->
refs
)
<=
0
)
{
[(
WineWindow
*
)
query
->
window
release
];
free
(
query
);
}
}
/***********************************************************************
* macdrv_set_query_done
*/
void
macdrv_set_query_done
(
macdrv_query
*
query
)
{
macdrv_retain_query
(
query
);
OnMainThreadAsync
(
^
{
query
->
done
=
TRUE
;
macdrv_release_query
(
query
);
});
}
@end
dlls/winemac.drv/cocoa_opengl.m
View file @
69e631e0
...
...
@@ -21,7 +21,7 @@
#import "cocoa_opengl.h"
#include "macdrv_cocoa.h"
#include "cocoa_
app
.h"
#include "cocoa_
event
.h"
@interface
WineOpenGLContext
()
...
...
dlls/winemac.drv/event.c
View file @
69e631e0
...
...
@@ -41,6 +41,7 @@ static const char *dbgstr_event(int type)
"MOUSE_MOVED"
,
"MOUSE_MOVED_ABSOLUTE"
,
"MOUSE_SCROLL"
,
"QUERY_EVENT"
,
"WINDOW_CLOSE_REQUESTED"
,
"WINDOW_DID_MINIMIZE"
,
"WINDOW_DID_UNMINIMIZE"
,
...
...
@@ -94,11 +95,39 @@ static macdrv_event_mask get_event_mask(DWORD mask)
event_mask
|=
event_mask_for_type
(
WINDOW_LOST_FOCUS
);
}
if
(
mask
&
QS_SENDMESSAGE
)
{
event_mask
|=
event_mask_for_type
(
QUERY_EVENT
);
}
return
event_mask
;
}
/***********************************************************************
* macdrv_query_event
*
* Handler for QUERY_EVENT queries.
*/
static
void
macdrv_query_event
(
HWND
hwnd
,
macdrv_event
*
event
)
{
BOOL
success
=
FALSE
;
macdrv_query
*
query
=
event
->
query_event
.
query
;
switch
(
query
->
type
)
{
default:
FIXME
(
"unrecognized query type %d
\n
"
,
query
->
type
);
break
;
}
TRACE
(
"success %d
\n
"
,
success
);
query
->
status
=
success
;
macdrv_set_query_done
(
query
);
}
/***********************************************************************
* macdrv_handle_event
*/
void
macdrv_handle_event
(
macdrv_event
*
event
)
...
...
@@ -138,6 +167,9 @@ void macdrv_handle_event(macdrv_event *event)
case
MOUSE_SCROLL
:
macdrv_mouse_scroll
(
hwnd
,
event
);
break
;
case
QUERY_EVENT
:
macdrv_query_event
(
hwnd
,
event
);
break
;
case
WINDOW_CLOSE_REQUESTED
:
macdrv_window_close_requested
(
hwnd
);
break
;
...
...
dlls/winemac.drv/macdrv.h
View file @
69e631e0
...
...
@@ -138,6 +138,8 @@ extern struct window_surface *create_surface(macdrv_window window, const RECT *r
extern
void
set_window_surface
(
macdrv_window
window
,
struct
window_surface
*
window_surface
)
DECLSPEC_HIDDEN
;
extern
void
set_surface_use_alpha
(
struct
window_surface
*
window_surface
,
BOOL
use_alpha
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_handle_event
(
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_window_close_requested
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_window_frame_changed
(
HWND
hwnd
,
CGRect
frame
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_window_got_focus
(
HWND
hwnd
,
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
...
...
dlls/winemac.drv/macdrv_cocoa.h
View file @
69e631e0
...
...
@@ -104,6 +104,7 @@ typedef struct macdrv_opaque_event_queue* macdrv_event_queue;
typedef
struct
macdrv_opaque_view
*
macdrv_view
;
typedef
struct
macdrv_opaque_opengl_context
*
macdrv_opengl_context
;
struct
macdrv_event
;
struct
macdrv_query
;
struct
macdrv_display
{
CGDirectDisplayID
displayID
;
...
...
@@ -145,6 +146,7 @@ enum {
MOUSE_MOVED
,
MOUSE_MOVED_ABSOLUTE
,
MOUSE_SCROLL
,
QUERY_EVENT
,
WINDOW_CLOSE_REQUESTED
,
WINDOW_DID_MINIMIZE
,
WINDOW_DID_UNMINIMIZE
,
...
...
@@ -193,6 +195,9 @@ typedef struct macdrv_event {
unsigned
long
time_ms
;
}
mouse_scroll
;
struct
{
struct
macdrv_query
*
query
;
}
query_event
;
struct
{
CGRect
frame
;
}
window_frame_changed
;
struct
{
...
...
@@ -202,12 +207,26 @@ typedef struct macdrv_event {
};
}
macdrv_event
;
enum
{
NUM_QUERY_TYPES
};
typedef
struct
macdrv_query
{
int
refs
;
int
type
;
macdrv_window
window
;
int
status
;
int
done
;
}
macdrv_query
;
static
inline
macdrv_event_mask
event_mask_for_type
(
int
type
)
{
return
((
macdrv_event_mask
)
1
<<
type
);
}
extern
macdrv_event_queue
macdrv_create_event_queue
(
void
)
DECLSPEC_HIDDEN
;
typedef
void
(
*
macdrv_event_handler
)(
macdrv_event
*
event
);
extern
macdrv_event_queue
macdrv_create_event_queue
(
macdrv_event_handler
handler
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_destroy_event_queue
(
macdrv_event_queue
queue
)
DECLSPEC_HIDDEN
;
extern
int
macdrv_get_event_queue_fd
(
macdrv_event_queue
queue
)
DECLSPEC_HIDDEN
;
...
...
@@ -215,6 +234,11 @@ extern int macdrv_get_event_from_queue(macdrv_event_queue queue,
macdrv_event_mask
mask
,
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_cleanup_event
(
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
macdrv_query
*
macdrv_create_query
(
void
)
DECLSPEC_HIDDEN
;
extern
macdrv_query
*
macdrv_retain_query
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_release_query
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_set_query_done
(
macdrv_query
*
query
)
DECLSPEC_HIDDEN
;
/* window */
struct
macdrv_window_features
{
...
...
dlls/winemac.drv/macdrv_main.c
View file @
69e631e0
...
...
@@ -157,7 +157,7 @@ struct macdrv_thread_data *macdrv_init_thread_data(void)
ExitProcess
(
1
);
}
if
(
!
(
data
->
queue
=
macdrv_create_event_queue
()))
if
(
!
(
data
->
queue
=
macdrv_create_event_queue
(
macdrv_handle_event
)))
{
ERR
(
"macdrv: Can't create event queue.
\n
"
);
ExitProcess
(
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment