1/* 2 * Copyright © 2003 Philip Blundell 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Philip Blundell not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Philip Blundell makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL PHILIP BLUNDELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_KDRIVE_CONFIG_H 24#include <kdrive-config.h> 25#endif 26 27 28#include <X11/X.h> 29#include <X11/Xproto.h> 30#include "misc.h" 31#include "os.h" 32#include "dixstruct.h" 33#include "extnsionst.h" 34#include "swaprep.h" 35#include "protocol-versions.h" 36 37#include <X11/extensions/xcalibrateproto.h> 38#include <X11/extensions/xcalibratewire.h> 39 40extern void (*tslib_raw_event_hook)(int x, int y, int pressure, void *closure); 41extern void *tslib_raw_event_closure; 42 43static CARD8 XCalibrateReqCode; 44int XCalibrateEventBase; 45int XCalibrateReqBase; 46int XCalibrateErrorBase; 47 48static ClientPtr xcalibrate_client; 49 50static void 51xcalibrate_event_hook (int x, int y, int pressure, void *closure) 52{ 53 ClientPtr pClient = (ClientPtr) closure; 54 xXCalibrateRawTouchscreenEvent ev; 55 56 ev.type = XCalibrateEventBase + X_XCalibrateRawTouchscreen; 57 ev.x = x; 58 ev.y = y; 59 ev.pressure = pressure; 60 61 WriteEventsToClient (pClient, 1, (xEvent *) &ev); 62} 63 64static int 65ProcXCalibrateQueryVersion (ClientPtr client) 66{ 67 REQUEST(xXCalibrateQueryVersionReq); 68 xXCalibrateQueryVersionReply rep; 69 CARD16 client_major, client_minor; /* not used */ 70 71 REQUEST_SIZE_MATCH (xXCalibrateQueryVersionReq); 72 73 client_major = stuff->majorVersion; 74 client_minor = stuff->minorVersion; 75 76 fprintf(stderr, "%s(): called\n", __func__); 77 78 rep.type = X_Reply; 79 rep.length = 0; 80 rep.sequenceNumber = client->sequence; 81 rep.majorVersion = SERVER_XCALIBRATE_MAJOR_VERSION; 82 rep.minorVersion = SERVER_XCALIBRATE_MINOR_VERSION; 83 if (client->swapped) { 84 int n; 85 swaps(&rep.sequenceNumber, n); 86 swapl(&rep.length, n); 87 swaps(&rep.majorVersion, n); 88 swaps(&rep.minorVersion, n); 89 } 90 WriteToClient(client, sizeof (xXCalibrateQueryVersionReply), (char *)&rep); 91 return Success; 92} 93 94static int 95SProcXCalibrateQueryVersion (ClientPtr client) 96{ 97 REQUEST(xXCalibrateQueryVersionReq); 98 int n; 99 100 REQUEST_SIZE_MATCH (xXCalibrateQueryVersionReq); 101 swaps(&stuff->majorVersion,n); 102 swaps(&stuff->minorVersion,n); 103 return ProcXCalibrateQueryVersion(client); 104} 105 106static int 107ProcXCalibrateSetRawMode (ClientPtr client) 108{ 109 REQUEST(xXCalibrateRawModeReq); 110 xXCalibrateRawModeReply rep; 111 112 REQUEST_SIZE_MATCH (xXCalibrateRawModeReq); 113 114 memset (&rep, 0, sizeof (rep)); 115 rep.type = X_Reply; 116 rep.sequenceNumber = client->sequence; 117 118 if (stuff->on) 119 { 120 if (xcalibrate_client == NULL) 121 { 122 /* Start calibrating. */ 123 xcalibrate_client = client; 124 tslib_raw_event_hook = xcalibrate_event_hook; 125 tslib_raw_event_closure = client; 126 rep.status = GrabSuccess; 127 } 128 else 129 { 130 rep.status = AlreadyGrabbed; 131 } 132 } 133 else 134 { 135 if (xcalibrate_client == client) 136 { 137 /* Stop calibrating. */ 138 xcalibrate_client = NULL; 139 tslib_raw_event_hook = NULL; 140 tslib_raw_event_closure = NULL; 141 rep.status = GrabSuccess; 142 143 /* Cycle input off and on to reload configuration. */ 144 KdDisableInput (); 145 KdEnableInput (); 146 } 147 else 148 { 149 rep.status = AlreadyGrabbed; 150 } 151 } 152 153 if (client->swapped) 154 { 155 int n; 156 157 swaps (&rep.sequenceNumber, n); 158 swaps (&rep.status, n); 159 } 160 WriteToClient(client, sizeof (rep), (char *) &rep); 161 return Success; 162} 163 164static int 165SProcXCalibrateSetRawMode (ClientPtr client) 166{ 167 REQUEST(xXCalibrateRawModeReq); 168 int n; 169 170 REQUEST_SIZE_MATCH (xXCalibrateRawModeReq); 171 172 swaps(&stuff->on, n); 173 174 return ProcXCalibrateSetRawMode(client); 175} 176 177static int 178ProcXCalibrateScreenToCoord (ClientPtr client) 179{ 180 REQUEST(xXCalibrateScreenToCoordReq); 181 xXCalibrateScreenToCoordReply rep; 182 183 REQUEST_SIZE_MATCH (xXCalibrateScreenToCoordReq); 184 185 memset (&rep, 0, sizeof (rep)); 186 rep.type = X_Reply; 187 rep.sequenceNumber = client->sequence; 188 rep.x = stuff->x; 189 rep.y = stuff->y; 190 191 KdScreenToPointerCoords(&rep.x, &rep.y); 192 193 if (client->swapped) 194 { 195 int n; 196 197 swaps (&rep.x, n); 198 swaps (&rep.y, n); 199 } 200 WriteToClient(client, sizeof (rep), (char *) &rep); 201 return Success; 202} 203 204static int 205SProcXCalibrateScreenToCoord (ClientPtr client) 206{ 207 REQUEST(xXCalibrateScreenToCoordReq); 208 int n; 209 210 REQUEST_SIZE_MATCH (xXCalibrateScreenToCoordReq); 211 212 swaps(&stuff->x, n); 213 swaps(&stuff->y, n); 214 215 return ProcXCalibrateScreenToCoord(client); 216} 217 218static int 219ProcXCalibrateDispatch (ClientPtr client) 220{ 221 REQUEST(xReq); 222 switch (stuff->data) { 223 case X_XCalibrateQueryVersion: 224 return ProcXCalibrateQueryVersion(client); 225 case X_XCalibrateRawMode: 226 return ProcXCalibrateSetRawMode(client); 227 case X_XCalibrateScreenToCoord: 228 return ProcXCalibrateScreenToCoord(client); 229 230 default: break; 231 } 232 233 return BadRequest; 234} 235 236static int 237SProcXCalibrateDispatch (ClientPtr client) 238{ 239 REQUEST(xReq); 240 int n; 241 242 swaps(&stuff->length,n); 243 244 switch (stuff->data) { 245 case X_XCalibrateQueryVersion: 246 return SProcXCalibrateQueryVersion(client); 247 case X_XCalibrateRawMode: 248 return SProcXCalibrateSetRawMode(client); 249 case X_XCalibrateScreenToCoord: 250 return SProcXCalibrateScreenToCoord(client); 251 252 default: break; 253 } 254 255 return BadRequest; 256} 257 258static void 259XCalibrateClientCallback (CallbackListPtr *list, 260 pointer closure, 261 pointer data) 262{ 263 NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; 264 ClientPtr pClient = clientinfo->client; 265 266 if (clientinfo->setup == NULL 267 && xcalibrate_client != NULL 268 && xcalibrate_client == pClient) 269 { 270 /* Stop calibrating. */ 271 xcalibrate_client = NULL; 272 tslib_raw_event_hook = NULL; 273 tslib_raw_event_closure = NULL; 274 } 275} 276 277void 278XCalibrateExtensionInit(void) 279{ 280 ExtensionEntry *extEntry; 281 282 if (!AddCallback (&ClientStateCallback, XCalibrateClientCallback, 0)) 283 return; 284 285 extEntry = AddExtension(XCALIBRATE_NAME, XCalibrateNumberEvents, XCalibrateNumberErrors, 286 ProcXCalibrateDispatch, SProcXCalibrateDispatch, 287 NULL, StandardMinorOpcode); 288 289 if (!extEntry) 290 return; 291 292 XCalibrateReqCode = (unsigned char)extEntry->base; 293 XCalibrateEventBase = extEntry->eventBase; 294 XCalibrateErrorBase = extEntry->errorBase; 295 296 xcalibrate_client = 0; 297} 298