1706f2543Smrg/*
2706f2543Smrg * Copyright © 2003 Philip Blundell
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Philip Blundell not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Philip Blundell makes no
11706f2543Smrg * representations about the suitability of this software for any purpose.  It
12706f2543Smrg * is provided "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * PHILIP BLUNDELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL PHILIP BLUNDELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg */
22706f2543Smrg
23706f2543Smrg#ifdef HAVE_KDRIVE_CONFIG_H
24706f2543Smrg#include <kdrive-config.h>
25706f2543Smrg#endif
26706f2543Smrg
27706f2543Smrg
28706f2543Smrg#include <X11/X.h>
29706f2543Smrg#include <X11/Xproto.h>
30706f2543Smrg#include "misc.h"
31706f2543Smrg#include "os.h"
32706f2543Smrg#include "dixstruct.h"
33706f2543Smrg#include "extnsionst.h"
34706f2543Smrg#include "swaprep.h"
35706f2543Smrg#include "protocol-versions.h"
36706f2543Smrg
37706f2543Smrg#include <X11/extensions/xcalibrateproto.h>
38706f2543Smrg#include <X11/extensions/xcalibratewire.h>
39706f2543Smrg
40706f2543Smrgextern void (*tslib_raw_event_hook)(int x, int y, int pressure, void *closure);
41706f2543Smrgextern void *tslib_raw_event_closure;
42706f2543Smrg
43706f2543Smrgstatic CARD8	XCalibrateReqCode;
44706f2543Smrgint		XCalibrateEventBase;
45706f2543Smrgint		XCalibrateReqBase;
46706f2543Smrgint		XCalibrateErrorBase;
47706f2543Smrg
48706f2543Smrgstatic ClientPtr xcalibrate_client;
49706f2543Smrg
50706f2543Smrgstatic void
51706f2543Smrgxcalibrate_event_hook (int x, int y, int pressure, void *closure)
52706f2543Smrg{
53706f2543Smrg  ClientPtr pClient = (ClientPtr) closure;
54706f2543Smrg  xXCalibrateRawTouchscreenEvent	ev;
55706f2543Smrg
56706f2543Smrg  ev.type = XCalibrateEventBase + X_XCalibrateRawTouchscreen;
57706f2543Smrg  ev.x = x;
58706f2543Smrg  ev.y = y;
59706f2543Smrg  ev.pressure = pressure;
60706f2543Smrg
61706f2543Smrg  WriteEventsToClient (pClient, 1, (xEvent *) &ev);
62706f2543Smrg}
63706f2543Smrg
64706f2543Smrgstatic int
65706f2543SmrgProcXCalibrateQueryVersion (ClientPtr client)
66706f2543Smrg{
67706f2543Smrg  REQUEST(xXCalibrateQueryVersionReq);
68706f2543Smrg  xXCalibrateQueryVersionReply rep;
69706f2543Smrg  CARD16 client_major, client_minor;  /* not used */
70706f2543Smrg
71706f2543Smrg  REQUEST_SIZE_MATCH (xXCalibrateQueryVersionReq);
72706f2543Smrg
73706f2543Smrg  client_major = stuff->majorVersion;
74706f2543Smrg  client_minor = stuff->minorVersion;
75706f2543Smrg
76706f2543Smrg  fprintf(stderr, "%s(): called\n", __func__);
77706f2543Smrg
78706f2543Smrg  rep.type = X_Reply;
79706f2543Smrg  rep.length = 0;
80706f2543Smrg  rep.sequenceNumber = client->sequence;
81706f2543Smrg  rep.majorVersion = SERVER_XCALIBRATE_MAJOR_VERSION;
82706f2543Smrg  rep.minorVersion = SERVER_XCALIBRATE_MINOR_VERSION;
83706f2543Smrg  if (client->swapped) {
84706f2543Smrg    int n;
85706f2543Smrg    swaps(&rep.sequenceNumber, n);
86706f2543Smrg    swapl(&rep.length, n);
87706f2543Smrg    swaps(&rep.majorVersion, n);
88706f2543Smrg    swaps(&rep.minorVersion, n);
89706f2543Smrg  }
90706f2543Smrg  WriteToClient(client, sizeof (xXCalibrateQueryVersionReply), (char *)&rep);
91706f2543Smrg  return Success;
92706f2543Smrg}
93706f2543Smrg
94706f2543Smrgstatic int
95706f2543SmrgSProcXCalibrateQueryVersion (ClientPtr client)
96706f2543Smrg{
97706f2543Smrg    REQUEST(xXCalibrateQueryVersionReq);
98706f2543Smrg    int n;
99706f2543Smrg
100706f2543Smrg    REQUEST_SIZE_MATCH (xXCalibrateQueryVersionReq);
101706f2543Smrg    swaps(&stuff->majorVersion,n);
102706f2543Smrg    swaps(&stuff->minorVersion,n);
103706f2543Smrg    return ProcXCalibrateQueryVersion(client);
104706f2543Smrg}
105706f2543Smrg
106706f2543Smrgstatic int
107706f2543SmrgProcXCalibrateSetRawMode (ClientPtr client)
108706f2543Smrg{
109706f2543Smrg  REQUEST(xXCalibrateRawModeReq);
110706f2543Smrg  xXCalibrateRawModeReply rep;
111706f2543Smrg
112706f2543Smrg  REQUEST_SIZE_MATCH (xXCalibrateRawModeReq);
113706f2543Smrg
114706f2543Smrg  memset (&rep, 0, sizeof (rep));
115706f2543Smrg  rep.type = X_Reply;
116706f2543Smrg  rep.sequenceNumber = client->sequence;
117706f2543Smrg
118706f2543Smrg  if (stuff->on)
119706f2543Smrg    {
120706f2543Smrg      if (xcalibrate_client == NULL)
121706f2543Smrg	{
122706f2543Smrg	  /* Start calibrating.  */
123706f2543Smrg	  xcalibrate_client = client;
124706f2543Smrg	  tslib_raw_event_hook = xcalibrate_event_hook;
125706f2543Smrg	  tslib_raw_event_closure = client;
126706f2543Smrg	  rep.status = GrabSuccess;
127706f2543Smrg	}
128706f2543Smrg      else
129706f2543Smrg	{
130706f2543Smrg	  rep.status = AlreadyGrabbed;
131706f2543Smrg	}
132706f2543Smrg    }
133706f2543Smrg  else
134706f2543Smrg    {
135706f2543Smrg      if (xcalibrate_client == client)
136706f2543Smrg	{
137706f2543Smrg	  /* Stop calibrating.  */
138706f2543Smrg	  xcalibrate_client = NULL;
139706f2543Smrg	  tslib_raw_event_hook = NULL;
140706f2543Smrg	  tslib_raw_event_closure = NULL;
141706f2543Smrg	  rep.status = GrabSuccess;
142706f2543Smrg
143706f2543Smrg	  /* Cycle input off and on to reload configuration.  */
144706f2543Smrg	  KdDisableInput ();
145706f2543Smrg	  KdEnableInput ();
146706f2543Smrg	}
147706f2543Smrg      else
148706f2543Smrg	{
149706f2543Smrg	  rep.status = AlreadyGrabbed;
150706f2543Smrg	}
151706f2543Smrg    }
152706f2543Smrg
153706f2543Smrg  if (client->swapped)
154706f2543Smrg    {
155706f2543Smrg      int n;
156706f2543Smrg
157706f2543Smrg      swaps (&rep.sequenceNumber, n);
158706f2543Smrg      swaps (&rep.status, n);
159706f2543Smrg    }
160706f2543Smrg  WriteToClient(client, sizeof (rep), (char *) &rep);
161706f2543Smrg  return Success;
162706f2543Smrg}
163706f2543Smrg
164706f2543Smrgstatic int
165706f2543SmrgSProcXCalibrateSetRawMode (ClientPtr client)
166706f2543Smrg{
167706f2543Smrg  REQUEST(xXCalibrateRawModeReq);
168706f2543Smrg  int n;
169706f2543Smrg
170706f2543Smrg  REQUEST_SIZE_MATCH (xXCalibrateRawModeReq);
171706f2543Smrg
172706f2543Smrg  swaps(&stuff->on, n);
173706f2543Smrg
174706f2543Smrg  return ProcXCalibrateSetRawMode(client);
175706f2543Smrg}
176706f2543Smrg
177706f2543Smrgstatic int
178706f2543SmrgProcXCalibrateScreenToCoord (ClientPtr client)
179706f2543Smrg{
180706f2543Smrg  REQUEST(xXCalibrateScreenToCoordReq);
181706f2543Smrg  xXCalibrateScreenToCoordReply rep;
182706f2543Smrg
183706f2543Smrg  REQUEST_SIZE_MATCH (xXCalibrateScreenToCoordReq);
184706f2543Smrg
185706f2543Smrg  memset (&rep, 0, sizeof (rep));
186706f2543Smrg  rep.type = X_Reply;
187706f2543Smrg  rep.sequenceNumber = client->sequence;
188706f2543Smrg  rep.x = stuff->x;
189706f2543Smrg  rep.y = stuff->y;
190706f2543Smrg
191706f2543Smrg  KdScreenToPointerCoords(&rep.x, &rep.y);
192706f2543Smrg
193706f2543Smrg  if (client->swapped)
194706f2543Smrg    {
195706f2543Smrg      int n;
196706f2543Smrg
197706f2543Smrg      swaps (&rep.x, n);
198706f2543Smrg      swaps (&rep.y, n);
199706f2543Smrg    }
200706f2543Smrg  WriteToClient(client, sizeof (rep), (char *) &rep);
201706f2543Smrg  return Success;
202706f2543Smrg}
203706f2543Smrg
204706f2543Smrgstatic int
205706f2543SmrgSProcXCalibrateScreenToCoord (ClientPtr client)
206706f2543Smrg{
207706f2543Smrg  REQUEST(xXCalibrateScreenToCoordReq);
208706f2543Smrg  int n;
209706f2543Smrg
210706f2543Smrg  REQUEST_SIZE_MATCH (xXCalibrateScreenToCoordReq);
211706f2543Smrg
212706f2543Smrg  swaps(&stuff->x, n);
213706f2543Smrg  swaps(&stuff->y, n);
214706f2543Smrg
215706f2543Smrg  return ProcXCalibrateScreenToCoord(client);
216706f2543Smrg}
217706f2543Smrg
218706f2543Smrgstatic int
219706f2543SmrgProcXCalibrateDispatch (ClientPtr client)
220706f2543Smrg{
221706f2543Smrg    REQUEST(xReq);
222706f2543Smrg    switch (stuff->data) {
223706f2543Smrg    case X_XCalibrateQueryVersion:
224706f2543Smrg        return ProcXCalibrateQueryVersion(client);
225706f2543Smrg    case X_XCalibrateRawMode:
226706f2543Smrg        return ProcXCalibrateSetRawMode(client);
227706f2543Smrg    case X_XCalibrateScreenToCoord:
228706f2543Smrg        return ProcXCalibrateScreenToCoord(client);
229706f2543Smrg
230706f2543Smrg    default: break;
231706f2543Smrg    }
232706f2543Smrg
233706f2543Smrg    return BadRequest;
234706f2543Smrg}
235706f2543Smrg
236706f2543Smrgstatic int
237706f2543SmrgSProcXCalibrateDispatch (ClientPtr client)
238706f2543Smrg{
239706f2543Smrg    REQUEST(xReq);
240706f2543Smrg    int n;
241706f2543Smrg
242706f2543Smrg    swaps(&stuff->length,n);
243706f2543Smrg
244706f2543Smrg    switch (stuff->data) {
245706f2543Smrg    case X_XCalibrateQueryVersion:
246706f2543Smrg        return SProcXCalibrateQueryVersion(client);
247706f2543Smrg    case X_XCalibrateRawMode:
248706f2543Smrg        return SProcXCalibrateSetRawMode(client);
249706f2543Smrg    case X_XCalibrateScreenToCoord:
250706f2543Smrg        return SProcXCalibrateScreenToCoord(client);
251706f2543Smrg
252706f2543Smrg    default: break;
253706f2543Smrg    }
254706f2543Smrg
255706f2543Smrg    return BadRequest;
256706f2543Smrg}
257706f2543Smrg
258706f2543Smrgstatic void
259706f2543SmrgXCalibrateClientCallback (CallbackListPtr	*list,
260706f2543Smrg			  pointer		closure,
261706f2543Smrg			  pointer		data)
262706f2543Smrg{
263706f2543Smrg    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
264706f2543Smrg    ClientPtr		pClient = clientinfo->client;
265706f2543Smrg
266706f2543Smrg    if (clientinfo->setup == NULL
267706f2543Smrg	&& xcalibrate_client != NULL
268706f2543Smrg	&& xcalibrate_client == pClient)
269706f2543Smrg      {
270706f2543Smrg	/* Stop calibrating.  */
271706f2543Smrg	xcalibrate_client = NULL;
272706f2543Smrg	tslib_raw_event_hook = NULL;
273706f2543Smrg	tslib_raw_event_closure = NULL;
274706f2543Smrg      }
275706f2543Smrg}
276706f2543Smrg
277706f2543Smrgvoid
278706f2543SmrgXCalibrateExtensionInit(void)
279706f2543Smrg{
280706f2543Smrg  ExtensionEntry *extEntry;
281706f2543Smrg
282706f2543Smrg  if (!AddCallback (&ClientStateCallback, XCalibrateClientCallback, 0))
283706f2543Smrg    return;
284706f2543Smrg
285706f2543Smrg  extEntry = AddExtension(XCALIBRATE_NAME, XCalibrateNumberEvents, XCalibrateNumberErrors,
286706f2543Smrg			  ProcXCalibrateDispatch, SProcXCalibrateDispatch,
287706f2543Smrg			  NULL, StandardMinorOpcode);
288706f2543Smrg
289706f2543Smrg  if (!extEntry)
290706f2543Smrg    return;
291706f2543Smrg
292706f2543Smrg  XCalibrateReqCode = (unsigned char)extEntry->base;
293706f2543Smrg  XCalibrateEventBase = extEntry->eventBase;
294706f2543Smrg  XCalibrateErrorBase = extEntry->errorBase;
295706f2543Smrg
296706f2543Smrg  xcalibrate_client = 0;
297706f2543Smrg}
298