forked from Mirrors/wine-wine
winemac: Implement GetKeyboardLayoutList.
parent
85e105bd37
commit
fecaab9cfd
|
@ -2446,3 +2446,52 @@ void macdrv_set_mouse_capture_window(macdrv_window window)
|
||||||
[[WineApplicationController sharedController] setMouseCaptureWindow:w];
|
[[WineApplicationController sharedController] setMouseCaptureWindow:w];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CFStringRef macdrv_input_source_input_key = CFSTR("input");
|
||||||
|
const CFStringRef macdrv_input_source_type_key = CFSTR("type");
|
||||||
|
const CFStringRef macdrv_input_source_lang_key = CFSTR("lang");
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* macdrv_create_input_source_list
|
||||||
|
*/
|
||||||
|
CFArrayRef macdrv_create_input_source_list(void)
|
||||||
|
{
|
||||||
|
CFMutableArrayRef ret = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
|
||||||
|
|
||||||
|
OnMainThread(^{
|
||||||
|
CFArrayRef input_list;
|
||||||
|
CFDictionaryRef filter_dict;
|
||||||
|
const void *filter_keys[2] = { kTISPropertyInputSourceCategory, kTISPropertyInputSourceIsSelectCapable };
|
||||||
|
const void *filter_values[2] = { kTISCategoryKeyboardInputSource, kCFBooleanTrue };
|
||||||
|
int i;
|
||||||
|
|
||||||
|
filter_dict = CFDictionaryCreate(NULL, filter_keys, filter_values, sizeof(filter_keys)/sizeof(filter_keys[0]),
|
||||||
|
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||||
|
input_list = TISCreateInputSourceList(filter_dict, false);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(input_list); i++)
|
||||||
|
{
|
||||||
|
TISInputSourceRef input = (TISInputSourceRef)CFArrayGetValueAtIndex(input_list, i);
|
||||||
|
CFArrayRef source_langs = TISGetInputSourceProperty(input, kTISPropertyInputSourceLanguages);
|
||||||
|
CFDictionaryRef entry;
|
||||||
|
const void *input_keys[3] = { macdrv_input_source_input_key,
|
||||||
|
macdrv_input_source_type_key,
|
||||||
|
macdrv_input_source_lang_key };
|
||||||
|
const void *input_values[3];
|
||||||
|
|
||||||
|
input_values[0] = input;
|
||||||
|
input_values[1] = TISGetInputSourceProperty(input, kTISPropertyInputSourceType);
|
||||||
|
input_values[2] = CFArrayGetValueAtIndex(source_langs, 0);
|
||||||
|
|
||||||
|
entry = CFDictionaryCreate(NULL, input_keys, input_values, sizeof(input_keys) / sizeof(input_keys[0]),
|
||||||
|
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||||
|
|
||||||
|
CFArrayAppendValue(ret, entry);
|
||||||
|
CFRelease(entry);
|
||||||
|
}
|
||||||
|
CFRelease(input_list);
|
||||||
|
CFRelease(filter_dict);
|
||||||
|
});
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -176,6 +176,7 @@ enum {
|
||||||
kVK_UpArrow = 0x7E,
|
kVK_UpArrow = 0x7E,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const CFStringRef kTISTypeKeyboardLayout;
|
||||||
|
|
||||||
/* Indexed by Mac virtual keycode values defined above. */
|
/* Indexed by Mac virtual keycode values defined above. */
|
||||||
static const struct {
|
static const struct {
|
||||||
|
@ -428,6 +429,90 @@ static int strip_apple_private_chars(LPWSTR bufW, int len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct list layout_list = LIST_INIT( layout_list );
|
||||||
|
struct layout
|
||||||
|
{
|
||||||
|
struct list entry;
|
||||||
|
HKL hkl;
|
||||||
|
TISInputSourceRef input_source;
|
||||||
|
};
|
||||||
|
|
||||||
|
static CRITICAL_SECTION layout_list_section;
|
||||||
|
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
|
{
|
||||||
|
0, 0, &layout_list_section,
|
||||||
|
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||||
|
0, 0, { (DWORD_PTR)(__FILE__ ": layout_list_section") }
|
||||||
|
};
|
||||||
|
static CRITICAL_SECTION layout_list_section = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static DWORD get_lcid(CFStringRef lang)
|
||||||
|
{
|
||||||
|
CFRange range;
|
||||||
|
WCHAR str[10];
|
||||||
|
|
||||||
|
range.location = 0;
|
||||||
|
range.length = min(CFStringGetLength(lang), sizeof(str) / sizeof(str[0]) - 1);
|
||||||
|
CFStringGetCharacters(lang, range, str);
|
||||||
|
str[range.length] = 0;
|
||||||
|
return LocaleNameToLCID(str, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HKL get_hkl(CFStringRef lang, CFStringRef type)
|
||||||
|
{
|
||||||
|
ULONG_PTR lcid = get_lcid(lang);
|
||||||
|
struct layout *layout;
|
||||||
|
|
||||||
|
/* Look for the last occurrence of this lcid in the list and if
|
||||||
|
present use that value + 0x10000 */
|
||||||
|
LIST_FOR_EACH_ENTRY_REV(layout, &layout_list, struct layout, entry)
|
||||||
|
{
|
||||||
|
ULONG_PTR hkl = HandleToUlong(layout->hkl);
|
||||||
|
|
||||||
|
if (LOWORD(hkl) == lcid)
|
||||||
|
{
|
||||||
|
lcid = (hkl & ~0xe0000000) + 0x10000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CFEqual(type, kTISTypeKeyboardLayout)) lcid |= 0xe0000000;
|
||||||
|
|
||||||
|
return (HKL)lcid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* update_layout_list
|
||||||
|
*
|
||||||
|
* Must be called while holding the layout_list_section
|
||||||
|
*/
|
||||||
|
static void update_layout_list(void)
|
||||||
|
{
|
||||||
|
CFArrayRef sources;
|
||||||
|
struct layout *layout;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!list_empty(&layout_list)) return;
|
||||||
|
|
||||||
|
sources = macdrv_create_input_source_list();
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(sources); i++)
|
||||||
|
{
|
||||||
|
CFDictionaryRef dict = CFArrayGetValueAtIndex(sources, i);
|
||||||
|
TISInputSourceRef input = (TISInputSourceRef)CFDictionaryGetValue(dict, macdrv_input_source_input_key);
|
||||||
|
CFStringRef type = CFDictionaryGetValue(dict, macdrv_input_source_type_key);
|
||||||
|
CFStringRef lang = CFDictionaryGetValue(dict, macdrv_input_source_lang_key);
|
||||||
|
|
||||||
|
layout = HeapAlloc(GetProcessHeap(), 0, sizeof(*layout));
|
||||||
|
layout->input_source = (TISInputSourceRef)CFRetain(input);
|
||||||
|
layout->hkl = get_hkl(lang, type);
|
||||||
|
|
||||||
|
list_add_tail(&layout_list, &layout->entry);
|
||||||
|
TRACE("adding new layout %p\n", layout->hkl);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(sources);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* macdrv_compute_keyboard_layout
|
* macdrv_compute_keyboard_layout
|
||||||
|
@ -1221,6 +1306,36 @@ HKL CDECL macdrv_GetKeyboardLayout(DWORD thread_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* GetKeyboardLayoutList (MACDRV.@)
|
||||||
|
*/
|
||||||
|
UINT CDECL macdrv_GetKeyboardLayoutList(INT size, HKL *list)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
struct layout *layout;
|
||||||
|
|
||||||
|
TRACE("%d, %p\n", size, list);
|
||||||
|
|
||||||
|
EnterCriticalSection(&layout_list_section);
|
||||||
|
|
||||||
|
update_layout_list();
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY(layout, &layout_list, struct layout, entry)
|
||||||
|
{
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
if (count >= size) break;
|
||||||
|
list[count] = layout->hkl;
|
||||||
|
TRACE("\t%d: %p\n", count, list[count]);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&layout_list_section);
|
||||||
|
|
||||||
|
TRACE("returning %d\n", count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* GetKeyboardLayoutName (MACDRV.@)
|
* GetKeyboardLayoutName (MACDRV.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -123,6 +123,7 @@ enum {
|
||||||
MACDRV_HOTKEY_FAILURE,
|
MACDRV_HOTKEY_FAILURE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct __TISInputSource *TISInputSourceRef;
|
||||||
|
|
||||||
typedef struct macdrv_opaque_window* macdrv_window;
|
typedef struct macdrv_opaque_window* macdrv_window;
|
||||||
typedef struct macdrv_opaque_event_queue* macdrv_event_queue;
|
typedef struct macdrv_opaque_event_queue* macdrv_event_queue;
|
||||||
|
@ -411,6 +412,10 @@ extern int macdrv_send_text_input_event(int pressed, unsigned int flags, int rep
|
||||||
|
|
||||||
/* keyboard */
|
/* keyboard */
|
||||||
extern CFDataRef macdrv_copy_keyboard_layout(CGEventSourceKeyboardType* keyboard_type, int* is_iso) DECLSPEC_HIDDEN;
|
extern CFDataRef macdrv_copy_keyboard_layout(CGEventSourceKeyboardType* keyboard_type, int* is_iso) DECLSPEC_HIDDEN;
|
||||||
|
extern CFArrayRef macdrv_create_input_source_list(void) DECLSPEC_HIDDEN;
|
||||||
|
extern const CFStringRef macdrv_input_source_input_key DECLSPEC_HIDDEN;
|
||||||
|
extern const CFStringRef macdrv_input_source_type_key DECLSPEC_HIDDEN;
|
||||||
|
extern const CFStringRef macdrv_input_source_lang_key DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
||||||
/* clipboard */
|
/* clipboard */
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
@ cdecl GetClipboardData(long) macdrv_GetClipboardData
|
@ cdecl GetClipboardData(long) macdrv_GetClipboardData
|
||||||
@ cdecl GetCursorPos(ptr) macdrv_GetCursorPos
|
@ cdecl GetCursorPos(ptr) macdrv_GetCursorPos
|
||||||
@ cdecl GetKeyboardLayout(long) macdrv_GetKeyboardLayout
|
@ cdecl GetKeyboardLayout(long) macdrv_GetKeyboardLayout
|
||||||
|
@ cdecl GetKeyboardLayoutList(long ptr) macdrv_GetKeyboardLayoutList
|
||||||
@ cdecl GetKeyboardLayoutName(ptr) macdrv_GetKeyboardLayoutName
|
@ cdecl GetKeyboardLayoutName(ptr) macdrv_GetKeyboardLayoutName
|
||||||
@ cdecl GetKeyNameText(long ptr long) macdrv_GetKeyNameText
|
@ cdecl GetKeyNameText(long ptr long) macdrv_GetKeyNameText
|
||||||
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
|
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
|
||||||
|
|
Loading…
Reference in New Issue