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
77de5768
Commit
77de5768
authored
Feb 03, 2013
by
Ken Thomases
Committed by
Alexandre Julliard
Feb 05, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemac: Generate KEY_PRESS/RELEASE events from Cocoa key events.
parent
d0e1a025
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
259 additions
and
1 deletion
+259
-1
cocoa_app.h
dlls/winemac.drv/cocoa_app.h
+4
-0
cocoa_app.m
dlls/winemac.drv/cocoa_app.m
+20
-1
cocoa_window.h
dlls/winemac.drv/cocoa_window.h
+2
-0
cocoa_window.m
dlls/winemac.drv/cocoa_window.m
+158
-0
event.c
dlls/winemac.drv/event.c
+10
-0
keyboard.c
dlls/winemac.drv/keyboard.c
+57
-0
macdrv.h
dlls/winemac.drv/macdrv.h
+1
-0
macdrv_cocoa.h
dlls/winemac.drv/macdrv_cocoa.h
+7
-0
No files found.
dlls/winemac.drv/cocoa_app.h
View file @
77de5768
...
...
@@ -42,9 +42,11 @@
unsigned
long
windowFocusSerial
;
CGEventSourceKeyboardType
keyboardType
;
NSEvent
*
lastFlagsChanged
;
}
@property
(
nonatomic
)
CGEventSourceKeyboardType
keyboardType
;
@property
(
readonly
,
copy
,
nonatomic
)
NSEvent
*
lastFlagsChanged
;
-
(
void
)
transformProcessToForeground
;
...
...
@@ -56,6 +58,8 @@
-
(
void
)
windowGotFocus
:(
WineWindow
*
)
window
;
-
(
void
)
keyboardSelectionDidChange
;
@end
void
OnMainThread
(
dispatch_block_t
block
);
...
...
dlls/winemac.drv/cocoa_app.m
View file @
77de5768
...
...
@@ -28,9 +28,16 @@
int
macdrv_err_on
;
@interface
WineApplication
()
@property
(
readwrite
,
copy
,
nonatomic
)
NSEvent
*
lastFlagsChanged
;
@end
@implementation
WineApplication
@synthesize
keyboardType
;
@synthesize
keyboardType
,
lastFlagsChanged
;
-
(
id
)
init
{
...
...
@@ -220,6 +227,18 @@ int macdrv_err_on;
/*
* ---------- NSApplication method overrides ----------
*/
-
(
void
)
sendEvent
:
(
NSEvent
*
)
anEvent
{
if
([
anEvent
type
]
==
NSFlagsChanged
)
self
.
lastFlagsChanged
=
anEvent
;
[
super
sendEvent
:
anEvent
];
}
/*
* ---------- NSApplicationDelegate methods ----------
*/
-
(
void
)
applicationDidResignActive
:
(
NSNotification
*
)
notification
...
...
dlls/winemac.drv/cocoa_window.h
View file @
77de5768
...
...
@@ -46,6 +46,8 @@
BOOL
usePerPixelAlpha
;
NSUInteger
lastModifierFlags
;
BOOL
causing_becomeKeyWindow
;
BOOL
ignore_windowMiniaturize
;
BOOL
ignore_windowDeminiaturize
;
...
...
dlls/winemac.drv/cocoa_window.m
View file @
77de5768
...
...
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#import <Carbon/Carbon.h>
#import "cocoa_window.h"
#include "macdrv_cocoa.h"
...
...
@@ -25,6 +27,12 @@
#import "cocoa_event.h"
/* Additional Mac virtual keycode, to complement those in Carbon's <HIToolbox/Events.h>. */
enum
{
kVK_RightCommand
=
0x36
,
/* Invented for Wine; was unused */
};
static
NSUInteger
style_mask_for_features
(
const
struct
macdrv_window_features
*
wf
)
{
NSUInteger
style_mask
;
...
...
@@ -55,6 +63,49 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
}
/* We rely on the supposedly device-dependent modifier flags to distinguish the
keys on the left side of the keyboard from those on the right. Some event
sources don't set those device-depdendent flags. If we see a device-independent
flag for a modifier without either corresponding device-dependent flag, assume
the left one. */
static
inline
void
fix_device_modifiers_by_generic
(
NSUInteger
*
modifiers
)
{
if
((
*
modifiers
&
(
NX_COMMANDMASK
|
NX_DEVICELCMDKEYMASK
|
NX_DEVICERCMDKEYMASK
))
==
NX_COMMANDMASK
)
*
modifiers
|=
NX_DEVICELCMDKEYMASK
;
if
((
*
modifiers
&
(
NX_SHIFTMASK
|
NX_DEVICELSHIFTKEYMASK
|
NX_DEVICERSHIFTKEYMASK
))
==
NX_SHIFTMASK
)
*
modifiers
|=
NX_DEVICELSHIFTKEYMASK
;
if
((
*
modifiers
&
(
NX_CONTROLMASK
|
NX_DEVICELCTLKEYMASK
|
NX_DEVICERCTLKEYMASK
))
==
NX_CONTROLMASK
)
*
modifiers
|=
NX_DEVICELCTLKEYMASK
;
if
((
*
modifiers
&
(
NX_ALTERNATEMASK
|
NX_DEVICELALTKEYMASK
|
NX_DEVICERALTKEYMASK
))
==
NX_ALTERNATEMASK
)
*
modifiers
|=
NX_DEVICELALTKEYMASK
;
}
/* As we manipulate individual bits of a modifier mask, we can end up with
inconsistent sets of flags. In particular, we might set or clear one of the
left/right-specific bits, but not the corresponding non-side-specific bit.
Fix that. If either side-specific bit is set, set the non-side-specific bit,
otherwise clear it. */
static
inline
void
fix_generic_modifiers_by_device
(
NSUInteger
*
modifiers
)
{
if
(
*
modifiers
&
(
NX_DEVICELCMDKEYMASK
|
NX_DEVICERCMDKEYMASK
))
*
modifiers
|=
NX_COMMANDMASK
;
else
*
modifiers
&=
~
NX_COMMANDMASK
;
if
(
*
modifiers
&
(
NX_DEVICELSHIFTKEYMASK
|
NX_DEVICERSHIFTKEYMASK
))
*
modifiers
|=
NX_SHIFTMASK
;
else
*
modifiers
&=
~
NX_SHIFTMASK
;
if
(
*
modifiers
&
(
NX_DEVICELCTLKEYMASK
|
NX_DEVICERCTLKEYMASK
))
*
modifiers
|=
NX_CONTROLMASK
;
else
*
modifiers
&=
~
NX_CONTROLMASK
;
if
(
*
modifiers
&
(
NX_DEVICELALTKEYMASK
|
NX_DEVICERALTKEYMASK
))
*
modifiers
|=
NX_ALTERNATEMASK
;
else
*
modifiers
&=
~
NX_ALTERNATEMASK
;
}
@interface
WineContentView
:
NSView
@end
...
...
@@ -493,6 +544,44 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
[
self
windowDidResize
:
nil
];
}
-
(
void
)
postKey
:
(
uint16_t
)
keyCode
pressed
:
(
BOOL
)
pressed
modifiers
:
(
NSUInteger
)
modifiers
event
:
(
NSEvent
*
)
theEvent
{
macdrv_event
event
;
CGEventRef
cgevent
;
WineApplication
*
app
=
(
WineApplication
*
)
NSApp
;
event
.
type
=
pressed
?
KEY_PRESS
:
KEY_RELEASE
;
event
.
window
=
(
macdrv_window
)[
self
retain
];
event
.
key
.
keycode
=
keyCode
;
event
.
key
.
modifiers
=
modifiers
;
event
.
key
.
time_ms
=
[
app
ticksForEventTime
:[
theEvent
timestamp
]];
if
((
cgevent
=
[
theEvent
CGEvent
]))
{
CGEventSourceKeyboardType
keyboardType
=
CGEventGetIntegerValueField
(
cgevent
,
kCGKeyboardEventKeyboardType
);
if
(
keyboardType
!=
app
.
keyboardType
)
{
app
.
keyboardType
=
keyboardType
;
[
app
keyboardSelectionDidChange
];
}
}
[
queue
postEvent
:
&
event
];
}
-
(
void
)
postKeyEvent
:
(
NSEvent
*
)
theEvent
{
[
self
flagsChanged
:
theEvent
];
[
self
postKey
:[
theEvent
keyCode
]
pressed
:[
theEvent
type
]
==
NSKeyDown
modifiers
:
[
theEvent
modifierFlags
]
event
:
theEvent
];
}
/*
* ---------- NSWindow method overrides ----------
...
...
@@ -556,12 +645,81 @@ static BOOL frame_intersects_screens(NSRect frame, NSArray* screens)
-
(
void
)
rightMouseUp
:
(
NSEvent
*
)
theEvent
{
[
self
mouseUp
:
theEvent
];
}
-
(
void
)
otherMouseUp
:
(
NSEvent
*
)
theEvent
{
[
self
mouseUp
:
theEvent
];
}
-
(
void
)
keyDown
:
(
NSEvent
*
)
theEvent
{
[
self
postKeyEvent
:
theEvent
];
}
-
(
void
)
keyUp
:
(
NSEvent
*
)
theEvent
{
[
self
postKeyEvent
:
theEvent
];
}
-
(
void
)
flagsChanged
:
(
NSEvent
*
)
theEvent
{
static
const
struct
{
NSUInteger
mask
;
uint16_t
keycode
;
}
modifiers
[]
=
{
{
NX_ALPHASHIFTMASK
,
kVK_CapsLock
},
{
NX_DEVICELSHIFTKEYMASK
,
kVK_Shift
},
{
NX_DEVICERSHIFTKEYMASK
,
kVK_RightShift
},
{
NX_DEVICELCTLKEYMASK
,
kVK_Control
},
{
NX_DEVICERCTLKEYMASK
,
kVK_RightControl
},
{
NX_DEVICELALTKEYMASK
,
kVK_Option
},
{
NX_DEVICERALTKEYMASK
,
kVK_RightOption
},
{
NX_DEVICELCMDKEYMASK
,
kVK_Command
},
{
NX_DEVICERCMDKEYMASK
,
kVK_RightCommand
},
};
NSUInteger
modifierFlags
=
[
theEvent
modifierFlags
];
NSUInteger
changed
;
int
i
,
last_changed
;
fix_device_modifiers_by_generic
(
&
modifierFlags
);
changed
=
modifierFlags
^
lastModifierFlags
;
last_changed
=
-
1
;
for
(
i
=
0
;
i
<
sizeof
(
modifiers
)
/
sizeof
(
modifiers
[
0
]);
i
++
)
if
(
changed
&
modifiers
[
i
].
mask
)
last_changed
=
i
;
for
(
i
=
0
;
i
<=
last_changed
;
i
++
)
{
if
(
changed
&
modifiers
[
i
].
mask
)
{
BOOL
pressed
=
(
modifierFlags
&
modifiers
[
i
].
mask
)
!=
0
;
if
(
i
==
last_changed
)
lastModifierFlags
=
modifierFlags
;
else
{
lastModifierFlags
^=
modifiers
[
i
].
mask
;
fix_generic_modifiers_by_device
(
&
lastModifierFlags
);
}
// Caps lock generates one event for each press-release action.
// We need to simulate a pair of events for each actual event.
if
(
modifiers
[
i
].
mask
==
NX_ALPHASHIFTMASK
)
{
[
self
postKey
:
modifiers
[
i
].
keycode
pressed
:
TRUE
modifiers
:
lastModifierFlags
event
:
(
NSEvent
*
)
theEvent
];
pressed
=
FALSE
;
}
[
self
postKey
:
modifiers
[
i
].
keycode
pressed
:
pressed
modifiers
:
lastModifierFlags
event
:
(
NSEvent
*
)
theEvent
];
}
}
}
/*
* ---------- NSWindowDelegate methods ----------
*/
-
(
void
)
windowDidBecomeKey
:
(
NSNotification
*
)
notification
{
NSEvent
*
event
=
[
NSApp
lastFlagsChanged
];
if
(
event
)
[
self
flagsChanged
:
event
];
if
(
causing_becomeKeyWindow
)
return
;
[
NSApp
windowGotFocus
:
self
];
...
...
dlls/winemac.drv/event.c
View file @
77de5768
...
...
@@ -33,6 +33,8 @@ static const char *dbgstr_event(int type)
{
static
const
char
*
const
event_names
[]
=
{
"APP_DEACTIVATED"
,
"KEY_PRESS"
,
"KEY_RELEASE"
,
"KEYBOARD_CHANGED"
,
"MOUSE_BUTTON"
,
"WINDOW_CLOSE_REQUESTED"
,
...
...
@@ -58,7 +60,11 @@ static macdrv_event_mask get_event_mask(DWORD mask)
if
((
mask
&
QS_ALLINPUT
)
==
QS_ALLINPUT
)
return
-
1
;
if
(
mask
&
QS_KEY
)
{
event_mask
|=
event_mask_for_type
(
KEY_PRESS
);
event_mask
|=
event_mask_for_type
(
KEY_RELEASE
);
event_mask
|=
event_mask_for_type
(
KEYBOARD_CHANGED
);
}
if
(
mask
&
QS_MOUSEBUTTON
)
event_mask
|=
event_mask_for_type
(
MOUSE_BUTTON
);
...
...
@@ -98,6 +104,10 @@ void macdrv_handle_event(macdrv_event *event)
case
APP_DEACTIVATED
:
macdrv_app_deactivated
();
break
;
case
KEY_PRESS
:
case
KEY_RELEASE
:
macdrv_key_event
(
hwnd
,
event
);
break
;
case
KEYBOARD_CHANGED
:
macdrv_keyboard_changed
(
event
);
break
;
...
...
dlls/winemac.drv/keyboard.c
View file @
77de5768
...
...
@@ -31,6 +31,7 @@
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
keyboard
);
WINE_DECLARE_DEBUG_CHANNEL
(
key
);
/* Carbon-style modifier mask definitions from <Carbon/HIToolbox/Events.h>. */
...
...
@@ -664,6 +665,62 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data)
/***********************************************************************
* macdrv_send_keyboard_input
*/
static
void
macdrv_send_keyboard_input
(
HWND
hwnd
,
WORD
vkey
,
WORD
scan
,
DWORD
flags
,
DWORD
time
)
{
INPUT
input
;
TRACE_
(
key
)(
"hwnd %p vkey=%04x scan=%04x flags=%04x
\n
"
,
hwnd
,
vkey
,
scan
,
flags
);
input
.
type
=
INPUT_KEYBOARD
;
input
.
ki
.
wVk
=
vkey
;
input
.
ki
.
wScan
=
scan
;
input
.
ki
.
dwFlags
=
flags
;
input
.
ki
.
time
=
time
;
input
.
ki
.
dwExtraInfo
=
0
;
__wine_send_input
(
hwnd
,
&
input
);
}
/***********************************************************************
* macdrv_key_event
*
* Handler for KEY_PRESS and KEY_RELEASE events.
*/
void
macdrv_key_event
(
HWND
hwnd
,
const
macdrv_event
*
event
)
{
struct
macdrv_thread_data
*
thread_data
=
macdrv_thread_data
();
WORD
vkey
,
scan
;
DWORD
flags
;
TRACE_
(
key
)(
"win %p/%p key %s keycode %hu modifiers 0x%08llx
\n
"
,
hwnd
,
event
->
window
,
(
event
->
type
==
KEY_PRESS
?
"press"
:
"release"
),
event
->
key
.
keycode
,
event
->
key
.
modifiers
);
if
(
event
->
key
.
keycode
<
sizeof
(
thread_data
->
keyc2vkey
)
/
sizeof
(
thread_data
->
keyc2vkey
[
0
]))
{
vkey
=
thread_data
->
keyc2vkey
[
event
->
key
.
keycode
];
scan
=
thread_data
->
keyc2scan
[
event
->
key
.
keycode
];
}
else
vkey
=
scan
=
0
;
TRACE_
(
key
)(
"keycode %hu converted to vkey 0x%X scan 0x%02x
\n
"
,
event
->
key
.
keycode
,
vkey
,
scan
);
if
(
!
vkey
)
return
;
flags
=
0
;
if
(
event
->
type
==
KEY_RELEASE
)
flags
|=
KEYEVENTF_KEYUP
;
if
(
scan
&
0x100
)
flags
|=
KEYEVENTF_EXTENDEDKEY
;
macdrv_send_keyboard_input
(
hwnd
,
vkey
,
scan
&
0xff
,
flags
,
event
->
key
.
time_ms
);
}
/***********************************************************************
* macdrv_keyboard_changed
*
* Handler for KEYBOARD_CHANGED events.
...
...
dlls/winemac.drv/macdrv.h
View file @
77de5768
...
...
@@ -135,5 +135,6 @@ extern void macdrv_mouse_button(HWND hwnd, const macdrv_event *event) DECLSPEC_H
extern
void
macdrv_compute_keyboard_layout
(
struct
macdrv_thread_data
*
thread_data
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_keyboard_changed
(
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
extern
void
macdrv_key_event
(
HWND
hwnd
,
const
macdrv_event
*
event
)
DECLSPEC_HIDDEN
;
#endif
/* __WINE_MACDRV_H */
dlls/winemac.drv/macdrv_cocoa.h
View file @
77de5768
...
...
@@ -125,6 +125,8 @@ extern void macdrv_free_displays(struct macdrv_display* displays) DECLSPEC_HIDDE
/* event */
enum
{
APP_DEACTIVATED
,
KEY_PRESS
,
KEY_RELEASE
,
KEYBOARD_CHANGED
,
MOUSE_BUTTON
,
WINDOW_CLOSE_REQUESTED
,
...
...
@@ -143,6 +145,11 @@ typedef struct macdrv_event {
macdrv_window
window
;
union
{
struct
{
CGKeyCode
keycode
;
CGEventFlags
modifiers
;
unsigned
long
time_ms
;
}
key
;
struct
{
CFDataRef
uchr
;
CGEventSourceKeyboardType
keyboard_type
;
int
iso_keyboard
;
...
...
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