Commit 9f702139 authored by Reinhard Tartler's avatar Reinhard Tartler

Imported nxcompshad-3.2.0-3.tar.gz

Summary: Imported nxcompshad-3.2.0-3.tar.gz Keywords: Imported nxcompshad-3.2.0-3.tar.gz into Git repository
parent c7dc0c3c
ChangeLog:
nxcompshad-3.2.0-3
- Improved keycode translation.
nxcompshad-3.2.0-2
- Solved a problem when sending fake modifier events.
- Added support for keyboard events handling for the web player.
- Changed keycodes translation for Solaris keyboard.
- Corrected a problem for keycodes translation from Solaris keyboard.
- Fixed TR02F02001. In shadow session the shadower's keyboard layout
could be wrong. Now keycodes are correctly translated if master and
shadow keyboards have different layouts.
- Added NXShadowGetScreenSize() and NXShadowSetScreenSize() functions,
so that the shadow session can handle correctly the resize of the
master session window.
- Solved a compilation problem on GCC 4.3.
nxcompshad-3.2.0-1
- Opened the 3.2.0 branch based on nxcompshad-3.1.0-2.
......
......@@ -538,6 +538,15 @@ void CorePoller::update(char *src, XRectangle r)
for (unsigned int i = 0; i < r.height; i++)
{
if(((r.x * bpp_ + r.y * bpl_) + bpl) > (bpl_ * height_))
{
//
// Out of bounds. Maybe a resize is going on.
//
continue;
}
memcpy(dst, src, bpl);
src += bpl;
......@@ -574,6 +583,13 @@ void CorePoller::handleEvent(Display *display, XEvent *event)
}
}
void CorePoller::handleWebKeyEvent(KeySym keysym, Bool isKeyPress)
{
logTrace("CorePoller::handleWebKeyEvent");
handleWebKeyboardEvent(keysym, isKeyPress);
}
void CorePoller::handleInput()
{
while (input_ -> checkIfEvent())
......
......@@ -68,6 +68,8 @@ class CorePoller
void handleEvent(Display *, XEvent *);
void handleWebKeyEvent(KeySym keysym, Bool isKeyPress);
Display *getShadowDisplay();
void setShadowDisplay(Display *shadowDisplay);
......@@ -115,6 +117,8 @@ class CorePoller
virtual void handleKeyboardEvent(Display *, XEvent *) = 0;
virtual void handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress) = 0;
virtual void handleMouseEvent(Display *, XEvent *) = 0;
Input *input_;
......
......@@ -18,11 +18,13 @@
#ifndef Misc_H
#define Misc_H
#include <iostream.h>
#include <iostream>
#include <errno.h>
#include <string.h>
using namespace std;
//
// Error handling macros.
//
......
......@@ -28,6 +28,15 @@
#include "Poller.h"
#include "Manager.h"
typedef struct {
KeySym *map;
KeyCode minKeyCode,
maxKeyCode;
int mapWidth;
} KeySymsRec, *KeySymsPtr;
KeySymsPtr NXShadowKeymap = NULL;
ShadowOptions NXShadowOptions = {1, 1, -1};
static int mirrorException = 0;
......@@ -295,6 +304,16 @@ void NXShadowDisableDamage(void)
NXShadowOptions.optionDamageExtension = 0;
}
void NXShadowGetScreenSize(int *w, int *h)
{
poller -> getScreenSize(w, h);
}
void NXShadowSetScreenSize(int *w, int *h)
{
poller -> setScreenSize(w, h);
}
#endif
void NXShadowDestroy()
......@@ -406,6 +425,11 @@ void NXShadowEvent(Display *display, XEvent event)
poller -> handleEvent(display, &event);
}
void NXShadowWebKeyEvent(KeySym keysym, Bool isKeyPress)
{
poller -> handleWebKeyEvent(keysym, isKeyPress);
}
#ifdef __CYGWIN32__
int NXShadowCaptureCursor(unsigned int wnd, void *vis)
......@@ -437,3 +461,11 @@ void NXShadowUpdateBuffer(void **buffer)
logTest("NXShadowUpdateBuffer","New frame buffer [0x%p]", (void *)*fBuffer);
}
void NXShadowInitKeymap(void *keysyms)
{
NXShadowKeymap = (KeySymsPtr) keysyms;
logTest("NXShadowInitKeymap","KeySyms pointer [0x%p] mapWidth [%d]",
(void *)NXShadowKeymap, NXShadowKeymap -> mapWidth);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com. */
/* */
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of Medialogic S.p.A. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include <signal.h>
#include <string.h>
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#include "Logger.h"
#include "Shadow.h"
#include "Poller.h"
#include "Manager.h"
typedef struct {
KeySym *map;
KeyCode minKeyCode,
maxKeyCode;
int mapWidth;
} KeySymsRec, *KeySymsPtr;
KeySymsPtr NXShadowKeymap = NULL;
ShadowOptions NXShadowOptions = {1, 1, -1};
static int mirrorException = 0;
static UpdateManager *updateManager;
static Poller *poller;
static Input *input;
int NXShadowRemoveAllUpdaters();
inline bool NXShadowNotInitialized()
{
//
// updateManager depends on input and poller.
// So this test seem redundant.
//
// return (input == NULL) || (poller == NULL) || (updateManager == NULL);
//
return (updateManager == NULL);
}
#ifdef NEED_SIGNAL_HANDLER
static void NXSignalHandler(int signal)
{
logTest("NXSignalHandler", "Got signal [%d]", signal);
if (signal == SIGINT)
{
mirrorException = 1;
}
else if (signal == SIGTERM)
{
mirrorException = 1;
}
}
static int NXInitSignal()
{
logTrace("NXInitSignal");
struct sigaction sa;
sa.sa_handler = NXSignalHandler;
sigfillset(&sa.sa_mask);
sa.sa_flags = 0;
int res;
while ((res = sigaction(SIGINT, &sa, NULL)) == -1 &&
errno == EINTR);
if (res == -1)
{
logError("NXInitSignal", EGET());
return -1;
}
return 1;
}
#endif
static void NXHandleException()
{
if (mirrorException)
{
mirrorException = 0;
NXShadowRemoveAllUpdaters();
}
}
static int NXCreateInput(char *keymap, char *shadowDisplayName)
{
logTrace("NXCreateInput");
input = new Input;
if (input == NULL)
{
logError("NXCreateInput", ESET(ENOMEM));
return -1;
}
input -> setKeymap(keymap);
input -> setShadowDisplayName(shadowDisplayName);
return 1;
}
static int NXCreatePoller(Display *display, Display **shadowDisplay)
{
logTrace("NXCreatePoller");
if (input == NULL)
{
logError("NXCreatePoller", ESET(EBADFD));
return -1;
}
poller = new Poller(input,display);
if (poller == NULL)
{
logError("NXCreatePoller", ESET(ENOMEM));
return -1;
}
if (poller -> init() == -1)
{
logTest("NXCreatePoller", "Failed to initialize poller.");
return -1;
}
*shadowDisplay = poller -> getShadowDisplay();
logTest("NXCreatePoller", "Poller geometry [%d, %d], ShadowDisplay[%p].", poller -> width(),
poller -> height(), (Display *) *shadowDisplay);
return 1;
}
static int NXCreateUpdateManager()
{
logTrace("NXCreateUpdateManager");
if (input == NULL || poller == NULL)
{
logError("NXCreateUpdateManager", ESET(EBADFD));
return -1;
}
updateManager = new UpdateManager(poller -> width(), poller -> height(),
poller -> getFrameBuffer(), input);
if (updateManager == NULL)
{
logError("NXCreateUpdateManager", ESET(ENOMEM));
return -1;
}
return 1;
}
void NXShadowResetOptions()
{
NXShadowOptions.optionShmExtension = 1;
NXShadowOptions.optionDamageExtension = 1;
}
//
// Exported functions.
//
int NXShadowHasUpdaters()
{
logTrace("NXShadowHasUpdaters");
return (updateManager && updateManager -> numberOfUpdaters()) ? 1 : 0;
}
int NXShadowRemoveAllUpdaters()
{
logTrace("NXShadowRemoveAllUpdaters");
return updateManager ? updateManager -> removeAllUpdaters() : 0;
}
int NXShadowRemoveUpdater(UpdaterHandle handle)
{
logTrace("NXShadowRemoveUpdater");
return updateManager ? updateManager -> removeUpdater(handle) : 0;
}
UpdaterHandle NXShadowAddUpdater(char *displayName)
{
logTrace("NXShadowAddUpdater");
return updateManager ? updateManager -> addUpdater(displayName, NULL) : NULL;
}
int NXShadowAddUpdaterDisplay(void *dpy, int *w, int *h, unsigned char *d)
{
Display *display = reinterpret_cast<Display*>(dpy);
logTrace("NXShadowAddUpdaterDisplay");
if ((updateManager ? updateManager -> addUpdater(NULL, display) : NULL) == NULL)
{
logTest("NXShadowAddUpdaterDisplay", "Error");
return 0;
}
*w = updateManager -> getWidth();
*h = updateManager -> getHeight();
*d = poller -> depth();
return 1;
}
int NXShadowCreate(void *dpy, char *keymap, char* shadowDisplayName, void **shadowDpy)
{
logTrace("NXShadowCreate");
Display *display = reinterpret_cast<Display*>(dpy);
Display **shadowDisplay = reinterpret_cast<Display**>(shadowDpy);
/* if (NXInitSignal() != 1)
{
logError("NXShadowCreate", EGET());
return -1;
}*/
if (NXCreateInput(keymap, shadowDisplayName) != 1)
{
logError("NXShadowCreate", EGET());
return -1;
}
if (NXCreatePoller(display, shadowDisplay) != 1)
{
logTest("NXShadowCreate", "NXCreatePoller failed.");
return -1;
}
if (NXCreateUpdateManager() != 1)
{
logError("NXShadowCreate", EGET());
return -1;
}
return 1;
}
#if !defined(__CYGWIN32__) && !defined(WIN32)
void NXShadowSetDisplayUid(int uid)
{
NXShadowOptions.optionShadowDisplayUid = uid;
}
void NXShadowDisableShm(void)
{
logUser("NXShadowDisableShm: Disabling SHM.\n");
NXShadowOptions.optionShmExtension = 0;
}
void NXShadowDisableDamage(void)
{
NXShadowOptions.optionDamageExtension = 0;
}
#endif
void NXShadowDestroy()
{
if (poller)
{
delete poller;
poller = NULL;
}
if (updateManager)
{
delete updateManager;
updateManager = NULL;
}
if (input)
{
delete input;
input = NULL;
}
}
void NXShadowHandleInput()
{
logTrace("NXShadowHandleInput");
if (NXShadowNotInitialized())
{
logError("NXShadowHandleInput - NXShadow not properly initialized.", ESET(EBADFD));
return;
}
NXHandleException();
updateManager -> handleInput();
poller -> handleInput();
}
int NXShadowHasChanged(int (*callback)(void *), void *arg, int *suspended)
{
int result;
logTrace("NXShadowHasChanged");
if (NXShadowNotInitialized())
{
logError("NXShadowHasChanged - NXShadow not properly initialized.", ESET(EBADFD));
return -1;
}
//
// FIXME
//updateManager -> destroyUpdateManagerRegion();
//
updateManager -> newRegion();
#if !defined(__CYGWIN32__) && !defined(WIN32)
poller -> getEvents();
#endif
result = poller -> isChanged(callback, arg, suspended);
if (result == 1)
{
updateManager -> addRegion(poller -> lastUpdatedRegion());
return 1;
}
else if (result == -1)
{
logTest("NXShadowHasChanged", "Scanline error.");
return -1;
}
return 0;
}
void NXShadowExportChanges(long *numRects, char **pBox)
{
Region pReg;
logTrace("NXShadowExportChanges");
if (NXShadowNotInitialized())
{
logError("NXShadowExportChanges - NXShadow not properly initialized.", ESET(EBADFD));
}
updateManager -> update();
pReg = updateManager -> getUpdateManagerRegion();
*numRects = pReg -> numRects;
*pBox = (char *)pReg -> rects;
logTest("NXShadowExportChanges", "numRects [%ld] pBox[%p], pReg->numRects[%ld], rects[%p], size[%lu]",
*numRects, *pBox, pReg -> numRects, &(pReg -> rects -> x2),
(unsigned long) sizeof(pReg -> rects -> x2));
}
void NXShadowEvent(Display *display, XEvent event)
{
poller -> handleEvent(display, &event);
}
void NXShadowWebKeyEvent(KeySym keysym, Bool isKeyPress)
{
poller -> handleWebKeyEvent(keysym, isKeyPress);
}
#ifdef __CYGWIN32__
int NXShadowCaptureCursor(unsigned int wnd, void *vis)
{
Window window = (Window)wnd;
Visual *visual = reinterpret_cast<Visual*>(vis);
logTrace("NXShadowCaptureCursor");
logTest("NXShadowCaptureCursor","Init");
return poller -> updateCursor(window, visual);
}
#endif
void NXShadowUpdateBuffer(void **buffer)
{
char **fBuffer = reinterpret_cast<char **>(buffer);
if (*fBuffer != NULL)
{
poller -> destroyFrameBuffer();
poller -> init();
}
*fBuffer = poller -> getFrameBuffer();
logTest("NXShadowUpdateBuffer","New frame buffer [0x%p]", (void *)*fBuffer);
}
void NXShadowInitKeymap(void *keysyms)
{
NXShadowKeymap = (KeySymsPtr) keysyms;
logTest("NXShadowInitKeymap","KeySyms pointer [0x%p] mapWidth [%d]",
(void *)NXShadowKeymap, NXShadowKeymap -> mapWidth);
}
......@@ -81,12 +81,18 @@ extern void NXShadowColorCorrect(int, int, unsigned int, unsigned int,
extern void NXShadowUpdateBuffer(void **);
extern void NXShadowEvent(Display *, XEvent);
extern void NXShadowWebKeyEvent(KeySym keysym, Bool isKeyPress);
extern void NXShadowSetDisplayUid(int uid);
extern void NXShadowDisableShm(void);
extern void NXShadowDisableDamage(void);
extern void NXShadowGetScreenSize(int *width, int *height);
extern void NXShadowSetScreenSize(int *width, int *height);
extern void NXShadowInitKeymap(void *keysyms);
#ifdef __cplusplus
}
#endif
......
......@@ -479,6 +479,13 @@ void Poller::handleKeyboardEvent(Display *display, XEvent *event)
delete[] keyname;
}
void Poller::handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress)
{
/*
FIXME
*/
}
void Poller::handleMouseEvent(Display *display, XEvent *event)
{
DWORD flg = 0;
......
......@@ -72,6 +72,7 @@ class Poller : public CorePoller
int Poller::updateShadowFrameBuffer(void);
void handleKeyboardEvent(Display *, XEvent *);
void handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress);
void addToKeymap(char *keyname, unsigned char scancode, unsigned short modifiers, char *mapname);
int xkeymapRead(char *mapname);
FILE *xkeymapOpen(char *filename);
......
......@@ -35,7 +35,49 @@
#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
#define TRANSLATE_KEYCODES
#undef TRANSLATE_KEYCODES
#define TRANSLATE_ALWAYS
typedef struct {
KeySym *map;
KeyCode minKeyCode,
maxKeyCode;
int mapWidth;
} KeySymsRec, *KeySymsPtr;
extern KeySymsPtr NXShadowKeymap;
typedef struct _KeyPressed
{
KeyCode keyRcvd;
KeyCode keySent;
struct _KeyPressed *next;
} KeyPressedRec;
static KeyPressedRec *shadowKeyPressedPtr = NULL;
static KeySym *shadowKeysyms = NULL;
static KeySym *masterKeysyms = NULL;
static int shadowMinKey, shadowMaxKey, shadowMapWidth;
static int masterMinKey, masterMaxKey, masterMapWidth;
static int leftShiftOn = 0;
static int rightShiftOn = 0;
static int modeSwitchOn = 0;
static int level3ShiftOn = 0;
static int altROn = 0;
static int sentFakeLShiftPress = 0;
static int sentFakeLShiftRelease = 0;
static int sentFakeRShiftRelease = 0;
static int sentFakeModeSwitchPress = 0;
static int sentFakeModeSwitchRelease = 0;
static int sentFakeLevel3ShiftPress = 0;
static int sentFakeLevel3ShiftRelease = 0;
static int sentFakeAltRRelease = 0;
static int shmInitTrap = 0;
Poller::Poller(Input *input, Display *display, int depth) : CorePoller(input, display)
{
......@@ -226,7 +268,10 @@ void Poller::shmInit(void)
{
logDebug("Poller::shmInit", "Called with shared memory already initialized.");
return;
if (shmInitTrap == 0)
{
return;
}
}
if (shmExtension_ < 0 && NXShadowOptions.optionShmExtension == 0)
......@@ -362,6 +407,520 @@ void Poller::shmInit(void)
}
}
void Poller::keymapShadowInit(Display *display)
{
if (NXShadowKeymap)
{
shadowMinKey = NXShadowKeymap -> minKeyCode;
shadowMaxKey = NXShadowKeymap -> maxKeyCode;
shadowMapWidth = NXShadowKeymap -> mapWidth;
shadowKeysyms = NXShadowKeymap -> map;
}
if (shadowKeysyms == NULL)
{
XDisplayKeycodes(display, &shadowMinKey, &shadowMaxKey);
shadowKeysyms = XGetKeyboardMapping(display, shadowMinKey, shadowMaxKey - shadowMinKey + 1,
&shadowMapWidth);
}
#ifdef DEBUG
if (shadowKeysyms)
{
for (int i = 0; i < (shadowMaxKey - shadowMinKey) * shadowMapWidth; i++)
{
logDebug("Poller::keymapShadowInit", "keycode %d - keysym %x %s",
(int)(i / shadowMapWidth), (unsigned int)shadowKeysyms[i],
XKeysymToString(shadowKeysyms[i]));
}
}
#endif
}
void Poller::keymapMasterInit()
{
XDisplayKeycodes(display_, &masterMinKey, &masterMaxKey);
masterKeysyms = XGetKeyboardMapping(display_, masterMinKey, masterMaxKey - masterMinKey + 1,
&masterMapWidth);
#ifdef DEBUG
if (masterKeysyms)
{
for (int i = 0; i < (masterMaxKey - masterMinKey) * masterMapWidth; i++)
{
logDebug("Poller::keymapMasterInit", "keycode %d - keysym %x %s",
(int)(i / masterMapWidth), (unsigned int)masterKeysyms[i],
XKeysymToString(masterKeysyms[i]));
}
}
#endif
}
KeySym Poller::keymapKeycodeToKeysym(KeyCode keycode, KeySym *keysyms,
int minKey, int mapWidth, int col)
{
int index = ((keycode - minKey) * mapWidth) + col;
return keysyms[index];
}
KeyCode Poller::keymapKeysymToKeycode(KeySym keysym, KeySym *keysyms,
int minKey, int maxKey, int mapWidth, int *col)
{
for (int i = 0; i < (maxKey - minKey + 1) * mapWidth; i++)
{
if (keysyms[i] == keysym)
{
*col = i % mapWidth;
return i / mapWidth + minKey;
}
}
return 0;
}
KeyCode Poller::translateKeysymToKeycode(KeySym keysym, int *col)
{
KeyCode keycode;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
if (keycode == 0)
{
if (((keysym >> 8) == 0) && (keysym >= XK_a) && (keysym <= XK_z))
{
/*
* The master session has a Solaris keyboard.
*/
keysym -= XK_a - XK_A;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
}
else if (keysym == XK_Shift_R)
{
keysym = XK_Shift_L;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
}
else if (keysym == XK_Shift_L)
{
keysym = XK_Shift_R;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
}
else if (keysym == XK_ISO_Level3_Shift)
{
keysym = XK_Mode_switch;
if ((keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col)) == 0)
{
keysym = XK_Alt_R;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
}
}
else if (keysym == XK_Alt_R)
{
keysym = XK_ISO_Level3_Shift;
if ((keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col)) == 0)
{
keysym = XK_Mode_switch;
keycode = keymapKeysymToKeycode(keysym, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, col);
}
}
}
return keycode;
}
Bool Poller::checkModifierKeys(KeySym keysym, Bool isKeyPress)
{
switch (keysym)
{
case XK_Shift_L:
leftShiftOn = isKeyPress;
return True;
case XK_Shift_R:
rightShiftOn = isKeyPress;
return True;
case XK_Mode_switch:
modeSwitchOn = isKeyPress;
return True;
case XK_ISO_Level3_Shift:
level3ShiftOn = isKeyPress;
return True;
case XK_Alt_R:
altROn = isKeyPress;
return True;
default:
return False;
}
}
void Poller::sendFakeModifierEvents(int pos, Bool skip)
{
KeySym fakeKeysym;
int col;
if ((!leftShiftOn && !rightShiftOn) &&
(!modeSwitchOn && !level3ShiftOn && !altROn))
{
if (pos == 1 || pos == 3)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeLShiftPress = 1;
}
if (pos == 2 || pos == 3)
{
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
if (fakeKeysym == 0)
{
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
sentFakeModeSwitchPress = 1;
}
else
{
sentFakeLevel3ShiftPress = 1;
}
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
}
}
else if ((leftShiftOn || rightShiftOn) &&
(!modeSwitchOn && !level3ShiftOn && !altROn))
{
if ((pos == 0 && !skip) || pos == 2)
{
if (leftShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLShiftRelease = 1;
}
if (rightShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeRShiftRelease = 1;
}
}
if (pos == 2 || pos ==3)
{
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
if (fakeKeysym == 0)
{
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
sentFakeModeSwitchPress = 1;
}
else
{
sentFakeLevel3ShiftPress = 1;
}
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
}
}
else if ((!leftShiftOn && !rightShiftOn) &&
(modeSwitchOn || level3ShiftOn || altROn))
{
if (pos == 1 || pos == 3)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeLShiftPress = 1;
}
if (pos == 0 || pos == 1)
{
if (modeSwitchOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeModeSwitchRelease = 1;
}
if (level3ShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLevel3ShiftRelease = 1;
}
if (altROn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Alt_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeAltRRelease = 1;
}
}
}
else if ((leftShiftOn || rightShiftOn) &&
(modeSwitchOn || level3ShiftOn || altROn))
{
if (pos == 0 || pos == 2)
{
if (leftShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLShiftRelease = 1;
}
if (rightShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Shift_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeRShiftRelease = 1;
}
}
if (pos == 0 || pos == 1)
{
if (modeSwitchOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeModeSwitchRelease = 1;
}
if (level3ShiftOn)
{
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLevel3ShiftRelease = 1;
}
if (altROn)
{
fakeKeysym = keymapKeysymToKeycode(XK_Alt_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeAltRRelease = 1;
}
}
}
}
void Poller::cancelFakeModifierEvents()
{
KeySym fakeKeysym;
int col;
if (sentFakeLShiftPress)
{
logTest("Poller::handleKeyboardEvent", "Fake Shift_L key press event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake Shift_L key release event");
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLShiftPress = 0;
}
if (sentFakeLShiftRelease)
{
logTest("Poller::handleKeyboardEvent", "Fake Shift_L key release event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake Shift_L key press event");
fakeKeysym = keymapKeysymToKeycode(XK_Shift_L, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeLShiftRelease = 0;
}
if (sentFakeRShiftRelease)
{
logTest("Poller::handleKeyboardEvent", "Fake Shift_R key release event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake Shift_R key press event");
fakeKeysym = keymapKeysymToKeycode(XK_Shift_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeRShiftRelease = 0;
}
if (sentFakeModeSwitchPress)
{
logTest("Poller::handleKeyboardEvent", "Fake Mode_switch key press event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake Mode_switch key release event");
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeModeSwitchPress = 0;
}
if (sentFakeModeSwitchRelease)
{
logTest("Poller::handleKeyboardEvent", "Fake Mode_switch key release event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending Mode_switch key press event");
fakeKeysym = keymapKeysymToKeycode(XK_Mode_switch, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeModeSwitchRelease = 0;
}
if (sentFakeLevel3ShiftPress)
{
logTest("Poller::handleKeyboardEvent", "Fake ISO_Level3_Shift key press event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake ISO_Level3_Shift key release event");
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 0, 0);
sentFakeLevel3ShiftPress = 0;
}
if (sentFakeLevel3ShiftRelease)
{
logTest("Poller::handleKeyboardEvent", "Fake ISO_Level3_Shift key release event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake ISO_Level3_Shift key press event");
fakeKeysym = keymapKeysymToKeycode(XK_ISO_Level3_Shift, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeLevel3ShiftRelease = 0;
}
if (sentFakeAltRRelease)
{
logTest("Poller::handleKeyboardEvent", "Fake XK_Alt_R key release event has been sent");
logTest("Poller::handleKeyboardEvent", "Sending fake XK_Alt_R key press event");
fakeKeysym = keymapKeysymToKeycode(XK_Alt_R, masterKeysyms, masterMinKey,
masterMaxKey, masterMapWidth, &col);
XTestFakeKeyEvent(display_, fakeKeysym, 1, 0);
sentFakeAltRRelease = 0;
}
}
Bool Poller::keyIsDown(KeyCode keycode)
{
KeyPressedRec *downKey;
downKey = shadowKeyPressedPtr;
while (downKey)
{
if (downKey -> keyRcvd == keycode)
{
return True;
}
downKey = downKey -> next;
}
return False;
}
void Poller::addKeyPressed(KeyCode received, KeyCode sent)
{
KeyPressedRec *downKey;
if (!keyIsDown(received))
{
if (shadowKeyPressedPtr == NULL)
{
shadowKeyPressedPtr = (KeyPressedRec *) malloc(sizeof(KeyPressedRec));
shadowKeyPressedPtr -> keyRcvd = received;
shadowKeyPressedPtr -> keySent = sent;
shadowKeyPressedPtr -> next = NULL;
}
else
{
downKey = shadowKeyPressedPtr;
while (downKey -> next != NULL)
{
downKey = downKey -> next;
}
downKey -> next = (KeyPressedRec *) malloc(sizeof(KeyPressedRec));
downKey -> next -> keyRcvd = received;
downKey -> next -> keySent = sent;
downKey -> next -> next = NULL;
}
}
}
KeyCode Poller::getKeyPressed(KeyCode received)
{
KeyCode sent;
KeyPressedRec *downKey;
KeyPressedRec *tempKey;
if (shadowKeyPressedPtr != NULL)
{
if (shadowKeyPressedPtr -> keyRcvd == received)
{
sent = shadowKeyPressedPtr -> keySent;
tempKey = shadowKeyPressedPtr;
shadowKeyPressedPtr = shadowKeyPressedPtr -> next;
free(tempKey);
return sent;
}
else
{
downKey = shadowKeyPressedPtr;
while (downKey -> next != NULL)
{
if (downKey -> next -> keyRcvd == received)
{
sent = downKey -> next -> keySent;
tempKey = downKey -> next;
downKey -> next = downKey -> next -> next;
free(tempKey);
return sent;
}
else
{
downKey = downKey -> next;
}
}
}
}
return 0;
}
void Poller::handleKeyboardEvent(Display *display, XEvent *event)
{
if (xtestExtension_ == 0 || display_ == 0)
......@@ -371,6 +930,158 @@ void Poller::handleKeyboardEvent(Display *display, XEvent *event)
logTest("Poller::handleKeyboardEvent", "Handling event at [%p]", event);
#ifdef TRANSLATE_ALWAYS
KeyCode keycode;
KeySym keysym;
int col = 0;
Bool isKeyPress = False;
Bool isModifier = False;
Bool skip = False;
if (event -> type == KeyPress)
{
isKeyPress = True;
}
if (shadowKeysyms == NULL)
{
keymapShadowInit(event -> xkey.display);
}
if (masterKeysyms == NULL)
{
keymapMasterInit();
}
if (shadowKeysyms == NULL || masterKeysyms == NULL)
{
logTest("Poller::handleKeyboardEvent", "Unable to initialize keymaps. Do not translate");
keycode = event -> xkey.keycode;
goto SendKeycode;
}
keysym = keymapKeycodeToKeysym(event -> xkey.keycode, shadowKeysyms,
shadowMinKey, shadowMapWidth, 0);
isModifier = checkModifierKeys(keysym, isKeyPress);
if (event -> type == KeyRelease)
{
KeyCode keycodeToSend;
keycodeToSend = getKeyPressed(event -> xkey.keycode);
if (keycodeToSend)
{
keycode = keycodeToSend;
goto SendKeycode;
}
}
/*
* Convert case for Solaris keyboard.
*/
if (((keysym >> 8) == 0) && (keysym >= XK_A) && (keysym <= XK_Z))
{
if (!leftShiftOn && !rightShiftOn)
{
keysym += XK_a - XK_A;
}
else
{
skip = True;
}
}
if (!isModifier)
{
if ((leftShiftOn || rightShiftOn) &&
(!modeSwitchOn && !level3ShiftOn && !altROn) &&
!skip)
{
keysym = keymapKeycodeToKeysym(event -> xkey.keycode, shadowKeysyms,
shadowMinKey, shadowMapWidth, 1);
}
if ((!leftShiftOn && !rightShiftOn) &&
(modeSwitchOn || level3ShiftOn || altROn))
{
keysym = keymapKeycodeToKeysym(event -> xkey.keycode, shadowKeysyms,
shadowMinKey, shadowMapWidth, 2);
}
if ((leftShiftOn || rightShiftOn) &&
(modeSwitchOn || level3ShiftOn || altROn))
{
keysym = keymapKeycodeToKeysym(event -> xkey.keycode, shadowKeysyms,
shadowMinKey, shadowMapWidth, 3);
}
}
if (keysym == 0)
{
logTest("Poller::handleKeyboardEvent", "Null keysym. Return");
return;
}
logTest("Poller::handleKeyboardEvent", "keysym [%x] [%s]",
(unsigned int)keysym, XKeysymToString(keysym));
if (keysym == XK_Mode_switch)
{
keysym = XK_ISO_Level3_Shift;
}
keycode = translateKeysymToKeycode(keysym, &col);
if (keycode == 0)
{
logTest("Poller::handleKeyboardEvent", "No keycode found for keysym [%x] [%s]. Return",
(unsigned int)keysym, XKeysymToString(keysym));
return;
}
logTest("Poller::handleKeyboardEvent", "keycode [%d] translated into keycode [%d]",
(int)event -> xkey.keycode, (unsigned int)keycode);
if (event -> type == KeyPress)
{
addKeyPressed(event -> xkey.keycode, keycode);
}
/*
* Send fake modifier events.
*/
if (!isModifier)
{
sendFakeModifierEvents(col, ((keysym >> 8) == 0) && (keysym >= XK_A) && (keysym <= XK_Z));
}
SendKeycode:
/*
* Send the event.
*/
XTestFakeKeyEvent(display_, keycode, isKeyPress, 0);
/*
* Check if fake modifier events have been sent.
*/
cancelFakeModifierEvents();
#else // TRANSLATE_ALWAYS
//
// Use keysyms to translate keycodes across different
// keyboard models. Unuseful when both keyboards have
......@@ -417,6 +1128,60 @@ void Poller::handleKeyboardEvent(Display *display, XEvent *event)
{
XTestFakeKeyEvent(display_, event -> xkey.keycode, 0, 0);
}
#endif // TRANSLATE_ALWAYS
}
void Poller::handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress)
{
KeyCode keycode;
int col;
if (masterKeysyms == NULL)
{
keymapMasterInit();
}
if (masterKeysyms == NULL)
{
logTest("Poller::handleWebKeyboardEvent", "Unable to initialize keymap");
return;
}
keycode = translateKeysymToKeycode(keysym, &col);
if (keycode == 0)
{
logTest("Poller::handleKeyboardEvent", "No keycode found for keysym [%x] [%s]. Return",
(unsigned int)keysym, XKeysymToString(keysym));
return;
}
logTest("Poller::handleKeyboardEvent", "keysym [%x] [%s] translated into keycode [%x]",
(unsigned int)keysym, XKeysymToString(keysym), (unsigned int)keycode);
/*
* Send fake modifier events.
*/
if (!checkModifierKeys(keysym, isKeyPress))
{
sendFakeModifierEvents(col, False);
}
/*
* Send the event.
*/
XTestFakeKeyEvent(display_, keycode, isKeyPress, 0);
/*
* Check if fake modifier events have been sent.
*/
cancelFakeModifierEvents();
}
void Poller::handleMouseEvent(Display *display, XEvent *event)
......@@ -712,6 +1477,26 @@ void Poller::updateDamagedAreas(void)
return;
}
void Poller::getScreenSize(int *w, int *h)
{
*w = WidthOfScreen(DefaultScreenOfDisplay(display_));
*h = HeightOfScreen(DefaultScreenOfDisplay(display_));
}
void Poller::setScreenSize(int *w, int *h)
{
setRootSize();
shmInitTrap = 1;
shmInit();
shmInitTrap = 0;
*w = width_;
*h = height_;
logDebug("Poller::setScreenSize", "New size of screen [%d, %d]", width_, height_);
}
int anyEventPredicate(Display *display, XEvent *event, XPointer parameter)
{
return 1;
......
......@@ -41,6 +41,10 @@ class Poller : public CorePoller
void getEvents(void);
void getScreenSize(int *width, int *height);
void setScreenSize(int *width, int *height);
private:
Display *display_;
......@@ -77,8 +81,34 @@ class Poller : public CorePoller
char *getRect(XRectangle);
void keymapShadowInit(Display *display);
void keymapMasterInit();
KeySym keymapKeycodeToKeysym(KeyCode keycode, KeySym *keysyms,
int minKey, int per, int col);
KeyCode keymapKeysymToKeycode(KeySym keysym, KeySym *keysyms,
int minKey, int maxKey, int per, int *col);
KeyCode translateKeysymToKeycode(KeySym keysym, int *col);
Bool checkModifierKeys(KeySym keysym, Bool isKeyPress);
void sendFakeModifierEvents(int pos, Bool skip);
void cancelFakeModifierEvents();
Bool keyIsDown(KeyCode keycode);
void addKeyPressed(KeyCode received, KeyCode sent);
KeyCode getKeyPressed(KeyCode received);
void handleKeyboardEvent(Display *display, XEvent *);
void handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress);
void handleMouseEvent(Display *, XEvent *);
void xtestInit(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment