winemac: Implement an IME that uses the OS X input methods.
Developed with Aric Stewart.
This commit is contained in:
parent
72be23270e
commit
192b8dbf9d
|
@ -1,6 +1,6 @@
|
|||
MODULE = winemac.drv
|
||||
IMPORTS = uuid user32 gdi32 advapi32
|
||||
DELAYIMPORTS = ole32 shell32
|
||||
DELAYIMPORTS = ole32 shell32 imm32
|
||||
EXTRALIBS = -framework AppKit -framework Carbon -framework Security -framework OpenGL -framework IOKit
|
||||
|
||||
C_SRCS = \
|
||||
|
@ -10,6 +10,7 @@ C_SRCS = \
|
|||
event.c \
|
||||
gdi.c \
|
||||
image.c \
|
||||
ime.c \
|
||||
keyboard.c \
|
||||
macdrv_main.c \
|
||||
mouse.c \
|
||||
|
|
|
@ -52,6 +52,8 @@ @interface WineApplicationController : NSObject <NSApplicationDelegate>
|
|||
|
||||
CGEventSourceKeyboardType keyboardType;
|
||||
NSEvent* lastFlagsChanged;
|
||||
BOOL inputSourceIsInputMethod;
|
||||
BOOL inputSourceIsInputMethodValid;
|
||||
|
||||
CGFloat primaryScreenHeight;
|
||||
BOOL primaryScreenHeightValid;
|
||||
|
|
|
@ -81,6 +81,7 @@ @interface WineApplicationController ()
|
|||
@property (copy, nonatomic) NSArray* cursorFrames;
|
||||
@property (retain, nonatomic) NSTimer* cursorTimer;
|
||||
@property (retain, nonatomic) NSImage* applicationIcon;
|
||||
@property (readonly, nonatomic) BOOL inputSourceIsInputMethod;
|
||||
|
||||
- (void) setupObservations;
|
||||
- (void) applicationDidBecomeActive:(NSNotification *)notification;
|
||||
|
@ -96,6 +97,19 @@ @implementation WineApplicationController
|
|||
@synthesize orderedWineWindows, applicationIcon;
|
||||
@synthesize cursorFrames, cursorTimer;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [WineApplicationController class])
|
||||
{
|
||||
NSDictionary* defaults = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"", @"NSQuotedKeystrokeBinding",
|
||||
@"", @"NSRepeatCountBinding",
|
||||
[NSNumber numberWithBool:NO], @"ApplePressAndHoldEnabled",
|
||||
nil];
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
||||
}
|
||||
}
|
||||
|
||||
+ (WineApplicationController*) sharedController
|
||||
{
|
||||
static WineApplicationController* sharedController;
|
||||
|
@ -323,6 +337,8 @@ - (void) keyboardSelectionDidChange
|
|||
{
|
||||
TISInputSourceRef inputSource;
|
||||
|
||||
inputSourceIsInputMethodValid = FALSE;
|
||||
|
||||
inputSource = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
if (inputSource)
|
||||
{
|
||||
|
@ -1227,6 +1243,25 @@ - (void) setupObservations
|
|||
[NSTextInputContext self];
|
||||
}
|
||||
|
||||
- (BOOL) inputSourceIsInputMethod
|
||||
{
|
||||
if (!inputSourceIsInputMethodValid)
|
||||
{
|
||||
TISInputSourceRef inputSource = TISCopyCurrentKeyboardInputSource();
|
||||
if (inputSource)
|
||||
{
|
||||
CFStringRef type = TISGetInputSourceProperty(inputSource, kTISPropertyInputSourceType);
|
||||
inputSourceIsInputMethod = !CFEqual(type, kTISTypeKeyboardLayout);
|
||||
CFRelease(inputSource);
|
||||
}
|
||||
else
|
||||
inputSourceIsInputMethod = FALSE;
|
||||
inputSourceIsInputMethodValid = TRUE;
|
||||
}
|
||||
|
||||
return inputSourceIsInputMethod;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ---------- NSApplicationDelegate methods ----------
|
||||
|
@ -1646,3 +1681,17 @@ void macdrv_quit_reply(int reply)
|
|||
[NSApp replyToApplicationShouldTerminate:reply];
|
||||
});
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_using_input_method
|
||||
*/
|
||||
int macdrv_using_input_method(void)
|
||||
{
|
||||
__block BOOL ret;
|
||||
|
||||
OnMainThread(^{
|
||||
ret = [[WineApplicationController sharedController] inputSourceIsInputMethod];
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -453,6 +453,10 @@ void macdrv_release_event(macdrv_event *event)
|
|||
|
||||
switch (event->type)
|
||||
{
|
||||
case IM_SET_TEXT:
|
||||
if (event->im_set_text.text)
|
||||
CFRelease(event->im_set_text.text);
|
||||
break;
|
||||
case KEYBOARD_CHANGED:
|
||||
CFRelease(event->keyboard_changed.uchr);
|
||||
break;
|
||||
|
|
|
@ -54,6 +54,9 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
|
|||
|
||||
NSTimer* liveResizeDisplayTimer;
|
||||
|
||||
void* imeData;
|
||||
BOOL commandDone;
|
||||
|
||||
BOOL causing_becomeKeyWindow;
|
||||
BOOL ignore_windowMiniaturize;
|
||||
BOOL ignore_windowDeminiaturize;
|
||||
|
|
|
@ -118,10 +118,13 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
|
|||
}
|
||||
|
||||
|
||||
@interface WineContentView : NSView
|
||||
@interface WineContentView : NSView <NSTextInputClient>
|
||||
{
|
||||
NSMutableArray* glContexts;
|
||||
NSMutableArray* pendingGlContexts;
|
||||
|
||||
NSMutableAttributedString* markedText;
|
||||
NSRange markedTextSelection;
|
||||
}
|
||||
|
||||
- (void) addGLContext:(WineOpenGLContext*)context;
|
||||
|
@ -154,6 +157,9 @@ @interface WineWindow ()
|
|||
|
||||
@property (readwrite, nonatomic) NSInteger levelWhenActive;
|
||||
|
||||
@property (assign, nonatomic) void* imeData;
|
||||
@property (nonatomic) BOOL commandDone;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -161,6 +167,7 @@ @implementation WineContentView
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[markedText release];
|
||||
[glContexts release];
|
||||
[pendingGlContexts release];
|
||||
[super dealloc];
|
||||
|
@ -289,6 +296,147 @@ - (BOOL) preservesContentDuringLiveResize
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return [[self window] contentView] == self;
|
||||
}
|
||||
|
||||
- (void) completeText:(NSString*)text
|
||||
{
|
||||
macdrv_event* event;
|
||||
WineWindow* window = (WineWindow*)[self window];
|
||||
|
||||
event = macdrv_create_event(IM_SET_TEXT, window);
|
||||
event->im_set_text.data = [window imeData];
|
||||
event->im_set_text.text = (CFStringRef)[text copy];
|
||||
event->im_set_text.complete = TRUE;
|
||||
|
||||
[[window queue] postEvent:event];
|
||||
|
||||
macdrv_release_event(event);
|
||||
|
||||
[markedText deleteCharactersInRange:NSMakeRange(0, [markedText length])];
|
||||
markedTextSelection = NSMakeRange(0, 0);
|
||||
[[self inputContext] discardMarkedText];
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------- NSTextInputClient methods ----------
|
||||
*/
|
||||
- (NSTextInputContext*) inputContext
|
||||
{
|
||||
if (!markedText)
|
||||
markedText = [[NSMutableAttributedString alloc] init];
|
||||
return [super inputContext];
|
||||
}
|
||||
|
||||
- (void) insertText:(id)string replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
if ([string isKindOfClass:[NSAttributedString class]])
|
||||
string = [string string];
|
||||
|
||||
if ([string isKindOfClass:[NSString class]])
|
||||
[self completeText:string];
|
||||
}
|
||||
|
||||
- (void) doCommandBySelector:(SEL)aSelector
|
||||
{
|
||||
[(WineWindow*)[self window] setCommandDone:TRUE];
|
||||
}
|
||||
|
||||
- (void) setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
if ([string isKindOfClass:[NSAttributedString class]])
|
||||
string = [string string];
|
||||
|
||||
if ([string isKindOfClass:[NSString class]])
|
||||
{
|
||||
macdrv_event* event;
|
||||
WineWindow* window = (WineWindow*)[self window];
|
||||
|
||||
if (replacementRange.location == NSNotFound)
|
||||
replacementRange = NSMakeRange(0, [markedText length]);
|
||||
|
||||
[markedText replaceCharactersInRange:replacementRange withString:string];
|
||||
markedTextSelection = selectedRange;
|
||||
markedTextSelection.location += replacementRange.location;
|
||||
|
||||
event = macdrv_create_event(IM_SET_TEXT, window);
|
||||
event->im_set_text.data = [window imeData];
|
||||
event->im_set_text.text = (CFStringRef)[[markedText string] copy];
|
||||
event->im_set_text.complete = FALSE;
|
||||
|
||||
[[window queue] postEvent:event];
|
||||
|
||||
macdrv_release_event(event);
|
||||
|
||||
event = macdrv_create_event(IM_SET_CURSOR_POS, window);
|
||||
event->im_set_cursor_pos.data = [window imeData];
|
||||
event->im_set_cursor_pos.pos = markedTextSelection.location;
|
||||
|
||||
[[window queue] postEvent:event];
|
||||
|
||||
macdrv_release_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) unmarkText
|
||||
{
|
||||
[self completeText:nil];
|
||||
}
|
||||
|
||||
- (NSRange) selectedRange
|
||||
{
|
||||
return markedTextSelection;
|
||||
}
|
||||
|
||||
- (NSRange) markedRange
|
||||
{
|
||||
NSRange range = NSMakeRange(0, [markedText length]);
|
||||
if (!range.length)
|
||||
range.location = NSNotFound;
|
||||
return range;
|
||||
}
|
||||
|
||||
- (BOOL) hasMarkedText
|
||||
{
|
||||
return [markedText length] > 0;
|
||||
}
|
||||
|
||||
- (NSAttributedString*) attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
if (aRange.location >= [markedText length])
|
||||
return nil;
|
||||
|
||||
aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));
|
||||
if (actualRange)
|
||||
*actualRange = aRange;
|
||||
return [markedText attributedSubstringFromRange:aRange];
|
||||
}
|
||||
|
||||
- (NSArray*) validAttributesForMarkedText
|
||||
{
|
||||
return [NSArray array];
|
||||
}
|
||||
|
||||
- (NSRect) firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||
{
|
||||
aRange = NSIntersectionRange(aRange, NSMakeRange(0, [markedText length]));
|
||||
if (actualRange)
|
||||
*actualRange = aRange;
|
||||
return NSMakeRect(100, 100, aRange.length ? 1 : 0, 12);
|
||||
}
|
||||
|
||||
- (NSUInteger) characterIndexForPoint:(NSPoint)aPoint
|
||||
{
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (NSInteger) windowLevel
|
||||
{
|
||||
return [[self window] level];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -300,6 +448,7 @@ @implementation WineWindow
|
|||
@synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
|
||||
@synthesize usePerPixelAlpha;
|
||||
@synthesize levelWhenActive;
|
||||
@synthesize imeData, commandDone;
|
||||
|
||||
+ (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)wf
|
||||
windowFrame:(NSRect)window_frame
|
||||
|
@ -356,6 +505,7 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
|
|||
[contentView addTrackingArea:trackingArea];
|
||||
|
||||
[window setContentView:contentView];
|
||||
[window setInitialFirstResponder:contentView];
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@ -1844,3 +1994,51 @@ uint32_t macdrv_window_background_color(void)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_send_text_input_event
|
||||
*/
|
||||
int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc, void* data)
|
||||
{
|
||||
__block BOOL ret;
|
||||
|
||||
OnMainThread(^{
|
||||
WineWindow* window = (WineWindow*)[NSApp keyWindow];
|
||||
if (![window isKindOfClass:[WineWindow class]])
|
||||
{
|
||||
window = (WineWindow*)[NSApp mainWindow];
|
||||
if (![window isKindOfClass:[WineWindow class]] && [[NSApp orderedWineWindows] count])
|
||||
{
|
||||
window = [[NSApp orderedWineWindows] objectAtIndex:0];
|
||||
if (![window isKindOfClass:[WineWindow class]])
|
||||
window = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (window)
|
||||
{
|
||||
NSUInteger localFlags = flags;
|
||||
CGEventRef c;
|
||||
NSEvent* event;
|
||||
|
||||
window.imeData = data;
|
||||
fix_device_modifiers_by_generic(&localFlags);
|
||||
|
||||
// An NSEvent created with +keyEventWithType:... is internally marked
|
||||
// as synthetic and doesn't get sent through input methods. But one
|
||||
// created from a CGEvent doesn't have that problem.
|
||||
c = CGEventCreateKeyboardEvent(NULL, keyc, pressed);
|
||||
CGEventSetFlags(c, localFlags);
|
||||
CGEventSetIntegerValueField(c, kCGKeyboardEventAutorepeat, repeat);
|
||||
event = [NSEvent eventWithCGEvent:c];
|
||||
CFRelease(c);
|
||||
|
||||
window.commandDone = FALSE;
|
||||
ret = [[[window contentView] inputContext] handleEvent:event] && !window.commandDone;
|
||||
}
|
||||
else
|
||||
ret = FALSE;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ static const char *dbgstr_event(int type)
|
|||
"APP_DEACTIVATED",
|
||||
"APP_QUIT_REQUESTED",
|
||||
"DISPLAYS_CHANGED",
|
||||
"IM_SET_CURSOR_POS",
|
||||
"IM_SET_TEXT",
|
||||
"KEY_PRESS",
|
||||
"KEY_RELEASE",
|
||||
"KEYBOARD_CHANGED",
|
||||
|
@ -90,6 +92,8 @@ static macdrv_event_mask get_event_mask(DWORD mask)
|
|||
event_mask |= event_mask_for_type(APP_DEACTIVATED);
|
||||
event_mask |= event_mask_for_type(APP_QUIT_REQUESTED);
|
||||
event_mask |= event_mask_for_type(DISPLAYS_CHANGED);
|
||||
event_mask |= event_mask_for_type(IM_SET_CURSOR_POS);
|
||||
event_mask |= event_mask_for_type(IM_SET_TEXT);
|
||||
event_mask |= event_mask_for_type(STATUS_ITEM_CLICKED);
|
||||
event_mask |= event_mask_for_type(WINDOW_CLOSE_REQUESTED);
|
||||
event_mask |= event_mask_for_type(WINDOW_DID_MINIMIZE);
|
||||
|
@ -173,6 +177,12 @@ void macdrv_handle_event(const macdrv_event *event)
|
|||
case DISPLAYS_CHANGED:
|
||||
macdrv_displays_changed(event);
|
||||
break;
|
||||
case IM_SET_CURSOR_POS:
|
||||
macdrv_im_set_cursor_pos(event);
|
||||
break;
|
||||
case IM_SET_TEXT:
|
||||
macdrv_im_set_text(event);
|
||||
break;
|
||||
case KEY_PRESS:
|
||||
case KEY_RELEASE:
|
||||
macdrv_key_event(hwnd, event);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -888,6 +888,53 @@ static BOOL match_keyboard_layout(HKL hkl)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* macdrv_process_text_input
|
||||
*/
|
||||
BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state, void *himc)
|
||||
{
|
||||
struct macdrv_thread_data *thread_data = macdrv_thread_data();
|
||||
unsigned int flags;
|
||||
int keyc;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE("vkey 0x%04x scan 0x%04x repeat %u himc %p\n", vkey, scan, repeat, himc);
|
||||
|
||||
flags = thread_data->last_modifiers;
|
||||
if (key_state[VK_SHIFT] & 0x80)
|
||||
flags |= NX_SHIFTMASK;
|
||||
else
|
||||
flags &= ~(NX_SHIFTMASK | NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK);
|
||||
if (key_state[VK_CAPITAL] & 0x01)
|
||||
flags |= NX_ALPHASHIFTMASK;
|
||||
else
|
||||
flags &= ~NX_ALPHASHIFTMASK;
|
||||
if (key_state[VK_CONTROL] & 0x80)
|
||||
flags |= NX_CONTROLMASK;
|
||||
else
|
||||
flags &= ~(NX_CONTROLMASK | NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK);
|
||||
if (key_state[VK_MENU] & 0x80)
|
||||
flags |= NX_COMMANDMASK;
|
||||
else
|
||||
flags &= ~(NX_COMMANDMASK | NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK);
|
||||
|
||||
/* Find the Mac keycode corresponding to the scan code */
|
||||
for (keyc = 0; keyc < sizeof(thread_data->keyc2vkey)/sizeof(thread_data->keyc2vkey[0]); keyc++)
|
||||
if (thread_data->keyc2vkey[keyc] == vkey) break;
|
||||
|
||||
if (keyc >= sizeof(thread_data->keyc2vkey)/sizeof(thread_data->keyc2vkey[0]))
|
||||
goto done;
|
||||
|
||||
TRACE("flags 0x%08x keyc 0x%04x\n", flags, keyc);
|
||||
|
||||
ret = macdrv_send_text_input_event(((scan & 0x8000) == 0), flags, repeat, keyc, himc);
|
||||
|
||||
done:
|
||||
TRACE(" -> %s\n", ret ? "TRUE" : "FALSE");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ActivateKeyboardLayout (MACDRV.@)
|
||||
*/
|
||||
|
|
|
@ -64,6 +64,8 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
|||
CGRectGetMaxX(cgrect), CGRectGetMaxY(cgrect));
|
||||
}
|
||||
|
||||
extern const char* debugstr_cf(CFTypeRef t) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Mac GDI driver
|
||||
|
@ -188,4 +190,17 @@ extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP
|
|||
|
||||
extern void macdrv_status_item_clicked(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* Mac IME driver
|
||||
*/
|
||||
|
||||
extern void IME_RegisterClasses(HINSTANCE hImeInst) DECLSPEC_HIDDEN;
|
||||
|
||||
extern BOOL macdrv_process_text_input(UINT vkey, UINT scan, UINT repeat, const BYTE *key_state,
|
||||
void *himc) DECLSPEC_HIDDEN;
|
||||
|
||||
extern void macdrv_im_set_cursor_pos(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_im_set_text(const macdrv_event *event) DECLSPEC_HIDDEN;
|
||||
|
||||
#endif /* __WINE_MACDRV_H */
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
extern void macdrv_beep(void) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_set_application_icon(CFArrayRef images) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_quit_reply(int reply) DECLSPEC_HIDDEN;
|
||||
extern int macdrv_using_input_method(void) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* cursor */
|
||||
|
@ -156,6 +157,8 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
APP_DEACTIVATED,
|
||||
APP_QUIT_REQUESTED,
|
||||
DISPLAYS_CHANGED,
|
||||
IM_SET_CURSOR_POS,
|
||||
IM_SET_TEXT,
|
||||
KEY_PRESS,
|
||||
KEY_RELEASE,
|
||||
KEYBOARD_CHANGED,
|
||||
|
@ -195,6 +198,15 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
struct {
|
||||
int activating;
|
||||
} displays_changed;
|
||||
struct {
|
||||
void *data;
|
||||
unsigned int pos;
|
||||
} im_set_cursor_pos;
|
||||
struct {
|
||||
void *data;
|
||||
CFStringRef text; /* new text or NULL if just completing existing text */
|
||||
unsigned int complete; /* is completing text? */
|
||||
} im_set_text;
|
||||
struct {
|
||||
CGKeyCode keycode;
|
||||
CGEventFlags modifiers;
|
||||
|
@ -348,6 +360,8 @@ extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat
|
|||
extern void macdrv_add_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN;
|
||||
extern void macdrv_remove_view_opengl_context(macdrv_view v, macdrv_opengl_context c) DECLSPEC_HIDDEN;
|
||||
extern uint32_t macdrv_window_background_color(void) DECLSPEC_HIDDEN;
|
||||
extern int macdrv_send_text_input_event(int pressed, unsigned int flags, int repeat, int keyc,
|
||||
void* data) DECLSPEC_HIDDEN;
|
||||
|
||||
|
||||
/* keyboard */
|
||||
|
|
|
@ -206,6 +206,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
|||
switch(reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
IME_RegisterClasses(hinst);
|
||||
ret = process_attach();
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
|
|
|
@ -49,3 +49,21 @@
|
|||
|
||||
# System tray
|
||||
@ cdecl wine_notify_icon(long ptr)
|
||||
|
||||
# IME
|
||||
@ stdcall ImeConfigure(long long long ptr)
|
||||
@ stdcall ImeConversionList(long wstr ptr long long)
|
||||
@ stdcall ImeDestroy(long)
|
||||
@ stdcall ImeEnumRegisterWord(ptr wstr long wstr ptr)
|
||||
@ stdcall ImeEscape(long long ptr)
|
||||
@ stdcall ImeGetImeMenuItems(long long long ptr ptr long)
|
||||
@ stdcall ImeGetRegisterWordStyle(wstr long wstr)
|
||||
@ stdcall ImeInquire(ptr wstr wstr)
|
||||
@ stdcall ImeProcessKey(long long long ptr)
|
||||
@ stdcall ImeRegisterWord(wstr long wstr)
|
||||
@ stdcall ImeSelect(long long)
|
||||
@ stdcall ImeSetActiveContext(long long)
|
||||
@ stdcall ImeSetCompositionString(long long ptr long ptr long)
|
||||
@ stdcall ImeToAsciiEx(long long ptr ptr long long)
|
||||
@ stdcall ImeUnregisterWord(wstr long wstr)
|
||||
@ stdcall NotifyIME(long long long long)
|
||||
|
|
Loading…
Reference in New Issue