Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1201 - (hide annotations) (download)
Mon Nov 22 23:25:59 2010 UTC (13 years, 6 months ago) by niro
File size: 35721 byte(s)
-patches for 1.0.1 against xorg-server-1.7
1 niro 1201 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;