Magellan Linux

Contents of /trunk/tigervnc/patches/tigervnc-1.0.1-r3887.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1201 - (show annotations) (download)
Mon Nov 22 23:25:59 2010 UTC (13 years, 5 months ago) by niro
File size: 35721 byte(s)
-patches for 1.0.1 against xorg-server-1.7
1 Index: unix/xserver/hw/vnc/Input.cc
2 ===================================================================
3 --- unix/xserver/hw/vnc/Input.cc (revision 3886)
4 +++ unix/xserver/hw/vnc/Input.cc (revision 3887)
5 @@ -21,13 +21,49 @@
6 #include <dix-config.h>
7 #endif
8
9 +#include <rfb/LogWriter.h>
10 #include "Input.h"
11 #include "xorg-version.h"
12 +#include "vncExtInit.h"
13
14 extern "C" {
15 +#define public c_public
16 +#define class c_class
17 +#include "inputstr.h"
18 #include "mi.h"
19 +#ifndef XKB_IN_SERVER
20 +#define XKB_IN_SERVER
21 +#endif
22 +#ifdef XKB
23 +/*
24 + * This include is needed to use XkbConvertCase instead of XConvertCase even if
25 + * we don't use XKB extension.
26 + */
27 +#include <xkbsrv.h>
28 +#endif
29 +#if XORG >= 16
30 +#include "exevents.h"
31 +extern void
32 +CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
33 +#endif
34 +#include <X11/keysym.h>
35 +#include <X11/Xutil.h>
36 +#undef public
37 +#undef class
38 }
39
40 +using namespace rdr;
41 +using namespace rfb;
42 +
43 +static LogWriter vlog("Input");
44 +
45 +#define BUTTONS 5
46 +static int pointerProc(DeviceIntPtr pDevice, int onoff);
47 +
48 +static int keyboardProc(DeviceIntPtr pDevice, int onoff);
49 +static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col);
50 +static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col);
51 +
52 /* Event queue is shared between all devices. */
53 #if XORG == 15
54 static xEvent *eventq = NULL;
55 @@ -70,10 +106,6 @@
56 }
57 }
58
59 -/* Pointer device pre-declarations */
60 -#define BUTTONS 5
61 -static int pointerProc(DeviceIntPtr pDevice, int onoff);
62 -
63 /* Pointer device methods */
64
65 PointerDevice::PointerDevice(rfb::VNCServerST *_server)
66 @@ -165,3 +197,569 @@
67 return Success;
68 }
69
70 +/* KeyboardDevice methods */
71 +
72 +KeyboardDevice::KeyboardDevice(void)
73 +{
74 + dev = AddInputDevice(
75 +#if XORG >= 16
76 + serverClient,
77 +#endif
78 + keyboardProc, TRUE);
79 + RegisterKeyboardDevice(dev);
80 + initEventq();
81 +}
82 +
83 +#define IS_PRESSED(keyc, keycode) \
84 + ((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
85 +
86 +/*
87 + * ModifierState is a class which helps simplify generating a "fake" press or
88 + * release of shift, ctrl, alt, etc. An instance of the class is created for
89 + * every modifier which may need to be pressed or released. Then either
90 + * press() or release() may be called to make sure that the corresponding keys
91 + * are in the right state. The destructor of the class automatically reverts
92 + * to the previous state. Each modifier may have multiple keys associated with
93 + * it, so in the case of a fake release, this may involve releasing more than
94 + * one key.
95 + */
96 +
97 +class ModifierState {
98 +public:
99 + ModifierState(DeviceIntPtr _dev, int _modIndex)
100 + : modIndex(_modIndex), nKeys(0), keys(0), pressed(false),
101 + dev(_dev) {}
102 +
103 + ~ModifierState()
104 + {
105 + for (int i = 0; i < nKeys; i++)
106 + generateXKeyEvent(keys[i], !pressed);
107 + delete [] keys;
108 + }
109 +
110 + void press()
111 + {
112 + KeyClassPtr keyc = dev->key;
113 + if (!(keyc->state & (1 << modIndex))) {
114 + int index = modIndex * keyc->maxKeysPerModifier;
115 + tempKeyEvent(keyc->modifierKeyMap[index], true);
116 + pressed = true;
117 + }
118 + }
119 +
120 + void release()
121 + {
122 + KeyClassPtr keyc = dev->key;
123 + if ((keyc->state & (1 << modIndex)) == 0)
124 + return;
125 +
126 + for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
127 + int index = modIndex * keyc->maxKeysPerModifier + k;
128 + int keycode = keyc->modifierKeyMap[index];
129 + if (keycode && IS_PRESSED(keyc, keycode))
130 + tempKeyEvent(keycode, false);
131 + }
132 + }
133 +
134 +private:
135 + void tempKeyEvent(int keycode, bool down)
136 + {
137 + if (keycode) {
138 + if (!keys) keys = new int[dev->key->maxKeysPerModifier];
139 + keys[nKeys++] = keycode;
140 + generateXKeyEvent(keycode, down);
141 + }
142 + }
143 +
144 + void generateXKeyEvent(int keycode, bool down)
145 + {
146 + int n, action;
147 +
148 + action = down ? KeyPress : KeyRelease;
149 + n = GetKeyboardEvents(eventq, dev, action, keycode);
150 + enqueueEvents(dev, n);
151 +
152 + vlog.debug("fake keycode %d %s", keycode,
153 + down ? "down" : "up");
154 + }
155 +
156 + int modIndex;
157 + int nKeys;
158 + int *keys;
159 + bool pressed;
160 + DeviceIntPtr dev;
161 +};
162 +
163 +
164 +/* altKeysym is a table of alternative keysyms which have the same meaning. */
165 +
166 +static struct altKeysym_t {
167 + KeySym a, b;
168 +} altKeysym[] = {
169 + { XK_Shift_L, XK_Shift_R },
170 + { XK_Control_L, XK_Control_R },
171 + { XK_Meta_L, XK_Meta_R },
172 + { XK_Alt_L, XK_Alt_R },
173 + { XK_Super_L, XK_Super_R },
174 + { XK_Hyper_L, XK_Hyper_R },
175 + { XK_KP_Space, XK_space },
176 + { XK_KP_Tab, XK_Tab },
177 + { XK_KP_Enter, XK_Return },
178 + { XK_KP_F1, XK_F1 },
179 + { XK_KP_F2, XK_F2 },
180 + { XK_KP_F3, XK_F3 },
181 + { XK_KP_F4, XK_F4 },
182 + { XK_KP_Home, XK_Home },
183 + { XK_KP_Left, XK_Left },
184 + { XK_KP_Up, XK_Up },
185 + { XK_KP_Right, XK_Right },
186 + { XK_KP_Down, XK_Down },
187 + { XK_KP_Page_Up, XK_Page_Up },
188 + { XK_KP_Page_Down, XK_Page_Down },
189 + { XK_KP_End, XK_End },
190 + { XK_KP_Begin, XK_Begin },
191 + { XK_KP_Insert, XK_Insert },
192 + { XK_KP_Delete, XK_Delete },
193 + { XK_KP_Equal, XK_equal },
194 + { XK_KP_Multiply, XK_asterisk },
195 + { XK_KP_Add, XK_plus },
196 + { XK_KP_Separator, XK_comma },
197 + { XK_KP_Subtract, XK_minus },
198 + { XK_KP_Decimal, XK_period },
199 + { XK_KP_Divide, XK_slash },
200 + { XK_KP_0, XK_0 },
201 + { XK_KP_1, XK_1 },
202 + { XK_KP_2, XK_2 },
203 + { XK_KP_3, XK_3 },
204 + { XK_KP_4, XK_4 },
205 + { XK_KP_5, XK_5 },
206 + { XK_KP_6, XK_6 },
207 + { XK_KP_7, XK_7 },
208 + { XK_KP_8, XK_8 },
209 + { XK_KP_9, XK_9 },
210 +};
211 +
212 +/*
213 + * keyEvent() - work out the best keycode corresponding to the keysym sent by
214 + * the viewer. This is non-trivial because we can't assume much about the
215 + * local keyboard layout. We must also find out which column of the keyboard
216 + * mapping the keysym is in, and alter the shift state appropriately. Column 0
217 + * means both shift and "mode_switch" (AltGr) must be released, column 1 means
218 + * shift must be pressed and mode_switch released, column 2 means shift must be
219 + * released and mode_switch pressed, and column 3 means both shift and
220 + * mode_switch must be pressed.
221 + *
222 + * Magic, which dynamically adds keysym<->keycode mapping depends on X.Org
223 + * version. Quick explanation of that "magic":
224 + *
225 + * 1.5
226 + * - has only one core keyboard so we have to keep core keyboard mapping
227 + * synchronized with vncKeyboardDevice. Do it via SwitchCoreKeyboard()
228 + *
229 + * 1.6 (aka MPX - Multi pointer X)
230 + * - multiple master devices (= core devices) exists, keep vncKeyboardDevice
231 + * synchronized with proper master device
232 + */
233 +
234 +void KeyboardDevice::keyEvent(rdr::U32 keysym, bool down)
235 +{
236 + DeviceIntPtr master;
237 + KeyClassPtr keyc = dev->key;
238 + KeySymsPtr keymap = &keyc->curKeySyms;
239 + KeySym *map = keymap->map;
240 + KeyCode minKeyCode = keymap->minKeyCode;
241 + KeyCode maxKeyCode = keymap->maxKeyCode;
242 + int mapWidth = keymap->mapWidth;
243 + unsigned int i, n;
244 + int j, k, action;
245 +
246 + if (keysym == XK_Caps_Lock) {
247 + vlog.debug("Ignoring caps lock");
248 + return;
249 + }
250 +
251 + /* find which modifier Mode_switch is on. */
252 + int modeSwitchMapIndex = 0;
253 + for (i = 3; i < 8; i++) {
254 + for (k = 0; k < keyc->maxKeysPerModifier; k++) {
255 + int index = i * keyc->maxKeysPerModifier + k;
256 + int keycode = keyc->modifierKeyMap[index];
257 +
258 + if (keycode == 0)
259 + continue;
260 +
261 + for (j = 0; j < mapWidth; j++) {
262 + if (map[(keycode - minKeyCode) * mapWidth + j]
263 + == XK_Mode_switch) {
264 + modeSwitchMapIndex = i;
265 + goto ModeSwitchFound;
266 + }
267 + }
268 + }
269 + }
270 +ModeSwitchFound:
271 +
272 + int col = 0;
273 + if ((keyc->state & (1 << ShiftMapIndex)) != 0)
274 + col |= 1;
275 + if (modeSwitchMapIndex != 0 &&
276 + ((keyc->state & (1 << modeSwitchMapIndex))) != 0)
277 + col |= 2;
278 +
279 + int kc = KeysymToKeycode(keymap, keysym, &col);
280 +
281 + /*
282 + * Sort out the "shifted Tab" mess. If we are sent a shifted Tab,
283 + * generate a local shifted Tab regardless of what the "shifted Tab"
284 + * keysym is on the local keyboard (it might be Tab, ISO_Left_Tab or
285 + * HP's private BackTab keysym, and quite possibly some others too).
286 + * We never get ISO_Left_Tab here because it's already been translated
287 + * in VNCSConnectionST.
288 + */
289 + if (keysym == XK_Tab && ((keyc->state & (1 << ShiftMapIndex))) != 0)
290 + col |= 1;
291 +
292 + if (kc == 0) {
293 + /*
294 + * Not a direct match in the local keyboard mapping. Check for
295 + * alternative keysyms with the same meaning.
296 + */
297 + for (i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {
298 + if (keysym == altKeysym[i].a)
299 + kc = KeysymToKeycode(keymap, altKeysym[i].b,
300 + &col);
301 + else if (keysym == altKeysym[i].b)
302 + kc = KeysymToKeycode(keymap, altKeysym[i].a,
303 + &col);
304 + if (kc)
305 + break;
306 + }
307 + }
308 +
309 + if (kc == 0) {
310 + /* Dynamically add a new key to the keyboard mapping. */
311 + for (kc = maxKeyCode; kc >= minKeyCode; kc--) {
312 + if (map[(kc - minKeyCode) * mapWidth] != 0)
313 + continue;
314 +
315 + map[(kc - minKeyCode) * mapWidth] = keysym;
316 + col = 0;
317 +
318 + vlog.info("Added unknown keysym 0x%x to keycode %d",
319 + keysym, kc);
320 +#if XORG == 15
321 + master = inputInfo.keyboard;
322 +#else
323 + master = dev->u.master;
324 +#endif
325 + void *slave = dixLookupPrivate(&master->devPrivates,
326 + CoreDevicePrivateKey);
327 + if (dev == slave) {
328 + dixSetPrivate(&master->devPrivates,
329 + CoreDevicePrivateKey, NULL);
330 +#if XORG == 15
331 + SwitchCoreKeyboard(dev);
332 +#else
333 + CopyKeyClass(dev, master);
334 +#endif
335 + }
336 + break;
337 + }
338 + }
339 +
340 + if (kc < minKeyCode) {
341 + vlog.info("Keyboard mapping full - ignoring unknown keysym "
342 + "0x%x",keysym);
343 + return;
344 + }
345 +
346 + /*
347 + * See if it's a modifier key. If so, then don't do any auto-repeat,
348 + * because the X server will translate each press into a release
349 + * followed by a press.
350 + */
351 + for (i = 0; i < 8; i++) {
352 + for (k = 0; k < keyc->maxKeysPerModifier; k++) {
353 + int index = i * keyc->maxKeysPerModifier + k;
354 + if (kc == keyc->modifierKeyMap[index] &&
355 + IS_PRESSED(keyc,kc) && down)
356 + return;
357 + }
358 + }
359 +
360 + ModifierState shift(dev, ShiftMapIndex);
361 + ModifierState modeSwitch(dev, modeSwitchMapIndex);
362 + if (down) {
363 + if (col & 1)
364 + shift.press();
365 + else
366 + shift.release();
367 + if (modeSwitchMapIndex) {
368 + if (col & 2)
369 + modeSwitch.press();
370 + else
371 + modeSwitch.release();
372 + }
373 + }
374 +
375 + vlog.debug("keycode %d %s", kc, down ? "down" : "up");
376 + action = down ? KeyPress : KeyRelease;
377 + n = GetKeyboardEvents(eventq, dev, action, kc);
378 + enqueueEvents(dev, n);
379 +}
380 +
381 +static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)
382 +{
383 + int per = keymap->mapWidth;
384 + KeySym *syms;
385 + KeySym lsym, usym;
386 +
387 + if ((col < 0) || ((col >= per) && (col > 3)) ||
388 + (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))
389 + return NoSymbol;
390 +
391 + syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
392 + if (col >= 4)
393 + return syms[col];
394 +
395 + if (col > 1) {
396 + while ((per > 2) && (syms[per - 1] == NoSymbol))
397 + per--;
398 + if (per < 3)
399 + col -= 2;
400 + }
401 +
402 + if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
403 + XConvertCase(syms[col&~1], &lsym, &usym);
404 + if (!(col & 1))
405 + return lsym;
406 + /*
407 + * I'm commenting out this logic because it's incorrect even
408 + * though it was copied from the Xlib sources. The X protocol
409 + * book quite clearly states that where a group consists of
410 + * element 1 being a non-alphabetic keysym and element 2 being
411 + * NoSymbol that you treat the second element as being the
412 + * same as the first. This also tallies with the behaviour
413 + * produced by the installed Xlib on my linux box (I believe
414 + * this is because it uses some XKB code rather than the
415 + * original Xlib code - compare XKBBind.c with KeyBind.c in
416 + * lib/X11).
417 + */
418 +#if 0
419 + else if (usym == lsym)
420 + return NoSymbol;
421 +#endif
422 + else
423 + return usym;
424 + }
425 +
426 + return syms[col];
427 +}
428 +
429 +/*
430 + * KeysymToKeycode() - find the keycode and column corresponding to the given
431 + * keysym. The value of col passed in should be the column determined from the
432 + * current shift state. If the keysym can be found in that column we prefer
433 + * that to finding it in a different column (which would require fake events to
434 + * alter the shift state).
435 + */
436 +static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col)
437 +{
438 + int i, j;
439 +
440 + j = *col;
441 + for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
442 + if (KeyCodetoKeySym(keymap, i, j) == ks)
443 + return i;
444 + }
445 +
446 + for (j = 0; j < keymap->mapWidth; j++) {
447 + for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
448 + if (KeyCodetoKeySym(keymap, i, j) == ks) {
449 + *col = j;
450 + return i;
451 + }
452 + }
453 + }
454 +
455 + return 0;
456 +}
457 +
458 +/* Fairly standard US PC Keyboard */
459 +
460 +#define MIN_KEY 8
461 +#define MAX_KEY 255
462 +#define MAP_LEN (MAX_KEY - MIN_KEY + 1)
463 +#define KEYSYMS_PER_KEY 2
464 +KeySym keyboardMap[MAP_LEN * KEYSYMS_PER_KEY] = {
465 + NoSymbol, NoSymbol,
466 + XK_Escape, NoSymbol,
467 + XK_1, XK_exclam,
468 + XK_2, XK_at,
469 + XK_3, XK_numbersign,
470 + XK_4, XK_dollar,
471 + XK_5, XK_percent,
472 + XK_6, XK_asciicircum,
473 + XK_7, XK_ampersand,
474 + XK_8, XK_asterisk,
475 + XK_9, XK_parenleft,
476 + XK_0, XK_parenright,
477 + XK_minus, XK_underscore,
478 + XK_equal, XK_plus,
479 + XK_BackSpace, NoSymbol,
480 + XK_Tab, NoSymbol,
481 + XK_q, XK_Q,
482 + XK_w, XK_W,
483 + XK_e, XK_E,
484 + XK_r, XK_R,
485 + XK_t, XK_T,
486 + XK_y, XK_Y,
487 + XK_u, XK_U,
488 + XK_i, XK_I,
489 + XK_o, XK_O,
490 + XK_p, XK_P,
491 + XK_bracketleft, XK_braceleft,
492 + XK_bracketright, XK_braceright,
493 + XK_Return, NoSymbol,
494 + XK_Control_L, NoSymbol,
495 + XK_a, XK_A,
496 + XK_s, XK_S,
497 + XK_d, XK_D,
498 + XK_f, XK_F,
499 + XK_g, XK_G,
500 + XK_h, XK_H,
501 + XK_j, XK_J,
502 + XK_k, XK_K,
503 + XK_l, XK_L,
504 + XK_semicolon, XK_colon,
505 + XK_apostrophe, XK_quotedbl,
506 + XK_grave, XK_asciitilde,
507 + XK_Shift_L, NoSymbol,
508 + XK_backslash, XK_bar,
509 + XK_z, XK_Z,
510 + XK_x, XK_X,
511 + XK_c, XK_C,
512 + XK_v, XK_V,
513 + XK_b, XK_B,
514 + XK_n, XK_N,
515 + XK_m, XK_M,
516 + XK_comma, XK_less,
517 + XK_period, XK_greater,
518 + XK_slash, XK_question,
519 + XK_Shift_R, NoSymbol,
520 + XK_KP_Multiply, NoSymbol,
521 + XK_Alt_L, XK_Meta_L,
522 + XK_space, NoSymbol,
523 + /* XK_Caps_Lock */ NoSymbol, NoSymbol,
524 + XK_F1, NoSymbol,
525 + XK_F2, NoSymbol,
526 + XK_F3, NoSymbol,
527 + XK_F4, NoSymbol,
528 + XK_F5, NoSymbol,
529 + XK_F6, NoSymbol,
530 + XK_F7, NoSymbol,
531 + XK_F8, NoSymbol,
532 + XK_F9, NoSymbol,
533 + XK_F10, NoSymbol,
534 + XK_Num_Lock, XK_Pointer_EnableKeys,
535 + XK_Scroll_Lock, NoSymbol,
536 + XK_KP_Home, XK_KP_7,
537 + XK_KP_Up, XK_KP_8,
538 + XK_KP_Prior, XK_KP_9,
539 + XK_KP_Subtract, NoSymbol,
540 + XK_KP_Left, XK_KP_4,
541 + XK_KP_Begin, XK_KP_5,
542 + XK_KP_Right, XK_KP_6,
543 + XK_KP_Add, NoSymbol,
544 + XK_KP_End, XK_KP_1,
545 + XK_KP_Down, XK_KP_2,
546 + XK_KP_Next, XK_KP_3,
547 + XK_KP_Insert, XK_KP_0,
548 + XK_KP_Delete, XK_KP_Decimal,
549 + NoSymbol, NoSymbol,
550 + NoSymbol, NoSymbol,
551 + NoSymbol, NoSymbol,
552 + XK_F11, NoSymbol,
553 + XK_F12, NoSymbol,
554 + XK_Home, NoSymbol,
555 + XK_Up, NoSymbol,
556 + XK_Prior, NoSymbol,
557 + XK_Left, NoSymbol,
558 + NoSymbol, NoSymbol,
559 + XK_Right, NoSymbol,
560 + XK_End, NoSymbol,
561 + XK_Down, NoSymbol,
562 + XK_Next, NoSymbol,
563 + XK_Insert, NoSymbol,
564 + XK_Delete, NoSymbol,
565 + XK_KP_Enter, NoSymbol,
566 + XK_Control_R, NoSymbol,
567 + XK_Pause, XK_Break,
568 + XK_Print, XK_Execute,
569 + XK_KP_Divide, NoSymbol,
570 + XK_Alt_R, XK_Meta_R,
571 +};
572 +
573 +static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
574 +{
575 + int i;
576 +
577 + for (i = 0; i < MAP_LENGTH; i++)
578 + pModMap[i] = NoSymbol;
579 +
580 + for (i = 0; i < MAP_LEN; i++) {
581 + if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
582 + pModMap[i + MIN_KEY] = LockMask;
583 + else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
584 + keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
585 + pModMap[i + MIN_KEY] = ShiftMask;
586 + else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
587 + keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R)
588 + pModMap[i + MIN_KEY] = ControlMask;
589 + else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
590 + keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
591 + pModMap[i + MIN_KEY] = Mod1Mask;
592 + }
593 +
594 + pKeySyms->minKeyCode = MIN_KEY;
595 + pKeySyms->maxKeyCode = MAX_KEY;
596 + pKeySyms->mapWidth = KEYSYMS_PER_KEY;
597 + pKeySyms->map = keyboardMap;
598 +
599 + return TRUE;
600 +}
601 +
602 +static void keyboardBell(int percent, DeviceIntPtr device, pointer ctrl,
603 + int class_)
604 +{
605 + if (percent > 0)
606 + vncBell();
607 +}
608 +
609 +static int keyboardProc(DeviceIntPtr pDevice, int onoff)
610 +{
611 + KeySymsRec keySyms;
612 + CARD8 modMap[MAP_LENGTH];
613 + DevicePtr pDev = (DevicePtr)pDevice;
614 +
615 + switch (onoff) {
616 + case DEVICE_INIT:
617 + GetMappings(&keySyms, modMap);
618 + InitKeyboardDeviceStruct(pDev, &keySyms, modMap, keyboardBell,
619 + (KbdCtrlProcPtr)NoopDDA);
620 + break;
621 + case DEVICE_ON:
622 + pDev->on = TRUE;
623 + break;
624 + case DEVICE_OFF:
625 + pDev->on = FALSE;
626 + break;
627 +#if 0
628 + case DEVICE_CLOSE:
629 + break;
630 +#endif
631 + }
632 +
633 + return Success;
634 +}
635 +
636 Index: unix/xserver/hw/vnc/Input.h
637 ===================================================================
638 --- unix/xserver/hw/vnc/Input.h (revision 3886)
639 +++ unix/xserver/hw/vnc/Input.h (revision 3887)
640 @@ -58,4 +58,17 @@
641 rfb::Point cursorPos, oldCursorPos;
642 };
643
644 +/* Represents keyboard device. */
645 +class KeyboardDevice {
646 +public:
647 + /* Create new Keyboard device instance. */
648 + KeyboardDevice(void);
649 +
650 + void Press(rdr::U32 keysym) { keyEvent(keysym, true); }
651 + void Release(rdr::U32 keysym) { keyEvent(keysym, false); }
652 +private:
653 + void keyEvent(rdr::U32 keysym, bool down);
654 + DeviceIntPtr dev;
655 +};
656 +
657 #endif
658 Index: unix/xserver/hw/vnc/XserverDesktop.cc
659 ===================================================================
660 --- unix/xserver/hw/vnc/XserverDesktop.cc (revision 3886)
661 +++ unix/xserver/hw/vnc/XserverDesktop.cc (revision 3887)
662 @@ -50,26 +50,7 @@
663
664 extern char *display;
665
666 -#include "inputstr.h"
667 -#include "servermd.h"
668 #include "colormapst.h"
669 -#include "resource.h"
670 -#include "cursorstr.h"
671 -#include "windowstr.h"
672 -#include "mi.h"
673 -#define XK_CYRILLIC
674 -#include <X11/keysym.h>
675 -#ifndef XKB_IN_SERVER
676 -#define XKB_IN_SERVER
677 -#endif
678 -#ifdef XKB
679 -#include <xkbsrv.h>
680 -#endif
681 -#if XORG >= 16
682 -#include "exevents.h"
683 -extern void
684 -CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
685 -#endif
686 #ifdef RANDR
687 #include "randrstr.h"
688 #endif
689 @@ -77,15 +58,6 @@
690 #undef class
691 }
692
693 -static DeviceIntPtr vncKeyboardDevice = NULL;
694 -#if XORG == 15
695 -static xEvent *eventq = NULL;
696 -#else
697 -static EventList *eventq = NULL;
698 -#endif
699 -
700 -static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff);
701 -
702 using namespace rfb;
703 using namespace network;
704
705 @@ -102,8 +74,6 @@
706 "rejecting the connection",
707 10);
708
709 -static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col);
710 -
711 static rdr::U8 reverseBits[] = {
712 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
713 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
714 @@ -193,33 +163,8 @@
715 if (httpListener)
716 httpServer = new FileHTTPServer(this);
717
718 -#if XORG == 15
719 - /*
720 - * XXX eventq is never free()-ed because it has to exist during server life
721 - * */
722 - if (!eventq)
723 - eventq = (xEvent *) xcalloc(sizeof(xEvent), GetMaximumEventsNum());
724 - if (!eventq)
725 - FatalError("Couldn't allocate eventq\n");
726 -#else
727 - GetEventList(&eventq);
728 -#endif
729 -
730 - /*
731 - * NOTE:
732 - * We _might_ have to call ActivateDevice function for both keyboard and
733 - * mouse. For Xvnc it's not needed but I have to check libvnc.so module.
734 - */
735 - if (vncKeyboardDevice == NULL) {
736 - vncKeyboardDevice = AddInputDevice(
737 -#if XORG >= 16
738 - serverClient,
739 -#endif
740 - vfbKeybdProc, TRUE);
741 - RegisterKeyboardDevice(vncKeyboardDevice);
742 - }
743 -
744 pointerDevice = new PointerDevice(server);
745 + keyboardDevice = new KeyboardDevice();
746 }
747
748 XserverDesktop::~XserverDesktop()
749 @@ -229,6 +174,7 @@
750 TimerFree(deferredUpdateTimer);
751 TimerFree(dummyTimer);
752 delete pointerDevice;
753 + delete keyboardDevice;
754 delete httpServer;
755 delete server;
756 }
757 @@ -854,533 +800,10 @@
758 }
759 }
760
761 -//
762 -// Keyboard handling
763 -//
764 -
765 -#define IS_PRESSED(keyc, keycode) \
766 - ((keyc)->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
767 -
768 -// ModifierState is a class which helps simplify generating a "fake" press
769 -// or release of shift, ctrl, alt, etc. An instance of the class is created
770 -// for every modifier which may need to be pressed or released. Then either
771 -// press() or release() may be called to make sure that the corresponding keys
772 -// are in the right state. The destructor of the class automatically reverts
773 -// to the previous state. Each modifier may have multiple keys associated with
774 -// it, so in the case of a fake release, this may involve releasing more than
775 -// one key.
776 -
777 -class ModifierState {
778 -public:
779 - ModifierState(int modIndex_)
780 - : modIndex(modIndex_), nKeys(0), keys(0), pressed(false)
781 - {
782 - }
783 - ~ModifierState() {
784 - for (int i = 0; i < nKeys; i++)
785 - generateXKeyEvent(keys[i], !pressed);
786 - delete [] keys;
787 - }
788 - void press() {
789 - KeyClassPtr keyc = vncKeyboardDevice->key;
790 - if (!(keyc->state & (1<<modIndex))) {
791 - tempKeyEvent(keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier],
792 - true);
793 - pressed = true;
794 - }
795 - }
796 - void release() {
797 - KeyClassPtr keyc = vncKeyboardDevice->key;
798 - if (keyc->state & (1<<modIndex)) {
799 - for (int k = 0; k < keyc->maxKeysPerModifier; k++) {
800 - int keycode
801 - = keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier + k];
802 - if (keycode && IS_PRESSED(keyc, keycode))
803 - tempKeyEvent(keycode, false);
804 - }
805 - }
806 - }
807 -private:
808 - void tempKeyEvent(int keycode, bool down) {
809 - if (keycode) {
810 - if (!keys) keys = new int[vncKeyboardDevice->key->maxKeysPerModifier];
811 - keys[nKeys++] = keycode;
812 - generateXKeyEvent(keycode, down);
813 - }
814 - }
815 - void generateXKeyEvent(int keycode, bool down) {
816 - int i, n;
817 - n = GetKeyboardEvents (eventq, vncKeyboardDevice,
818 - down ? KeyPress : KeyRelease, keycode);
819 - for (i = 0; i < n; i++) {
820 - mieqEnqueue (vncKeyboardDevice,
821 -#if XORG == 15
822 - eventq + i
823 -#else
824 - (eventq + i)->event
825 -#endif
826 - );
827 - }
828 - vlog.debug("fake keycode %d %s", keycode, down ? "down" : "up");
829 - }
830 - int modIndex;
831 - int nKeys;
832 - int* keys;
833 - bool pressed;
834 -};
835 -
836 -
837 -// altKeysym is a table of alternative keysyms which have the same meaning.
838 -
839 -struct altKeysym_t {
840 - KeySym a, b;
841 -};
842 -
843 -altKeysym_t altKeysym[] = {
844 - { XK_Shift_L, XK_Shift_R },
845 - { XK_Control_L, XK_Control_R },
846 - { XK_Meta_L, XK_Meta_R },
847 - { XK_Alt_L, XK_Alt_R },
848 - { XK_Super_L, XK_Super_R },
849 - { XK_Hyper_L, XK_Hyper_R },
850 - { XK_KP_Space, XK_space },
851 - { XK_KP_Tab, XK_Tab },
852 - { XK_KP_Enter, XK_Return },
853 - { XK_KP_F1, XK_F1 },
854 - { XK_KP_F2, XK_F2 },
855 - { XK_KP_F3, XK_F3 },
856 - { XK_KP_F4, XK_F4 },
857 - { XK_KP_Home, XK_Home },
858 - { XK_KP_Left, XK_Left },
859 - { XK_KP_Up, XK_Up },
860 - { XK_KP_Right, XK_Right },
861 - { XK_KP_Down, XK_Down },
862 - { XK_KP_Page_Up, XK_Page_Up },
863 - { XK_KP_Page_Down, XK_Page_Down },
864 - { XK_KP_End, XK_End },
865 - { XK_KP_Begin, XK_Begin },
866 - { XK_KP_Insert, XK_Insert },
867 - { XK_KP_Delete, XK_Delete },
868 - { XK_KP_Equal, XK_equal },
869 - { XK_KP_Multiply, XK_asterisk },
870 - { XK_KP_Add, XK_plus },
871 - { XK_KP_Separator, XK_comma },
872 - { XK_KP_Subtract, XK_minus },
873 - { XK_KP_Decimal, XK_period },
874 - { XK_KP_Divide, XK_slash },
875 - { XK_KP_0, XK_0 },
876 - { XK_KP_1, XK_1 },
877 - { XK_KP_2, XK_2 },
878 - { XK_KP_3, XK_3 },
879 - { XK_KP_4, XK_4 },
880 - { XK_KP_5, XK_5 },
881 - { XK_KP_6, XK_6 },
882 - { XK_KP_7, XK_7 },
883 - { XK_KP_8, XK_8 },
884 - { XK_KP_9, XK_9 },
885 -};
886 -
887 -/*
888 - * keyEvent() - work out the best keycode corresponding to the keysym sent by
889 - * the viewer. This is non-trivial because we can't assume much about the
890 - * local keyboard layout. We must also find out which column of the keyboard
891 - * mapping the keysym is in, and alter the shift state appropriately. Column 0
892 - * means both shift and "mode_switch" (AltGr) must be released, column 1 means
893 - * shift must be pressed and mode_switch released, column 2 means shift must be
894 - * released and mode_switch pressed, and column 3 means both shift and
895 - * mode_switch must be pressed.
896 - *
897 - * Magic, which dynamically adds keysym<->keycode mapping depends on X.Org
898 - * version. Quick explanation of that "magic":
899 - *
900 - * 1.5
901 - * - has only one core keyboard so we have to keep core keyboard mapping
902 - * synchronized with vncKeyboardDevice. Do it via SwitchCoreKeyboard()
903 - *
904 - * 1.6 (aka MPX - Multi pointer X)
905 - * - multiple master devices (= core devices) exists, keep vncKeyboardDevice
906 - * synchronized with proper master device
907 - */
908 -
909 void XserverDesktop::keyEvent(rdr::U32 keysym, bool down)
910 {
911 - DeviceIntPtr master;
912 - KeyClassPtr keyc = vncKeyboardDevice->key;
913 - KeySymsPtr keymap = &keyc->curKeySyms;
914 - unsigned int i, n;
915 - int j, k;
916 -
917 - if (keysym == XK_Caps_Lock) {
918 - vlog.debug("Ignoring caps lock");
919 - return;
920 - }
921 -
922 - // find which modifier Mode_switch is on.
923 - int modeSwitchMapIndex = 0;
924 - for (i = 3; i < 8; i++) {
925 - for (k = 0; k < keyc->maxKeysPerModifier; k++) {
926 - int keycode = keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k];
927 - for (j = 0; j < keymap->mapWidth; j++) {
928 - if (keycode != 0 &&
929 - keymap->map[(keycode - keymap->minKeyCode)
930 - * keymap->mapWidth + j] == XK_Mode_switch)
931 - {
932 - modeSwitchMapIndex = i;
933 - break;
934 - }
935 - }
936 - }
937 - }
938 -
939 - int col = 0;
940 - if (keyc->state & (1<<ShiftMapIndex)) col |= 1;
941 - if (modeSwitchMapIndex && (keyc->state & (1<<modeSwitchMapIndex))) col |= 2;
942 -
943 - int kc = KeysymToKeycode(keymap, keysym, &col);
944 -
945 - // Sort out the "shifted Tab" mess. If we are sent a shifted Tab, generate a
946 - // local shifted Tab regardless of what the "shifted Tab" keysym is on the
947 - // local keyboard (it might be Tab, ISO_Left_Tab or HP's private BackTab
948 - // keysym, and quite possibly some others too). We never get ISO_Left_Tab
949 - // here because it's already been translated in VNCSConnectionST.
950 - if (keysym == XK_Tab && (keyc->state & (1<<ShiftMapIndex)))
951 - col |= 1;
952 -
953 - if (kc == 0) {
954 - // Not a direct match in the local keyboard mapping. Check for alternative
955 - // keysyms with the same meaning.
956 - for (i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {
957 - if (keysym == altKeysym[i].a)
958 - kc = KeysymToKeycode(keymap, altKeysym[i].b, &col);
959 - else if (keysym == altKeysym[i].b)
960 - kc = KeysymToKeycode(keymap, altKeysym[i].a, &col);
961 - if (kc) break;
962 - }
963 - }
964 -
965 - if (kc == 0) {
966 - // Last resort - dynamically add a new key to the keyboard mapping.
967 - for (kc = keymap->maxKeyCode; kc >= keymap->minKeyCode; kc--) {
968 - if (!keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth]) {
969 - keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth] = keysym;
970 - col = 0;
971 -
972 - vlog.info("Added unknown keysym 0x%x to keycode %d",keysym,kc);
973 -
974 -#if XORG == 15
975 - master = inputInfo.keyboard;
976 -#else
977 - master = vncKeyboardDevice->u.master;
978 -#endif
979 - if (vncKeyboardDevice ==
980 - dixLookupPrivate(&master->devPrivates, CoreDevicePrivateKey)) {
981 - dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, NULL);
982 -#if XORG == 15
983 - SwitchCoreKeyboard(vncKeyboardDevice);
984 -#else
985 - CopyKeyClass(vncKeyboardDevice, master);
986 -#endif
987 - }
988 - break;
989 - }
990 - }
991 - if (kc < keymap->minKeyCode) {
992 - vlog.info("Keyboard mapping full - ignoring unknown keysym 0x%x",keysym);
993 - return;
994 - }
995 - }
996 -
997 - // See if it's a modifier key. If so, then don't do any auto-repeat, because
998 - // the X server will translate each press into a release followed by a press.
999 - for (i = 0; i < 8; i++) {
1000 - for (k = 0; k < keyc->maxKeysPerModifier; k++) {
1001 - if (kc == keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k] &&
1002 - IS_PRESSED(keyc,kc) && down)
1003 - return;
1004 - }
1005 - }
1006 -
1007 - ModifierState shift(ShiftMapIndex);
1008 - ModifierState modeSwitch(modeSwitchMapIndex);
1009 - if (down) {
1010 - if (col & 1)
1011 - shift.press();
1012 - else
1013 - shift.release();
1014 - if (modeSwitchMapIndex) {
1015 - if (col & 2)
1016 - modeSwitch.press();
1017 - else
1018 - modeSwitch.release();
1019 - }
1020 - }
1021 - vlog.debug("keycode %d %s", kc, down ? "down" : "up");
1022 - n = GetKeyboardEvents (eventq, vncKeyboardDevice, down ?
1023 - KeyPress : KeyRelease, kc);
1024 - for (i = 0; i < n; i++) {
1025 - mieqEnqueue (vncKeyboardDevice,
1026 -#if XORG == 15
1027 - eventq + i
1028 -#else
1029 - (eventq + i)->event
1030 -#endif
1031 - );
1032 - }
1033 + if (down)
1034 + keyboardDevice->Press(keysym);
1035 + else
1036 + keyboardDevice->Release(keysym);
1037 }
1038 -
1039 -static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col)
1040 -{
1041 - register int per = keymap->mapWidth;
1042 - register KeySym *syms;
1043 - KeySym lsym, usym;
1044 -
1045 - if ((col < 0) || ((col >= per) && (col > 3)) ||
1046 - (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))
1047 - return NoSymbol;
1048 -
1049 - syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
1050 - if (col < 4) {
1051 - if (col > 1) {
1052 - while ((per > 2) && (syms[per - 1] == NoSymbol))
1053 - per--;
1054 - if (per < 3)
1055 - col -= 2;
1056 - }
1057 - if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {
1058 - XConvertCase(syms[col&~1], &lsym, &usym);
1059 - if (!(col & 1))
1060 - return lsym;
1061 - // I'm commenting out this logic because it's incorrect even though it
1062 - // was copied from the Xlib sources. The X protocol book quite clearly
1063 - // states that where a group consists of element 1 being a non-alphabetic
1064 - // keysym and element 2 being NoSymbol that you treat the second element
1065 - // as being the same as the first. This also tallies with the behaviour
1066 - // produced by the installed Xlib on my linux box (I believe this is
1067 - // because it uses some XKB code rather than the original Xlib code -
1068 - // compare XKBBind.c with KeyBind.c in lib/X11).
1069 - // else if (usym == lsym)
1070 - // return NoSymbol;
1071 - else
1072 - return usym;
1073 - }
1074 - }
1075 - return syms[col];
1076 -}
1077 -
1078 -// KeysymToKeycode() - find the keycode and column corresponding to the given
1079 -// keysym. The value of col passed in should be the column determined from the
1080 -// current shift state. If the keysym can be found in that column we prefer
1081 -// that to finding it in a different column (which would require fake events to
1082 -// alter the shift state).
1083 -
1084 -static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col)
1085 -{
1086 - register int i, j;
1087 -
1088 - j = *col;
1089 - for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
1090 - if (KeyCodetoKeySym(keymap, i, j) == ks)
1091 - return i;
1092 - }
1093 -
1094 - for (j = 0; j < keymap->mapWidth; j++) {
1095 - for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {
1096 - if (KeyCodetoKeySym(keymap, i, j) == ks) {
1097 - *col = j;
1098 - return i;
1099 - }
1100 - }
1101 - }
1102 - return 0;
1103 -}
1104 -
1105 -/* Fairly standard US PC Keyboard */
1106 -
1107 -#define VFB_MIN_KEY 8
1108 -#define VFB_MAX_KEY 255
1109 -#define VFB_MAP_LEN (VFB_MAX_KEY - VFB_MIN_KEY + 1)
1110 -#define KEYSYMS_PER_KEY 2
1111 -KeySym keyboardMap[VFB_MAP_LEN * KEYSYMS_PER_KEY] = {
1112 - NoSymbol, NoSymbol,
1113 - XK_Escape, NoSymbol,
1114 - XK_1, XK_exclam,
1115 - XK_2, XK_at,
1116 - XK_3, XK_numbersign,
1117 - XK_4, XK_dollar,
1118 - XK_5, XK_percent,
1119 - XK_6, XK_asciicircum,
1120 - XK_7, XK_ampersand,
1121 - XK_8, XK_asterisk,
1122 - XK_9, XK_parenleft,
1123 - XK_0, XK_parenright,
1124 - XK_minus, XK_underscore,
1125 - XK_equal, XK_plus,
1126 - XK_BackSpace, NoSymbol,
1127 - XK_Tab, NoSymbol,
1128 - XK_q, XK_Q,
1129 - XK_w, XK_W,
1130 - XK_e, XK_E,
1131 - XK_r, XK_R,
1132 - XK_t, XK_T,
1133 - XK_y, XK_Y,
1134 - XK_u, XK_U,
1135 - XK_i, XK_I,
1136 - XK_o, XK_O,
1137 - XK_p, XK_P,
1138 - XK_bracketleft, XK_braceleft,
1139 - XK_bracketright, XK_braceright,
1140 - XK_Return, NoSymbol,
1141 - XK_Control_L, NoSymbol,
1142 - XK_a, XK_A,
1143 - XK_s, XK_S,
1144 - XK_d, XK_D,
1145 - XK_f, XK_F,
1146 - XK_g, XK_G,
1147 - XK_h, XK_H,
1148 - XK_j, XK_J,
1149 - XK_k, XK_K,
1150 - XK_l, XK_L,
1151 - XK_semicolon, XK_colon,
1152 - XK_apostrophe, XK_quotedbl,
1153 - XK_grave, XK_asciitilde,
1154 - XK_Shift_L, NoSymbol,
1155 - XK_backslash, XK_bar,
1156 - XK_z, XK_Z,
1157 - XK_x, XK_X,
1158 - XK_c, XK_C,
1159 - XK_v, XK_V,
1160 - XK_b, XK_B,
1161 - XK_n, XK_N,
1162 - XK_m, XK_M,
1163 - XK_comma, XK_less,
1164 - XK_period, XK_greater,
1165 - XK_slash, XK_question,
1166 - XK_Shift_R, NoSymbol,
1167 - XK_KP_Multiply, NoSymbol,
1168 - XK_Alt_L, XK_Meta_L,
1169 - XK_space, NoSymbol,
1170 - /*XK_Caps_Lock*/ NoSymbol, NoSymbol,
1171 - XK_F1, NoSymbol,
1172 - XK_F2, NoSymbol,
1173 - XK_F3, NoSymbol,
1174 - XK_F4, NoSymbol,
1175 - XK_F5, NoSymbol,
1176 - XK_F6, NoSymbol,
1177 - XK_F7, NoSymbol,
1178 - XK_F8, NoSymbol,
1179 - XK_F9, NoSymbol,
1180 - XK_F10, NoSymbol,
1181 - XK_Num_Lock, XK_Pointer_EnableKeys,
1182 - XK_Scroll_Lock, NoSymbol,
1183 - XK_KP_Home, XK_KP_7,
1184 - XK_KP_Up, XK_KP_8,
1185 - XK_KP_Prior, XK_KP_9,
1186 - XK_KP_Subtract, NoSymbol,
1187 - XK_KP_Left, XK_KP_4,
1188 - XK_KP_Begin, XK_KP_5,
1189 - XK_KP_Right, XK_KP_6,
1190 - XK_KP_Add, NoSymbol,
1191 - XK_KP_End, XK_KP_1,
1192 - XK_KP_Down, XK_KP_2,
1193 - XK_KP_Next, XK_KP_3,
1194 - XK_KP_Insert, XK_KP_0,
1195 - XK_KP_Delete, XK_KP_Decimal,
1196 - NoSymbol, NoSymbol,
1197 - NoSymbol, NoSymbol,
1198 - NoSymbol, NoSymbol,
1199 - XK_F11, NoSymbol,
1200 - XK_F12, NoSymbol,
1201 - XK_Home, NoSymbol,
1202 - XK_Up, NoSymbol,
1203 - XK_Prior, NoSymbol,
1204 - XK_Left, NoSymbol,
1205 - NoSymbol, NoSymbol,
1206 - XK_Right, NoSymbol,
1207 - XK_End, NoSymbol,
1208 - XK_Down, NoSymbol,
1209 - XK_Next, NoSymbol,
1210 - XK_Insert, NoSymbol,
1211 - XK_Delete, NoSymbol,
1212 - XK_KP_Enter, NoSymbol,
1213 - XK_Control_R, NoSymbol,
1214 - XK_Pause, XK_Break,
1215 - XK_Print, XK_Execute,
1216 - XK_KP_Divide, NoSymbol,
1217 - XK_Alt_R, XK_Meta_R,
1218 -};
1219 -
1220 -static Bool GetMappings(KeySymsPtr pKeySyms, CARD8 *pModMap)
1221 -{
1222 - int i;
1223 -
1224 - for (i = 0; i < MAP_LENGTH; i++)
1225 - pModMap[i] = NoSymbol;
1226 -
1227 - for (i = 0; i < VFB_MAP_LEN; i++) {
1228 - if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Caps_Lock)
1229 - pModMap[i + VFB_MIN_KEY] = LockMask;
1230 - else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_L ||
1231 - keyboardMap[i * KEYSYMS_PER_KEY] == XK_Shift_R)
1232 - pModMap[i + VFB_MIN_KEY] = ShiftMask;
1233 - else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_L ||
1234 - keyboardMap[i * KEYSYMS_PER_KEY] == XK_Control_R) {
1235 - pModMap[i + VFB_MIN_KEY] = ControlMask;
1236 - }
1237 - else if (keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_L ||
1238 - keyboardMap[i * KEYSYMS_PER_KEY] == XK_Alt_R)
1239 - pModMap[i + VFB_MIN_KEY] = Mod1Mask;
1240 - }
1241 -
1242 - pKeySyms->minKeyCode = VFB_MIN_KEY;
1243 - pKeySyms->maxKeyCode = VFB_MAX_KEY;
1244 - pKeySyms->mapWidth = KEYSYMS_PER_KEY;
1245 - pKeySyms->map = keyboardMap;
1246 -
1247 - return TRUE;
1248 -}
1249 -
1250 -static void vfbBell(int percent, DeviceIntPtr device, pointer ctrl, int class_)
1251 -{
1252 - if (percent > 0)
1253 - vncBell();
1254 -}
1255 -
1256 -static int vfbKeybdProc(DeviceIntPtr pDevice, int onoff)
1257 -{
1258 - KeySymsRec keySyms;
1259 - CARD8 modMap[MAP_LENGTH];
1260 - DevicePtr pDev = (DevicePtr)pDevice;
1261 -#ifdef XKB
1262 - XkbComponentNamesRec names;
1263 -#endif
1264 -
1265 - switch (onoff)
1266 - {
1267 - case DEVICE_INIT:
1268 - GetMappings(&keySyms, modMap);
1269 -#ifdef XKB
1270 - if (!noXkbExtension) {
1271 - memset(&names, 0, sizeof (names));
1272 - XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
1273 - XkbInitKeyboardDeviceStruct(pDevice, &names, &keySyms, modMap,
1274 - (BellProcPtr)vfbBell,
1275 - (KbdCtrlProcPtr)NoopDDA);
1276 - } else
1277 -#endif
1278 - {
1279 - InitKeyboardDeviceStruct(pDev, &keySyms, modMap,
1280 - (BellProcPtr)vfbBell, (KbdCtrlProcPtr)NoopDDA);
1281 - }
1282 - break;
1283 - case DEVICE_ON:
1284 - pDev->on = TRUE;
1285 - break;
1286 - case DEVICE_OFF:
1287 - pDev->on = FALSE;
1288 - break;
1289 - case DEVICE_CLOSE:
1290 - break;
1291 - }
1292 - return Success;
1293 -}
1294 -
1295 Index: unix/xserver/hw/vnc/XserverDesktop.h
1296 ===================================================================
1297 --- unix/xserver/hw/vnc/XserverDesktop.h (revision 3886)
1298 +++ unix/xserver/hw/vnc/XserverDesktop.h (revision 3887)
1299 @@ -123,6 +123,7 @@
1300 void deferUpdate();
1301 ScreenPtr pScreen;
1302 PointerDevice *pointerDevice;
1303 + KeyboardDevice *keyboardDevice;
1304 OsTimerPtr deferredUpdateTimer, dummyTimer;
1305 rfb::VNCServerST* server;
1306 rfb::HTTPServer* httpServer;