~ubuntu-branches/ubuntu/raring/freerdp/raring

« back to all changes in this revision

Viewing changes to X11/xf_keyboard.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2010-06-23 21:39:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100623213909-bb9pvvv03913tdv6
Tags: upstream-0.7.1
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (c) 2009-2010 Jay Sorg
 
3
 
 
4
   Permission is hereby granted, free of charge, to any person obtaining a
 
5
   copy of this software and associated documentation files (the "Software"),
 
6
   to deal in the Software without restriction, including without limitation
 
7
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
   and/or sell copies of the Software, and to permit persons to whom the
 
9
   Software is furnished to do so, subject to the following conditions:
 
10
 
 
11
   The above copyright notice and this permission notice shall be included
 
12
   in all copies or substantial portions of the Software.
 
13
 
 
14
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
15
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
17
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
19
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
20
   DEALINGS IN THE SOFTWARE.
 
21
*/
 
22
 
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <X11/Xlib.h>
 
27
#include <X11/Xutil.h>
 
28
#include <X11/keysym.h>
 
29
#include <freerdp/freerdp.h>
 
30
#include <freerdp/kbd.h>
 
31
#include "xf_types.h"
 
32
#include "xf_win.h"
 
33
#include "xf_keyboard.h"
 
34
 
 
35
static int xf_kb_keyboard_layout = 0;
 
36
static RD_BOOL pressed_keys[256] = { False };
 
37
 
 
38
void
 
39
xf_kb_init(unsigned int keyboard_layout_id)
 
40
{
 
41
        xf_kb_keyboard_layout = freerdp_kbd_init(keyboard_layout_id);
 
42
        printf("freerdp_kbd_init: %X\n", xf_kb_keyboard_layout);
 
43
}
 
44
 
 
45
void
 
46
xf_kb_inst_init(xfInfo * xfi)
 
47
{
 
48
        xfi->inst->settings->keyboard_layout = xf_kb_keyboard_layout;
 
49
};
 
50
 
 
51
void
 
52
xf_kb_send_key(xfInfo * xfi, int flags, uint8 keycode)
 
53
{
 
54
        int scancode;
 
55
 
 
56
        if (keycode == xfi->pause_key)
 
57
        {
 
58
                /* This is a special key the actually sends two scancodes to the
 
59
                   server.  It looks like Control - NumLock but with special flags. */
 
60
                //printf("special VK_PAUSE\n");
 
61
                if (flags & KBD_FLAG_UP)
 
62
                {
 
63
                        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, 0x8200, 0x1d, 0);
 
64
                        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, 0x8000, 0x45, 0);
 
65
                }
 
66
                else
 
67
                {
 
68
                        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, 0x0200, 0x1d, 0);
 
69
                        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, 0x0000, 0x45, 0);
 
70
                }
 
71
        }
 
72
        else
 
73
        {
 
74
                scancode = freerdp_kbd_get_scancode_by_keycode(keycode, &flags);
 
75
                if (scancode == 0)
 
76
                {
 
77
                        printf("xf_kb_send_key: unable to get scancode (keycode=%d)\n", keycode);
 
78
                }
 
79
                else
 
80
                {
 
81
                        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, flags, scancode, 0);
 
82
                }
 
83
        }
 
84
}
 
85
 
 
86
static int
 
87
xf_kb_read_keyboard_state(xfInfo * xfi)
 
88
{
 
89
        uint32 state;
 
90
        Window wdummy;
 
91
        int dummy;
 
92
 
 
93
        XQueryPointer(xfi->display, xfi->wnd, &wdummy, &wdummy, &dummy, &dummy,
 
94
                &dummy, &dummy, &state);
 
95
        return state;
 
96
}
 
97
 
 
98
static RD_BOOL
 
99
xf_kb_get_key_state(xfInfo * xfi, int state, int keysym)
 
100
{
 
101
        int modifierpos, key, keysymMask = 0;
 
102
        int offset;
 
103
        KeyCode keycode = XKeysymToKeycode(xfi->display, keysym);
 
104
 
 
105
        if (keycode == NoSymbol)
 
106
        {
 
107
                return False;
 
108
        }
 
109
        for (modifierpos = 0; modifierpos < 8; modifierpos++)
 
110
        {
 
111
                offset = xfi->mod_map->max_keypermod * modifierpos;
 
112
                for (key = 0; key < xfi->mod_map->max_keypermod; key++)
 
113
                {
 
114
                        if (xfi->mod_map->modifiermap[offset + key] == keycode)
 
115
                        {
 
116
                                keysymMask |= 1 << modifierpos;
 
117
                        }
 
118
                }
 
119
        }
 
120
        return (state & keysymMask) ? True : False;
 
121
}
 
122
 
 
123
int
 
124
xf_kb_get_toggle_keys_state(xfInfo * xfi)
 
125
{
 
126
        int toggle_keys_state = 0;
 
127
        int state;
 
128
 
 
129
        state = xf_kb_read_keyboard_state(xfi);
 
130
        if (xf_kb_get_key_state(xfi, state, XK_Scroll_Lock))
 
131
        {
 
132
                toggle_keys_state |= KBD_SYNC_SCROLL_LOCK;
 
133
        }
 
134
        if (xf_kb_get_key_state(xfi, state, XK_Num_Lock))
 
135
        {
 
136
                toggle_keys_state |= KBD_SYNC_NUM_LOCK;
 
137
        }
 
138
        if (xf_kb_get_key_state(xfi, state, XK_Caps_Lock))
 
139
        {
 
140
                toggle_keys_state |= KBD_SYNC_CAPS_LOCK;
 
141
        }
 
142
        if (xf_kb_get_key_state(xfi, state, XK_Kana_Lock))
 
143
        {
 
144
                toggle_keys_state |= KBD_SYNC_KANA_LOCK;
 
145
        }
 
146
        return toggle_keys_state;
 
147
}
 
148
 
 
149
void
 
150
xf_kb_focus_in(xfInfo * xfi)
 
151
{
 
152
        int flags;
 
153
        int scancode;
 
154
 
 
155
        /* on focus in send a tab up like mstsc.exe */
 
156
        scancode = freerdp_kbd_get_scancode_by_virtualkey(xfi->tab_key);
 
157
        xfi->inst->rdp_send_input(xfi->inst, RDP_INPUT_SCANCODE, KBD_FLAG_UP, scancode, 0);
 
158
        /* sync num, caps, scroll, kana lock */
 
159
        flags = xf_kb_get_toggle_keys_state(xfi);
 
160
        xfi->inst->rdp_sync_input(xfi->inst, flags);
 
161
}
 
162
 
 
163
void
 
164
xf_kb_set_keypress(uint8 keycode, KeySym keysym)
 
165
{
 
166
        if (keycode < 8 || keycode > 255)
 
167
                return;
 
168
        pressed_keys[keycode] = keysym;
 
169
}
 
170
 
 
171
void
 
172
xf_kb_unset_keypress(uint8 keycode)
 
173
{
 
174
        if (keycode < 8 || keycode > 255)
 
175
                return;
 
176
        pressed_keys[keycode] = NoSymbol;
 
177
}
 
178
 
 
179
static RD_BOOL
 
180
xf_kb_key_pressed(xfInfo * xfi, KeySym keysym)
 
181
{
 
182
        KeyCode keycode = XKeysymToKeycode(xfi->display, keysym);
 
183
        return pressed_keys[keycode] == keysym;
 
184
}
 
185
 
 
186
RD_BOOL
 
187
xf_kb_handle_special_keys(xfInfo * xfi, KeySym keysym)
 
188
{
 
189
        if (keysym == XK_Return)
 
190
        {
 
191
                if ((xf_kb_key_pressed(xfi, XK_Alt_L) || xf_kb_key_pressed(xfi, XK_Alt_R))
 
192
                    && (xf_kb_key_pressed(xfi, XK_Control_L) || xf_kb_key_pressed(xfi, XK_Control_R)))
 
193
                {
 
194
                        /* Ctrl-Alt-Enter: toggle full screen */
 
195
                        xf_toggle_fullscreen(xfi);
 
196
                        return True;
 
197
                }
 
198
        }
 
199
 
 
200
        return False;
 
201
}