Commit d9e2822f authored by Mike Gabriel's avatar Mike Gabriel

nxcompshad: Drop Cygwin/Win32 support. Has been untested and unused for a long time.

This code can be reactivated any time in the future once some potential maintainer turns up and makes this work on the MS Windows / Cygwin platform.
parent bc66da71
......@@ -201,14 +201,6 @@ int CorePoller::isChanged(int (*checkIfInputCallback)(void *), void *arg, int *s
{
logTrace("CorePoller::isChanged");
#if defined(__CYGWIN32__) || defined(WIN32)
checkDesktop();
#endif
#if !defined(__CYGWIN32__) && !defined(WIN32)
if (mirror_ == 1)
{
int result = mirrorChanges_;
......@@ -218,8 +210,6 @@ int CorePoller::isChanged(int (*checkIfInputCallback)(void *), void *arg, int *s
return result;
}
#endif
logDebug("CorePoller:isChanged", "Going to use default polling algorithm.\n");
//
......
......@@ -111,10 +111,6 @@ class CorePoller
int imageByteOrder_;
#ifdef __CYGWIN32__
virtual char checkDesktop(void) = 0;
#endif
Display *shadowDisplay_;
void update(char *src, XRectangle r);
......
......@@ -9,7 +9,6 @@ libXcompshad_la_SOURCES = \
Manager.cpp \
Shadow.cpp \
Updater.cpp \
Win.cpp \
X11.cpp \
$(NULL)
......
......@@ -26,14 +26,6 @@
#ifndef Poller_H
#define Poller_H
#if defined(__CYGWIN32__) || defined(WIN32)
#include "Win.h"
#else
#include "X11.h"
#endif
#endif /* Poller_H */
......@@ -295,8 +295,6 @@ int NXShadowCreate(void *dpy, char *keymap, char* shadowDisplayName, void **shad
return 1;
}
#if !defined(__CYGWIN32__) && !defined(WIN32)
void NXShadowSetDisplayUid(int uid)
{
NXShadowOptions.optionShadowDisplayUid = uid;
......@@ -324,8 +322,6 @@ void NXShadowSetScreenSize(int *w, int *h)
poller -> setScreenSize(w, h);
}
#endif
void NXShadowDestroy()
{
if (poller)
......@@ -388,9 +384,7 @@ int NXShadowHasChanged(int (*callback)(void *), void *arg, int *suspended)
updateManager -> newRegion();
#if !defined(__CYGWIN32__) && !defined(WIN32)
poller -> getEvents();
#endif
result = poller -> isChanged(callback, arg, suspended);
......@@ -440,22 +434,6 @@ 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);
......
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE which comes in the source */
/* distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the core maintainers and supporters are listed as */
/* copyright holders. Please contact us, if you feel you should be listed */
/* as copyright holder, as well. */
/* */
/**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(__CYGWIN32__) || defined(WIN32)
#include <nx-X11/keysym.h>
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#include "Poller.h"
#include "Logger.h"
Poller::Poller(Input *input, Display *display, int depth) : CorePoller(input, display)
{
logTrace("Poller::Poller");
screenDC_ = NULL;
screenBmp_ = NULL;
memoryDC_ = NULL;
pDIBbits_ = NULL;
DIBBuffer_ = NULL;
pKey_ = NULL;
pMouse_ = NULL;
path_ = NULL;
keymapName_ = input -> getKeymap();
keymap_ = NULL;
toggleButtonState_ = 0;
serverModifierState_ = 0;
display_ = display;
depth_ = DefaultDepth(display_, DefaultScreen(display_));
oldCursor_ = 0;
xCursor_ = 0;
}
Poller::~Poller()
{
logTrace("Poller::~Poller");
if (screenDC_)
{
BOOL result = ReleaseDC(NULL, screenDC_);
logTest("Poller::~Poller", "ReleaseDC returned [%d].", result);
screenDC_ = NULL;
}
if (memoryDC_)
{
BOOL result = DeleteDC(memoryDC_);
logTest("Poller::~Poller", "DeleteDC returned [%d].", result);
memoryDC_ = NULL;
}
if (screenBmp_)
{
BOOL result = DeleteObject(screenBmp_);
logTest("Poller::~Poller", "DeleteObject returned [%d].", result);
screenBmp_ = NULL;
}
if (DIBBuffer_)
{
logDebug("Poller::~Poller", "Delete DIBBuffer_ [%p].", DIBBuffer_);
delete [] DIBBuffer_;
}
if (pKey_)
{
logDebug("Poller::~Poller", " pKey_[%p].", pKey_);
delete [] pKey_;
}
if (pMouse_)
{
logDebug("Poller::~Poller", " pMouse_[%p].", pMouse_);
delete [] pMouse_;
}
if (keymap_)
{
logDebug("Poller::~Poller", " keymap_[%p].", keymap_);
delete [] keymap_;
}
}
int Poller::init()
{
logTrace("Poller::init");
int maxLengthArrayINPUT = 6;
platformOS();
pKey_ = new INPUT [maxLengthArrayINPUT];
if (pKey_ == NULL)
{
logError("Poller::init", ESET(ENOMEM));
return -1;
}
for (int i = 0; i < maxLengthArrayINPUT; i++)
{
pKey_[i].type = INPUT_KEYBOARD;
pKey_[i].ki.wVk = (WORD) 0;
pKey_[i].ki.time = (DWORD) 0;
pKey_[i].ki.dwExtraInfo = (DWORD) 0;
}
pMouse_ = new INPUT;
if (pMouse_ == NULL)
{
logError("Poller::init", ESET(ENOMEM));
return -1;
}
pMouse_ -> type = INPUT_MOUSE;
pMouse_ -> mi.dx = 0;
pMouse_ -> mi.dy = 0;
pMouse_ -> mi.mouseData = (DWORD) 0;
pMouse_ -> mi.time = 0;
pMouse_ -> mi.dwExtraInfo = (ULONG_PTR) NULL;
screenDC_ = GetDC(NULL);
if (screenDC_ == NULL)
{
logError("Poller::init", ESET(ENOMSG));
return -1;
}
switch(depth_)
{
case 8:
{
depth_ = 16;
break;
}
case 16:
{
depth_ = 16;
break;
}
case 24:
{
depth_ = 32;
break;
}
default:
{
logError("Poller::init", ESET(EINVAL));
return -1;
}
}
width_ = GetDeviceCaps(screenDC_, HORZRES);
height_ = GetDeviceCaps(screenDC_, VERTRES);
bpl_ = width_ * (depth_ >> 3);
bpp_ = (depth_ >> 3);
logTest("Poller::init", "Screen geometry is [%d, %d] depth is [%d] bpl [%d] bpp [%d].",
width_, height_, depth_, bpl_, bpp_);
logTest("Poller::init", "Got device context at [%p] screen size is (%d,%d).",
screenDC_, width_, height_);
memoryDC_ = CreateCompatibleDC(screenDC_);
if (memoryDC_ == NULL)
{
logError("Poller::init", ESET(ENOMSG));
return -1;
}
//
// Delete the old bitmap for the memory device.
//
HBITMAP bitmap = (HBITMAP) GetCurrentObject(memoryDC_, OBJ_BITMAP);
if (bitmap && DeleteObject(bitmap) == 0)
{
logError("Poller::init", ESET(ENOMSG));
}
//
// Bitmap header describing the bitmap we want to get from GetDIBits.
//
bmi_.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi_.bmiHeader.biWidth = width_;
bmi_.bmiHeader.biHeight = -height_;
bmi_.bmiHeader.biPlanes = 1;
bmi_.bmiHeader.biBitCount = depth_;
bmi_.bmiHeader.biCompression = BI_RGB;
bmi_.bmiHeader.biSizeImage = 0;
bmi_.bmiHeader.biXPelsPerMeter = 0;
bmi_.bmiHeader.biYPelsPerMeter = 0;
bmi_.bmiHeader.biClrUsed = 0;
bmi_.bmiHeader.biClrImportant = 0;
screenBmp_ = CreateDIBSection(memoryDC_, &bmi_, DIB_RGB_COLORS, &pDIBbits_, NULL, 0);
ReleaseDC(NULL,memoryDC_);
if (screenBmp_ == NULL)
{
logTest ("Poller::init", "This video device is not supporting DIB section");
pDIBbits_ = NULL;
screenBmp_ = CreateCompatibleBitmap(screenDC_, width_, height_);
if (screenBmp_ == NULL)
{
logError("Poller::init", ESET(ENOMSG));
return -1;
}
if (SelectObject(memoryDC_, screenBmp_) == NULL)
{
logError("Poller::init", ESET(ENOMSG));
return -1;
}
}
else
{
logTest ("Poller::init", "Enabled the DIB section");
if (SelectObject(memoryDC_, screenBmp_) == NULL)
{
logError("Poller::init", ESET(ENOMSG));
return -1;
}
}
//
// Check if the screen device raster capabilities
// support the bitmap transfer.
//
if ((GetDeviceCaps(screenDC_, RASTERCAPS) & RC_BITBLT) == 0)
{
logTest("Poller::init", "This video device is not supporting the bitmap transfer.");
logError("Poller::init", ESET(ENOMSG));
return -1;
}
//
// Check if the memory device raster capabilities
// support the GetDIBits and SetDIBits functions.
//
if ((GetDeviceCaps(memoryDC_, RASTERCAPS) & RC_DI_BITMAP) == 0)
{
logTest("Poller::init", "This memory device is not supporting the GetDIBits and SetDIBits "
"function.");
logError("Poller::init", ESET(ENOMSG));
return -1;
}
if (GetDeviceCaps(screenDC_, PLANES) != 1)
{
logTest("Poller::init", "This video device has more than 1 color plane.");
logError("Poller::init", ESET(ENOMSG));
return -1;
}
return CorePoller::init();
}
//
// FIXME: Remove me.
//
void ErrorExit(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
logTest(lpszFunction, " Failed with error [%ld]: %s", dw, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
ExitProcess(dw);
}
//
// FIXME: End.
//
char *Poller::getRect(XRectangle r)
{
logTrace("Poller::getRect");
logDebug("Poller::getRect", "Going to retrive rectangle [%d, %d, %d, %d].",
r.x, r.y, r.width, r.height);
//
// The CAPTUREBLT operation could be a very
// cpu-consuming task. We should make some
// test to see how much it is expensive.
// Anyway we get tooltip windows and any
// other special effect not included with
// only the SRCCOPY operation.
//
if (BitBlt(memoryDC_, r.x, r.y, r.width, r.height,
screenDC_, r.x, r.y, SRCCOPY | CAPTUREBLT) == 0)
{
logError("Poller::getRect", ESET(ENOMSG));
logTest("Poller::getRect", "Failed to perform a bit-block transfer.");
logTest("Poller::getRect", "bit-block error=%lu", GetLastError());
return NULL;
}
// bmi_.bmiHeader.biWidth = r.width;
// bmi_.bmiHeader.biHeight = -r.height;
if (pDIBbits_ == NULL)
{
static long nPixel = 0;
if (nPixel < r.width * r.height)
{
if (DIBBuffer_)
{
delete [] DIBBuffer_;
}
nPixel = r.width * r.height;
DIBBuffer_ = new char [nPixel * bpp_];
if (DIBBuffer_ == NULL)
{
logError("Poller::getRect", ESET(ENOMEM));
nPixel = 0;
return NULL;
}
}
if (GetDIBits(memoryDC_, screenBmp_, height_ - r.height - r.y, r.height,
DIBBuffer_, &bmi_, DIB_RGB_COLORS) == 0)
{
logError("Poller::getRect", ESET(ENOMSG));
logTest("Poller::getRect", "Failed to retrieve the screen bitmap.");
return NULL;
}
return DIBBuffer_;
}
else
{
return (char *) pDIBbits_ + r.y * bpl_ + r.x * bpp_;
}
}
void Poller::handleKeyboardEvent(Display *display, XEvent *event)
{
KeySym keysym;
char *keyname = new char [31];
keyTranslation tr = {0, 0};
unsigned char scancode = 0;
int lengthArrayINPUT = 0;
if (XLookupString((XKeyEvent *) event, keyname, 30, &keysym, NULL) > 0)
{
logTest("Poller::handleKeyboardEvent", "keyname %s, keysym [%x]", keyname, (unsigned int)keysym);
}
if (specialKeys(keysym, event -> xkey.state, event -> type) == 1)
{
delete[] keyname;
return;
}
tr = xkeymapTranslateKey(keysym, event -> xkey.keycode, event -> xkey.state);
scancode = tr.scancode;
logTest("Poller::handleKeyboardEvent", "keyname [%s] scancode [0x%x], keycode[0x%x], keysym [%x]", keyname,
tr.scancode, event ->xkey.keycode, (unsigned int)keysym);
if (scancode == 0)
{
delete[] keyname;
return;
}
if (event -> type == KeyPress)
{
int test1 = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
int test2 = MapVirtualKey(0x24, MAPVK_VSC_TO_VK_EX);
if (test1 == test2)
{
simulateCtrlAltDel();
}
if (isModifier(scancode) == 0)
{
savedServerModifierState_ = serverModifierState_;
}
ensureServerModifiers(tr, &lengthArrayINPUT);
if (sendInput(scancode, 1, &lengthArrayINPUT) == 0)
{
logTest("Poller::handleKeyboardEvent", "lengthArrayINPUT [%d].", lengthArrayINPUT);
}
restoreServerModifiers(scancode);
}
else if (event -> type == KeyRelease)
{
if (sendInput(scancode, 0, &lengthArrayINPUT) == 0)
{
logTest("Poller::handleKeyboardEvent", "lengthArrayINPUT [%d].", lengthArrayINPUT);
}
}
updateModifierState(scancode, (event -> type == KeyPress));
delete[] keyname;
}
void Poller::handleWebKeyboardEvent(KeySym keysym, Bool isKeyPress)
{
/*
FIXME
*/
}
void Poller::handleMouseEvent(Display *display, XEvent *event)
{
DWORD flg = 0;
DWORD whl = 0;
if (event -> type == ButtonPress)
{
logTest("Poller::handleMouseEvent", "ButtonPress.\n");
switch (event -> xbutton.button)
{
case Button1:
{
flg = MOUSEEVENTF_LEFTDOWN;
break;
}
case Button2:
{
flg = MOUSEEVENTF_MIDDLEDOWN;
break;
}
case Button3:
{
flg = MOUSEEVENTF_RIGHTDOWN;
break;
}
case Button4:
{
flg = MOUSEEVENTF_WHEEL;
whl = WHEEL_DELTA;
pMouse_ -> mi.mouseData = whl;
break;
}
case Button5:
{
flg = MOUSEEVENTF_WHEEL;
whl = (DWORD) (-WHEEL_DELTA);
pMouse_ -> mi.mouseData = whl;
break;
}
}
}
else if (event -> type == ButtonRelease)
{
switch (event -> xbutton.button)
{
case Button1:
{
flg = MOUSEEVENTF_LEFTUP;
break;
}
case Button2:
{
flg = MOUSEEVENTF_MIDDLEUP;
break;
}
case Button3:
{
flg = MOUSEEVENTF_RIGHTUP;
break;
}
case Button4:
{
flg = MOUSEEVENTF_WHEEL;
whl = 0;
pMouse_ -> mi.mouseData = whl;
break;
}
case Button5:
{
flg = MOUSEEVENTF_WHEEL;
whl = 0;
pMouse_ -> mi.mouseData = whl;
break;
}
}
}
else if (event -> type == MotionNotify)
{
logTest("Poller::handleMouseEvent", "SetCursor - MotionNotify");
SetCursorPos(event -> xmotion.x, event -> xmotion.y);
}
if (flg > 0)
{
// logTest("Poller::handleMouseEvent", "SetCursor - flg > 0");
//
// FIXME: move the cursor to the pace the event occurred
//
SetCursorPos(event -> xbutton.x, event -> xbutton.y);
//
// FIXME: Remove me: send the click/release event
// mouse_event(flg, 0, 0, whl, (ULONG_PTR)NULL);
//
pMouse_ -> mi.dwFlags = flg;
if (SendInput(1, pMouse_, sizeof(INPUT)) == 0)
{
logTest("Poller::handleMouseEvent", "Failed SendInput");
}
}
}
int Poller::updateCursor(Window wnd, Visual* vis)
{
BYTE *mBits, *andBits, *xorBits;
logTrace("Poller::Cursor");
//
// Retrieve mouse cursor handle.
//
CURSORINFO cursorInfo;
cursorInfo.cbSize = sizeof(CURSORINFO);
if (GetCursorInfo(&cursorInfo) == 0)
{
logTest("Poller::Cursor", "GetCursorInfo() failed [%u].\n", (unsigned int)GetLastError());
LocalFree(&cursorInfo);
return -1;
}
HCURSOR hCursor = cursorInfo.hCursor;
if (hCursor == 0)
{
logTest("Poller::Cursor","Cursor Handle is NULL. Error[%u].\n", (unsigned int)GetLastError());
return 1;
}
if (hCursor == oldCursor_)
{
LocalFree(&cursorInfo);
return 1;
}
else
{
oldCursor_ = hCursor;
}
//
// Get cursor info.
//
// logTest("Poller::Cursor","hCursor [%xH] GetCursor [%xH].\n", hCursor, GetCursor());
ICONINFO iconInfo;
if (GetIconInfo(hCursor, &iconInfo) == 0)
{
logTest("Poller::Cursor","GetIconInfo() failed. Error[%d].", (unsigned int)GetLastError());
LocalFree(&iconInfo);
// return -1;
}
BOOL isColorCursor = FALSE;
if (iconInfo.hbmColor != NULL)
{
isColorCursor = TRUE;
}
if (iconInfo.hbmMask == NULL)
{
logTest("Poller::Cursor","Cursor bitmap handle is NULL.\n");
return -1;
}
//
// Check bitmap info for the cursor
//
BITMAP bmMask;
if (!GetObject(iconInfo.hbmMask, sizeof(BITMAP), (LPVOID)&bmMask))
{
logTest("Poller::Cursor","GetObject() for bitmap failed.\n");
DeleteObject(iconInfo.hbmMask);
LocalFree(&bmMask);
return -1;
}
if (bmMask.bmPlanes != 1 || bmMask.bmBitsPixel != 1)
{
logTest("Poller::Cursor","Incorrect data in cursor bitmap.\n");
LocalFree(&bmMask);
DeleteObject(iconInfo.hbmMask);
return -1;
}
// Get monochrome bitmap data for cursor
// NOTE: they say we should use GetDIBits() instead of GetBitmapBits().
mBits = new BYTE[bmMask.bmWidthBytes * bmMask.bmHeight];
if (mBits == NULL)//Data bitmap
{
DeleteObject(iconInfo.hbmMask);
DestroyCursor(cursorInfo.hCursor);
LocalFree(&iconInfo);
LocalFree(&bmMask);
delete[] mBits;
return -1;
}
BOOL success = GetBitmapBits(iconInfo.hbmMask, bmMask.bmWidthBytes * bmMask.bmHeight, mBits);
if (!success)
{
logTest("Poller::Cursor","GetBitmapBits() failed.\n");
delete[] mBits;
return -1;
}
andBits = mBits;
long width = bmMask.bmWidth;
long height = (isColorCursor) ? bmMask.bmHeight : bmMask.bmHeight/2;
//
// The bitmask is formatted so that the upper half is
// the icon AND bitmask and the lower half is the icon XOR bitmask.
//
if (!isColorCursor)
{
xorBits = andBits + bmMask.bmWidthBytes * height;
/* logTest("Poller::Cursor","no color widthB[%ld] width[%ld] height[%ld] totByte[%ld] mbits[%ld].\n",
bmMask.bmWidthBytes,width,height,success,bmMask.bmHeight * bmMask.bmWidthBytes);*/
if (xCursor_ > 0)
{
XFreeCursor(display_, xCursor_);
}
xCursor_ = createCursor(wnd, vis, (unsigned int)iconInfo.xHotspot, (unsigned int)iconInfo.yHotspot,
width, height, (unsigned char *)xorBits, (unsigned char *)andBits);
XDefineCursor(display_, wnd, xCursor_);
}
delete []mBits;
DeleteObject(iconInfo.hbmMask);
LocalFree(&bmMask);
DestroyCursor(cursorInfo.hCursor);
LocalFree(&iconInfo);
return success;
}
unsigned char Poller::specialKeys(unsigned int keysym, unsigned int state, int pressed)
{
return 0;
}
void Poller::ensureServerModifiers(keyTranslation tr, int *lengthArrayINPUT)
{
return;
}
void Poller::restoreServerModifiers(UINT scancode)
{
keyTranslation dummy;
int lengthArrayINPUT = 0;
if (isModifier(scancode) == 1)
{
return;
}
dummy.scancode = 0;
dummy.modifiers = savedServerModifierState_;
ensureServerModifiers(dummy, &lengthArrayINPUT);
if (sendInput(0, 0, &lengthArrayINPUT) == 0)
{
logTest("Poller::restoreServerModifiers", "lengthArrayINPUT [%d]", lengthArrayINPUT);
}
}
int Poller::updateShadowFrameBuffer(void)
{
return 1;
}
void Poller::addToKeymap(char *keyname, unsigned char scancode, unsigned short modifiers, char *mapname)
{
return;
}
FILE *Poller::xkeymapOpen(char *filename)
{
return NULL;
}
int Poller::xkeymapRead(char *mapname)
{
return 1;
}
void Poller::xkeymapInit(char *keyMapName)
{
return;
}
keyTranslation Poller::xkeymapTranslateKey(unsigned int keysym, unsigned int keycode,
unsigned int state)
{
keyTranslation tr = { 0, 0 };
return tr;
}
unsigned char Poller::getKeyState(unsigned int state, unsigned int keysym)
{
return 0;
}
char *Poller::getKsname(unsigned int keysym)
{
char *ksname = NULL;
return ksname;
}
//
// Routine used to fool Winlogon into thinking CtrlAltDel was pressed
//
char Poller::simulateCtrlAltDel(void)
{
HDESK oldDesktop = GetThreadDesktop(GetCurrentThreadId());
//
// Switch into the Winlogon desktop.
//
if (selectDesktopByName("Winlogon") == 0)
{
logTest("SimulateCtrlAltDelThreadFn","Failed to select logon desktop.");
return 0;
}
logTest("SimulateCtrlAltDelThreadFn","Generating ctrl-alt-del.");
//
// Winlogon uses hotkeys to trap Ctrl-Alt-Del.
//
PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));
//
// Switch back to our original desktop.
//
if (oldDesktop != NULL)
{
selectDesktop(oldDesktop);
}
return 1;
}
// Switches the current thread into a different desktop by desktop handle
// This call takes care of all the evil memory management involved
char Poller::selectDesktop(HDESK newDesktop)
{
//
// Only on NT.
//
if (isWinNT())
{
HDESK oldDesktop = GetThreadDesktop(GetCurrentThreadId());
DWORD dummy;
char newName[256];
if (GetUserObjectInformation(newDesktop, UOI_NAME, &newName, 256, &dummy) == 0)
{
logDebug("Poller::selectDesktop","GetUserObjectInformation() failed. Error[%lu].", GetLastError());
return 0;
}
logTest("Poller::selectDesktop","New Desktop to [%s] (%x) from (%x).",
newName, (unsigned int)newDesktop, (unsigned int)oldDesktop);
//
// Switch the desktop.
//
if(SetThreadDesktop(newDesktop) == 0)
{
logDebug("Poller::SelectDesktop","Unable to SetThreadDesktop(), Error=%lu.", GetLastError());
return 0;
}
//
// Switched successfully - destroy the old desktop.
//
if (CloseDesktop(oldDesktop) == 0)
{
logDebug("Poller::selectHdesk","Failed to close old desktop (%x), Error=%lu.",
(unsigned int)oldDesktop, GetLastError());
return 0;
}
}
return 1;
}
//
// Switches the current thread into a different desktop, by name
// Calling with a valid desktop name will place the thread in that desktop.
// Calling with a NULL name will place the thread in the current input desktop.
//
char Poller::selectDesktopByName(char *name)
{
//
// Only on NT.
//
if (isWinNT())
{
HDESK desktop;
if (name != NULL)
{
//
// Attempt to open the named desktop.
//
desktop = OpenDesktop(name, 0, FALSE,
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
}
else
{
//
// Open the input desktop.
//
desktop = OpenInputDesktop(0, FALSE,
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
}
if (desktop == NULL)
{
logDebug("Poller::selectDesktopByName","Unable to open desktop, Error=%lu.", GetLastError());
return 0;
}
//
// Switch to the new desktop
//
if (selectDesktop(desktop) == 0)
{
//
// Failed to enter the new desktop, so free it!
//
logDebug("Poller::selectDesktopByName","Failed to select desktop.");
if (CloseDesktop(desktop) == 0)
{
logDebug("Poller::selectDesktopByName","Failed to close desktop, Error=%lu.", GetLastError());
return 0;
}
}
return 1;
}
return (name == NULL);
}
void Poller::platformOS()
{
OSVERSIONINFO osversioninfo;
osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo);
//
// Get the current OS version.
//
if (GetVersionEx(&osversioninfo) == 0)
{
platformID_ = 0;
}
platformID_ = osversioninfo.dwPlatformId;
//
// versionMajor = osversioninfo.dwMajorVersion;
// versionMinor = osversioninfo.dwMinorVersion;
//
}
char Poller::checkDesktop()
{
//
// Only on NT.
//
if (isWinNT())
{
//
// Get the input and thread desktops.
//
HDESK desktop = GetThreadDesktop(GetCurrentThreadId());
HDESK inputDesktop = OpenInputDesktop(0, FALSE,
DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);
if (inputDesktop == NULL)
{
return 0;
}
DWORD dummy;
char desktopName[256];
char inputName[256];
if (GetUserObjectInformation(desktop, UOI_NAME, &desktopName, 256, &dummy) == 0)
{
if (CloseDesktop(inputDesktop) == 0)
{
logDebug("Poller::checkDesktop", "Failed to close desktop, Error[%d].", (unsigned int)GetLastError());
return 0;
}
}
if (GetUserObjectInformation(inputDesktop, UOI_NAME, &inputName, 256, &dummy) == 0)
{
if (CloseDesktop(inputDesktop) == 0)
{
logDebug("Poller::checkDesktop", "Failed to close input desktop, Error[%d].", (unsigned int)GetLastError());
return 0;
}
}
if (strcmp(desktopName, inputName) != 0)
{
//
// Switch to new desktop.
//
selectDesktop(inputDesktop);
}
if (CloseDesktop(desktop) == 0)
{
logDebug("Poller::checkDesktop", "Failed to close input desktop, Error[%d].", (unsigned int)GetLastError());
return 0;
}
if (CloseDesktop(inputDesktop) == 0)
{
logDebug("Poller::checkDesktop", "Failed to close input desktop, Error[%d].", (unsigned int)GetLastError());
return 0;
}
}
return 1;
}
unsigned char Poller::isModifier(UINT scancode)
{
return 0;
}
void Poller::updateModifierState(UINT scancode, unsigned char pressed)
{
return;
}
Cursor Poller::createCursor(Window wnd, Visual *vis,unsigned int x, unsigned int y,
int width, int height, unsigned char *xormask, unsigned char *andmask)
{
Pixmap maskglyph, cursorglyph;
XColor bg, fg;
Cursor xcursor;
unsigned char *cursor;
unsigned char *mask, *pmask, *pcursor, tmp;
int scanline, offset;
scanline = (width + 7) / 8;
offset = scanline * height;
pmask = andmask;
pcursor = xormask;
for (int i = 0; i < offset; i++)
{
//
// The pixel is black if both the bit of andmask and xormask is one.
//
tmp = *pcursor & *pmask;
*pcursor ^= tmp;
*pmask ^= tmp;
*pmask = ~(*pmask);
pmask++;
pcursor++;
}
cursor = new unsigned char[offset];
memcpy(cursor, xormask, offset);
mask = new unsigned char[offset];
memcpy(mask, andmask, offset);
fg.red = fg.blue = fg.green = 0xffff;
bg.red = bg.blue = bg.green = 0x0000;
fg.flags = bg.flags = DoRed | DoBlue | DoGreen;
cursorglyph = createGlyph(wnd, vis, width, height, cursor);
maskglyph = createGlyph(wnd, vis, width, height, mask);
xcursor = XCreatePixmapCursor(display_, cursorglyph, maskglyph, &fg, &bg, x, y);
XFreePixmap(display_, maskglyph);
XFreePixmap(display_, cursorglyph);
delete[]mask;
delete[]cursor;
return xcursor;
}
Pixmap Poller::createGlyph(Window wnd, Visual *visual, int width, int height, unsigned char *data)
{
XImage *image;
Pixmap bitmap;
int scanline;
GC glyphGC;
scanline = (width + 7) / 8;
bitmap = XCreatePixmap(display_, wnd, width, height, 1);
glyphGC = XCreateGC(display_, bitmap, 0, NULL);
image = XCreateImage(display_, visual, 1, ZPixmap, 0, (char *)data, width, height, 8, scanline);
image->byte_order = 1; // MSBFirst -- LSBFirst = 0
image->bitmap_bit_order = 1;
XInitImage(image);
/* logTest("Poller::createGlyph","XPutImage on pixmap %d,%d,%d,%d.\n",
0, 0, width, height);*/
XPutImage(display_, bitmap, glyphGC, image, 0, 0, 0, 0, width, height);
XFree(image);
return bitmap;
}
#endif /* defined(__CYGWIN32__) || defined(WIN32) */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */
/* Copyright (c) 2008-2014 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> */
/* Copyright (c) 2014-2016 Ulrich Sibiller <uli42@gmx.de> */
/* Copyright (c) 2014-2016 Mihai Moldovan <ionic@ionic.de> */
/* Copyright (c) 2011-2016 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>*/
/* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */
/* */
/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
/* are copyright of the aforementioned persons and companies. */
/* */
/* Redistribution and use of the present software is allowed according */
/* to terms specified in the file LICENSE which comes in the source */
/* distribution. */
/* */
/* All rights reserved. */
/* */
/* NOTE: This software has received contributions from various other */
/* contributors, only the core maintainers and supporters are listed as */
/* copyright holders. Please contact us, if you feel you should be listed */
/* as copyright holder, as well. */
/* */
/**************************************************************************/
#ifdef __CYGWIN32__
#ifndef Win32Poller_H
#define Win32Poller_H
//#include <nx-X11/X.h>
#include <Windows.h>
#include <wingdi.h>
#include <winable.h>
#include <winuser.h>
#define CAPTUREBLT 0x40000000
#define KEYEVENTF_SCANCODE 0x00000008
#define MAPVK_VSC_TO_VK_EX 3
//
// The CAPTUREBLT is a raster operation used
// in bit blit transfer.
//
// Using this operation includes any windows
// that are layered on top of your window in
// the resulting image. By default, the image
// only contains your window.
//
#include "Core.h"
typedef struct _keyTranslation
{
unsigned char scancode;
unsigned short modifiers;
}keyTranslation;
class Poller : public CorePoller
{
public:
Display *display_;
keyTranslation *keymap_;
unsigned char keymapLoaded_;
int minKeycode_;
Poller(Input *, Display *display, int = 16);
~Poller();
int init();
int updateCursor(Window, Visual*);
private:
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);
void xkeymapInit(char *keyMapName);
keyTranslation xkeymapTranslateKey(unsigned int keysym, unsigned int keycode, unsigned int state);
unsigned char getKeyState(unsigned int state, unsigned int keysym);
char *getKsname(unsigned int keysym);
unsigned char specialKeys(unsigned int keysym, unsigned int state, int pressed);
unsigned char toggleSwitch(unsigned char ToggleStateClient, unsigned char ToggleStateServer, UINT scancode,
int *lengthArrayINPUT);
void updateModifierState(UINT, unsigned char);
unsigned char toggleServerState(UINT scancode);
unsigned char keyState(UINT scancode, UINT mapType);
unsigned char keyStateAsync(UINT scancode);
void handleMouseEvent(Display *, XEvent *);
Cursor createCursor(Window wnd, Visual *vis, unsigned int x, unsigned int y, int width,
int height, unsigned char *xormask, unsigned char *andmask);
Pixmap createGlyph(Window wnd, Visual *visual, int width, int height, unsigned char *data);
char isWinNT();
char selectDesktop(HDESK new_desktop);
char selectDesktopByName(char *name);
void platformOS();
char simulateCtrlAltDel(void);
DWORD platformID_;
INPUT *pKey_, *pMouse_;
char *keymapName_;
char *path_;
unsigned char toggleButtonState_;
unsigned short serverModifierState_;
unsigned short savedServerModifierState_;
void ensureServerModifiers(keyTranslation tr, int *lenghtArrayINPUT);
void restoreServerModifiers(UINT scancode);
unsigned char isModifier(UINT scancode);
char sendInput(unsigned char scancode, unsigned char pressed, int *lengthArrayINPUT);
char *getRect(XRectangle);
char checkDesktop();
char *DIBBuffer_;
HCURSOR oldCursor_;
VOID *pDIBbits_;
HDC screenDC_;
HDC memoryDC_;
BITMAPINFO bmi_;
HBITMAP screenBmp_;
Cursor xCursor_;
};
#undef TEST
inline unsigned char Poller::toggleSwitch(unsigned char ToggleStateClient, unsigned char ToggleStateServer,
UINT scancode, int *lengthArrayINPUT)
{
return 1;
}
inline unsigned char Poller::toggleServerState(UINT scancode)
{
return (GetKeyState(MapVirtualKeyEx(scancode, 3, GetKeyboardLayout((DWORD)NULL))) & 0x1);
}
inline unsigned char Poller::keyStateAsync(UINT vKeycode)
{
return GetAsyncKeyState(vKeycode);
}
inline unsigned char Poller::keyState(UINT code, UINT mapType)
{
if (mapType == 0)
{
//
// Virtual Keycode
//
return ((GetKeyState(code) & 0x80) == 0x80);
}
else
{
//
// scancode
//
return ((GetKeyState(MapVirtualKeyEx(code, 3, GetKeyboardLayout((DWORD)NULL))) & 0x80) == 0x80);
}
}
inline char Poller::isWinNT()
{
return (platformID_ == VER_PLATFORM_WIN32_NT);
}
inline char Poller::sendInput(unsigned char scancode, unsigned char pressed, int *lengthArrayINPUT)
{
DWORD keyEvent = 0;
DWORD extended = 0;
if (scancode > 0)
{
if (pressed == 0)
{
keyEvent = KEYEVENTF_KEYUP;
}
if (scancode & 0x80)
{
scancode &= ~0x80;
extended = KEYEVENTF_EXTENDEDKEY;
}
pKey_[*lengthArrayINPUT].ki.wScan = (WORD) scancode;
pKey_[*lengthArrayINPUT].ki.dwFlags = (DWORD) (keyEvent | KEYEVENTF_SCANCODE | extended);
(*lengthArrayINPUT)++;
}
if (*lengthArrayINPUT > 0) {
// FIXME: Remove me.
logTest("Poller::sendInput", "length Input [%d] event: %s", *lengthArrayINPUT,
pressed == 1 ? "KeyPress": "KeyRelease");
if (SendInput(*lengthArrayINPUT, pKey_, sizeof(INPUT)) == 0)
{
logTest("Poller::sendInput", "Failed SendInput, event: %s", pressed == 1 ? "KeyPress": "KeyRelease");
*lengthArrayINPUT = 0;
return 0;
}
*lengthArrayINPUT = 0;
}
return 1;
}
#endif /* Win32Poller_H */
#endif /* __CYGWIN32__ */
......@@ -27,8 +27,6 @@
#include "config.h"
#endif
#if !defined(__CYGWIN32__) && !defined(WIN32)
#define PANIC
#define WARNING
#undef TEST
......@@ -1594,5 +1592,3 @@ int anyEventPredicate(Display *display, XEvent *event, XPointer parameter)
{
return 1;
}
#endif /* !defined(__CYGWIN32__) && !defined(WIN32) */
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