Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /** |
2 | * Copyright © 2009 Red Hat, Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice (including the next | |
12 | * paragraph) shall be included in all copies or substantial portions of the | |
13 | * Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
21 | * DEALINGS IN THE SOFTWARE. | |
22 | */ | |
23 | ||
24 | #ifdef HAVE_DIX_CONFIG_H | |
25 | #include <dix-config.h> | |
26 | #endif | |
27 | ||
28 | #include <stdint.h> | |
29 | #include "extinit.h" /* for XInputExtensionInit */ | |
30 | #include "exglobals.h" | |
31 | #include "xkbsrv.h" /* for XkbInitPrivates */ | |
32 | #include "xserver-properties.h" | |
33 | #include "syncsrv.h" | |
34 | #include <X11/extensions/XI2.h> | |
35 | ||
36 | #include "protocol-common.h" | |
37 | ||
38 | struct devices devices; | |
39 | ScreenRec screen; | |
40 | WindowRec root; | |
41 | WindowRec window; | |
42 | static ClientRec server_client; | |
43 | ||
44 | void *userdata; | |
45 | ||
46 | extern int CorePointerProc(DeviceIntPtr pDev, int what); | |
47 | extern int CoreKeyboardProc(DeviceIntPtr pDev, int what); | |
48 | ||
49 | static void | |
50 | fake_init_sprite(DeviceIntPtr dev) | |
51 | { | |
52 | SpritePtr sprite; | |
53 | ||
54 | sprite = dev->spriteInfo->sprite; | |
55 | ||
56 | sprite->spriteTraceSize = 10; | |
57 | sprite->spriteTrace = calloc(sprite->spriteTraceSize, sizeof(WindowPtr)); | |
58 | sprite->spriteTraceGood = 1; | |
59 | sprite->spriteTrace[0] = &root; | |
60 | sprite->hot.x = SPRITE_X; | |
61 | sprite->hot.y = SPRITE_Y; | |
62 | sprite->hotPhys.x = sprite->hot.x; | |
63 | sprite->hotPhys.y = sprite->hot.y; | |
64 | sprite->win = &window; | |
65 | sprite->hotPhys.pScreen = &screen; | |
66 | sprite->physLimits.x1 = 0; | |
67 | sprite->physLimits.y1 = 0; | |
68 | sprite->physLimits.x2 = screen.width; | |
69 | sprite->physLimits.y2 = screen.height; | |
70 | } | |
71 | ||
72 | /* This is essentially CorePointerProc with ScrollAxes added */ | |
73 | static int | |
74 | TestPointerProc(DeviceIntPtr pDev, int what) | |
75 | { | |
76 | #define NBUTTONS 10 | |
77 | #define NAXES 4 | |
78 | BYTE map[NBUTTONS + 1]; | |
79 | int i = 0; | |
80 | Atom btn_labels[NBUTTONS] = { 0 }; | |
81 | Atom axes_labels[NAXES] = { 0 }; | |
82 | ||
83 | switch (what) { | |
84 | case DEVICE_INIT: | |
85 | for (i = 1; i <= NBUTTONS; i++) | |
86 | map[i] = i; | |
87 | ||
88 | btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); | |
89 | btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); | |
90 | btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); | |
91 | btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); | |
92 | btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); | |
93 | btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); | |
94 | btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); | |
95 | /* don't know about the rest */ | |
96 | ||
97 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); | |
98 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); | |
99 | axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_VSCROLL); | |
100 | axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HSCROLL); | |
101 | ||
102 | if (!InitPointerDeviceStruct | |
103 | ((DevicePtr) pDev, map, NBUTTONS, btn_labels, | |
104 | (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES, | |
105 | axes_labels)) { | |
106 | ErrorF("Could not initialize device '%s'. Out of memory.\n", | |
107 | pDev->name); | |
108 | return BadAlloc; | |
109 | } | |
110 | pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; | |
111 | pDev->last.valuators[0] = pDev->valuator->axisVal[0]; | |
112 | pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; | |
113 | pDev->last.valuators[1] = pDev->valuator->axisVal[1]; | |
114 | ||
115 | /* protocol-xiquerydevice.c relies on these increment */ | |
116 | SetScrollValuator(pDev, 2, SCROLL_TYPE_VERTICAL, 2.4, SCROLL_FLAG_NONE); | |
117 | SetScrollValuator(pDev, 3, SCROLL_TYPE_HORIZONTAL, 3.5, | |
118 | SCROLL_FLAG_PREFERRED); | |
119 | break; | |
120 | ||
121 | case DEVICE_CLOSE: | |
122 | break; | |
123 | ||
124 | default: | |
125 | break; | |
126 | } | |
127 | ||
128 | return Success; | |
129 | ||
130 | #undef NBUTTONS | |
131 | #undef NAXES | |
132 | } | |
133 | ||
134 | /** | |
135 | * Create and init 2 master devices (VCP + VCK) and two slave devices, one | |
136 | * default mouse, one default keyboard. | |
137 | */ | |
138 | struct devices | |
139 | init_devices(void) | |
140 | { | |
141 | ClientRec client; | |
142 | struct devices devices; | |
143 | ||
144 | client = init_client(0, NULL); | |
145 | ||
146 | AllocDevicePair(&client, "Virtual core", &devices.vcp, &devices.vck, | |
147 | CorePointerProc, CoreKeyboardProc, TRUE); | |
148 | inputInfo.pointer = devices.vcp; | |
149 | ||
150 | inputInfo.keyboard = devices.vck; | |
151 | ActivateDevice(devices.vcp, FALSE); | |
152 | ActivateDevice(devices.vck, FALSE); | |
153 | EnableDevice(devices.vcp, FALSE); | |
154 | EnableDevice(devices.vck, FALSE); | |
155 | ||
156 | AllocDevicePair(&client, "", &devices.mouse, &devices.kbd, | |
157 | TestPointerProc, CoreKeyboardProc, FALSE); | |
158 | ActivateDevice(devices.mouse, FALSE); | |
159 | ActivateDevice(devices.kbd, FALSE); | |
160 | EnableDevice(devices.mouse, FALSE); | |
161 | EnableDevice(devices.kbd, FALSE); | |
162 | ||
163 | devices.num_devices = 4; | |
164 | devices.num_master_devices = 2; | |
165 | ||
166 | fake_init_sprite(devices.mouse); | |
167 | fake_init_sprite(devices.vcp); | |
168 | ||
169 | return devices; | |
170 | } | |
171 | ||
172 | /* Create minimal client, with the given buffer and len as request buffer */ | |
173 | ClientRec | |
174 | init_client(int len, void *data) | |
175 | { | |
176 | ClientRec client = { 0 }; | |
177 | ||
178 | /* we store the privates now and reassign it after the memset. this way | |
179 | * we can share them across multiple test runs and don't have to worry | |
180 | * about freeing them after each test run. */ | |
181 | ||
182 | client.index = CLIENT_INDEX; | |
183 | client.clientAsMask = CLIENT_MASK; | |
184 | client.sequence = CLIENT_SEQUENCE; | |
185 | client.req_len = len; | |
186 | ||
187 | client.requestBuffer = data; | |
188 | dixAllocatePrivates(&client.devPrivates, PRIVATE_CLIENT); | |
189 | return client; | |
190 | } | |
191 | ||
192 | void | |
193 | init_window(WindowPtr window, WindowPtr parent, int id) | |
194 | { | |
195 | memset(window, 0, sizeof(*window)); | |
196 | ||
197 | window->drawable.id = id; | |
198 | if (parent) { | |
199 | window->drawable.x = 30; | |
200 | window->drawable.y = 50; | |
201 | window->drawable.width = 100; | |
202 | window->drawable.height = 200; | |
203 | } | |
204 | window->parent = parent; | |
205 | window->optional = calloc(1, sizeof(WindowOptRec)); | |
206 | assert(window->optional); | |
207 | } | |
208 | ||
209 | extern DevPrivateKeyRec miPointerScreenKeyRec; | |
210 | extern DevPrivateKeyRec miPointerPrivKeyRec; | |
211 | ||
212 | /* Needed for the screen setup, otherwise we crash during sprite initialization */ | |
213 | static Bool | |
214 | device_cursor_init(DeviceIntPtr dev, ScreenPtr screen) | |
215 | { | |
216 | return TRUE; | |
217 | } | |
218 | ||
219 | static void | |
220 | device_cursor_cleanup(DeviceIntPtr dev, ScreenPtr screen) | |
221 | { | |
222 | } | |
223 | ||
224 | static Bool | |
225 | set_cursor_pos(DeviceIntPtr dev, ScreenPtr screen, int x, int y, Bool event) | |
226 | { | |
227 | return TRUE; | |
228 | } | |
229 | ||
230 | void | |
231 | init_simple(void) | |
232 | { | |
233 | screenInfo.numScreens = 1; | |
234 | screenInfo.screens[0] = &screen; | |
235 | ||
236 | screen.myNum = 0; | |
237 | screen.id = 100; | |
238 | screen.width = 640; | |
239 | screen.height = 480; | |
240 | screen.DeviceCursorInitialize = device_cursor_init; | |
241 | screen.DeviceCursorCleanup = device_cursor_cleanup; | |
242 | screen.SetCursorPosition = set_cursor_pos; | |
243 | ||
244 | dixResetPrivates(); | |
245 | InitAtoms(); | |
246 | XkbInitPrivates(); | |
247 | dixRegisterPrivateKey(&XIClientPrivateKeyRec, PRIVATE_CLIENT, | |
248 | sizeof(XIClientRec)); | |
249 | dixRegisterPrivateKey(&miPointerScreenKeyRec, PRIVATE_SCREEN, 0); | |
250 | dixRegisterPrivateKey(&miPointerPrivKeyRec, PRIVATE_DEVICE, 0); | |
251 | XInputExtensionInit(); | |
252 | ||
253 | init_window(&root, NULL, ROOT_WINDOW_ID); | |
254 | init_window(&window, &root, CLIENT_WINDOW_ID); | |
255 | ||
256 | serverClient = &server_client; | |
257 | InitClient(serverClient, 0, (pointer) NULL); | |
258 | if (!InitClientResources(serverClient)) /* for root resources */ | |
259 | FatalError("couldn't init server resources"); | |
260 | SyncExtensionInit(); | |
261 | ||
262 | devices = init_devices(); | |
263 | } | |
264 | ||
265 | void | |
266 | __wrap_WriteToClient(ClientPtr client, int len, void *data) | |
267 | { | |
268 | assert(reply_handler != NULL); | |
269 | ||
270 | (*reply_handler) (client, len, data, userdata); | |
271 | } |