aboutsummaryrefslogtreecommitdiff
path: root/nxcompshad/Win.h
blob: 72566b8f441e8409cc9dbfbd8004214a65576bca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**************************************************************************/
/*                                                                        */
/* Copyright (c) 2001, 2010 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.                                                   */
/*                                                                        */
/**************************************************************************/

#ifdef __CYGWIN32__

#ifndef Win32Poller_H
#define Win32Poller_H

//#include <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__ */