summaryrefslogtreecommitdiffstats
path: root/unix/xserver/hw/vnc/Input.h
blob: 029b80d13bcbf90dec04165dae4de4e66bc28345 (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
/* Copyright (C) 2009 TightVNC Team
 * Copyright (C) 2009, 2010 Red Hat, Inc.
 * Copyright (C) 2009, 2010 TigerVNC Team
 * Copyright 2013 Pierre Ossman for Cendio AB
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

/* Make sure macro doesn't conflict with macro in include/input.h. */
#ifndef INPUT_H_
#define INPUT_H_

#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

#include <list>

#include <rdr/types.h>
#include <rfb/Rect.h>

extern "C" {
#include "input.h"
/* The Xorg headers define macros that wreak havoc with STL */
#undef max
};

#include "xorg-version.h"

/*
 * Represents input device (keyboard + pointer)
 *
 * Is a singleton as input devices are global in the X server so
 * we do not have one per desktop (i.e. per screen).
 */
extern class InputDevice *vncInputDevice;

class InputDevice {
public:
	/*
	 * Press or release buttons. Relationship between buttonMask and
	 * buttons is specified in RFB protocol.
	 */
	void PointerButtonAction(int buttonMask);

	/* Move pointer to target location (point coords are absolute). */
	void PointerMove(const rfb::Point &point);

	/* Get current known location of the pointer */
	const rfb::Point &getPointerPos(void);

	/* Press or release one or more keys to get the given symbol */
	void KeyboardPress(rdr::U32 keysym) { keyEvent(keysym, true); }
	void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); }

	/*
	 * Init input device.
	 * This has to be called after core pointer/keyboard
	 * initialization which unfortunately is after extesions
	 * initialization (which means we cannot call it in
	 * vncExtensionInit(). Check InitExtensions(),
	 * InitCoreDevices() and InitInput() calls in dix/main.c.
	 * Instead we call it from XserverDesktop at an appropriate
	 * time.
	 */
	void InitInputDevice(void);

private:
	InputDevice();

	void keyEvent(rdr::U32 keysym, bool down);

	/* Backend dependent functions below here */
	void PrepareInputDevices(void);

	unsigned getKeyboardState(void);
	unsigned getLevelThreeMask(void);

	KeyCode pressShift(void);
	std::list<KeyCode> releaseShift(void);

	KeyCode pressLevelThree(void);
	std::list<KeyCode> releaseLevelThree(void);

	KeyCode keysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state);

	bool isLockModifier(KeyCode keycode, unsigned state);

	bool isAffectedByNumLock(KeyCode keycode);

	KeyCode addKeysym(KeySym keysym, unsigned state);

private:
	static int pointerProc(DeviceIntPtr pDevice, int onoff);
	static int keyboardProc(DeviceIntPtr pDevice, int onoff);

#if XORG >= 17
	static void vncXkbProcessDeviceEvent(int screenNum,
	                                     InternalEvent *event,
	                                     DeviceIntPtr dev);
#else
	static void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap);
#endif

private:
	bool initialized;
	DeviceIntPtr keyboardDev;
	DeviceIntPtr pointerDev;

	int oldButtonMask;
	rfb::Point cursorPos;

	KeySym pressedKeys[256];

private:
	static InputDevice singleton;
};

#endif