aboutsummaryrefslogtreecommitdiffstats
path: root/src/native/hid/KeyboardUtil_windows.c
blob: ce5993a5dc42db98ff03465274229c777f799080 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

/**
 * \file KeyboardUtil_unix.c
 * \brief Windows specific code to press/release keys.
 * \author Sebastien Vincent
 */

#include <windows.h>

#include "KeyboardUtil.h"

void generateSymbol(const char* symbol, jboolean pressed)
{
    /* on Windows AltGr correspond to CTRL-ALT */
    if(!strcmp(symbol, "altgr"))
    {
        int scancode = MapVirtualKey(VK_CONTROL, 0);
        keybd_event(VK_CONTROL, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
        scancode = MapVirtualKey(VK_MENU, 0);
        keybd_event(VK_MENU, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
    }
    else if(!strcmp(symbol, "shift"))
    {
        int scancode = MapVirtualKey(VK_SHIFT, 0);
        keybd_event(VK_SHIFT, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
    }
    else if(!strcmp(symbol, "ctrl"))
    {
        int scancode = MapVirtualKey(VK_CONTROL, 0);
        keybd_event(VK_CONTROL, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
    }
    else if(!strcmp(symbol, "alt"))
    {
        int scancode = MapVirtualKey(VK_MENU, 0);
        keybd_event(VK_MENU, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
    }
    else if(!strcmp(symbol, "hankaku"))
    {
        /* XXX constant name for HANKAKU ? */
        /* 
        int scancode = MapVirtualKey(VK_HANKAKU, 0);
        keybd_event(VK_HANKAKU, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0); 
        */
    }
}

void generateKey(jchar key, jboolean pressed)
{
    SHORT letter = 0;
    TCHAR ch = key;
    UINT scancode = 0;
    SHORT modifiers = 0;

    letter = VkKeyScan(ch);

    if(letter == -1)
    {
        /* printf("No key found\n"); */
        return;
    }

    modifiers = HIBYTE(letter);
    letter = LOBYTE(letter);
       
    if(pressed)
    {
        /* shift */
        if(modifiers & 1)
        {
            generateSymbol("shift", JNI_TRUE);
        }

        /* ctrl */
        if(modifiers & 2)
        {
            generateSymbol("ctrl", JNI_TRUE);
        }

        /* alt */
        if(modifiers & 4)
        {
            generateSymbol("alt", JNI_TRUE);
        }

        /* hankaku */
        if(modifiers & 8)
        {
            generateSymbol("hankaku", JNI_TRUE);
        }
    }

    /* find scancode */
    scancode = MapVirtualKey(letter, 0);

    /* press and release key as well as modifiers */
    keybd_event(letter, scancode, pressed ? 0 : KEYEVENTF_KEYUP, 0);

    if(!pressed)
    {
        /* shift */
        if(modifiers & 1)
        {
            generateSymbol("shift", JNI_FALSE);
        }

        /* ctrl */
        if(modifiers & 2)
        {
            generateSymbol("ctrl", JNI_FALSE);
        }

        /* alt */
        if(modifiers & 4)
        {
            generateSymbol("alt", JNI_FALSE);
        }

        /* hankaku */
        if(modifiers & 8)
        {
            generateSymbol("hankaku", JNI_FALSE);
        }
    }
}