~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c,v 3.17 2002/05/31 18:46:02 dawes Exp $ */
 
2
/*
 
3
 * (c) Copyright 1994,1999,2000 by Holger Veit
 
4
 *                      <Holger.Veit@gmd.de>
 
5
 * Modified (c) 1996 Sebastien Marineau <marineau@genie.uottawa.ca>
 
6
 *
 
7
 * Permission is hereby granted, free of charge, to any person obtaining a 
 
8
 * copy of this software and associated documentation files (the "Software"), 
 
9
 * to deal in the Software without restriction, including without limitation 
 
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 
11
 * and/or sell copies of the Software, and to permit persons to whom the 
 
12
 * Software is furnished to do so, subject to the following conditions:
 
13
 *
 
14
 * The above copyright notice and this permission notice shall be included in
 
15
 * all copies or substantial portions of the Software.
 
16
 * 
 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
 
20
 * HOLGER VEIT  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
 
22
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 
23
 * SOFTWARE.
 
24
 * 
 
25
 * Except as contained in this notice, the name of Holger Veit shall not be
 
26
 * used in advertising or otherwise to promote the sale, use or other dealings
 
27
 * in this Software without prior written authorization from Holger Veit.
 
28
 *
 
29
 */
 
30
/* $XConsortium: os2_mouse.c /main/10 1996/10/27 11:48:51 kaleb $ */
 
31
 
 
32
#define I_NEED_OS2_H
 
33
#define NEED_EVENTS
 
34
#include "X.h"
 
35
#include "Xproto.h"
 
36
#include "misc.h"
 
37
#include "inputstr.h"
 
38
#include "scrnintstr.h"
 
39
 
 
40
#include "compiler.h"
 
41
 
 
42
#define INCL_DOSFILEMGR
 
43
#define INCL_DOSQUEUES
 
44
#define INCL_MOU
 
45
#undef RT_FONT
 
46
#include "xf86.h"
 
47
#include "xf86Priv.h"
 
48
#include "xf86_OSlib.h"
 
49
#include "xf86Config.h"
 
50
 
 
51
#include "xf86Xinput.h"
 
52
#include "xf86OSmouse.h"
 
53
#include "mipointer.h"
 
54
 
 
55
static int
 
56
SupportedInterfaces(void)
 
57
{
 
58
        return MSE_MISC;
 
59
}
 
60
 
 
61
static const char* internalNames[] = {
 
62
        "OS2Mouse",
 
63
        NULL
 
64
};
 
65
 
 
66
static const char**
 
67
BuiltinNames(void)
 
68
{
 
69
        return internalNames;
 
70
}
 
71
 
 
72
static Bool
 
73
CheckProtocol(const char *protocol)
 
74
{
 
75
        int i;
 
76
 
 
77
        for (i = 0; internalNames[i]; i++)
 
78
        if (xf86NameCmp(protocol, internalNames[i]) == 0)
 
79
                return TRUE;
 
80
        return FALSE;
 
81
}
 
82
 
 
83
static const char *
 
84
DefaultProtocol(void)
 
85
{
 
86
        return "OS2Mouse";
 
87
}
 
88
 
 
89
static const char *
 
90
SetupAuto(InputInfoPtr pInfo, int *protoPara)
 
91
{
 
92
        return "OS2Mouse";
 
93
}
 
94
 
 
95
HMOU hMouse=65535;
 
96
HEV hMouseSem;
 
97
HQUEUE hMouseQueue;
 
98
InputInfoPtr iinfoPtr;
 
99
int MouseTid;
 
100
BOOL HandleValid=FALSE;
 
101
extern BOOL SwitchedToWPS;
 
102
extern CARD32 LastSwitchTime;
 
103
void os2MouseEventThread(void* arg);
 
104
 
 
105
static void
 
106
os2MouseReadInput(InputInfoPtr pInfo)
 
107
{
 
108
        APIRET rc;
 
109
        ULONG postCount,dataLength;
 
110
        PVOID dummy;
 
111
        int buttons;
 
112
        int state;
 
113
        int i, dx,dy;
 
114
        BYTE elemPriority;
 
115
        REQUESTDATA requestData;
 
116
 
 
117
        MouseDevPtr pMse = pInfo->private;
 
118
 
 
119
        if (!HandleValid) return;
 
120
        while((rc = DosReadQueue(hMouseQueue,
 
121
                                 &requestData,&dataLength,&dummy, 
 
122
                                 0L,1L,&elemPriority,hMouseSem)) == 0) {
 
123
                dx = requestData.ulData;
 
124
                (void)DosReadQueue(hMouseQueue,
 
125
                                  &requestData,&dataLength,&dummy,
 
126
                                  0L,1L,&elemPriority,hMouseSem);
 
127
                dy = requestData.ulData;
 
128
                (void)DosReadQueue(hMouseQueue,
 
129
                                  &requestData,&dataLength,&dummy,
 
130
                                  0L,1L,&elemPriority,hMouseSem);
 
131
                state = requestData.ulData;
 
132
                (void)DosReadQueue(hMouseQueue,
 
133
                                  &requestData,&dataLength,&dummy,
 
134
                                  0L,1L,&elemPriority,hMouseSem);
 
135
                if (requestData.ulData != 0xFFFFFFFF) 
 
136
                        xf86Msg(X_ERROR,
 
137
                                "Unexpected mouse event tag, %d\n",
 
138
                                requestData.ulData);
 
139
 
 
140
                /* Contrary to other systems, OS/2 has mouse buttons *
 
141
                 * in the proper order, so we reverse them before    *
 
142
                 * sending the event.                                */
 
143
                 
 
144
                buttons = ((state & 0x06) ? 4 : 0) |
 
145
                          ((state & 0x18) ? 1 : 0) |
 
146
                          ((state & 0x60) ? 2 : 0);
 
147
                pMse->PostEvent(pInfo, buttons, dx, dy, 0, 0);
 
148
        }
 
149
        DosResetEventSem(hMouseSem,&postCount);
 
150
}
 
151
 
 
152
int os2MouseProc(DeviceIntPtr pPointer, int what)
 
153
{
 
154
    APIRET rc = 0;
 
155
    USHORT nbuttons, state;
 
156
    unsigned char map[MSE_MAXBUTTONS + 1];
 
157
    int i;
 
158
 
 
159
    InputInfoPtr pInfo = pPointer->public.devicePrivate;
 
160
    MouseDevPtr pMse = pInfo->private;
 
161
    pMse->device = pPointer;
 
162
 
 
163
    switch (what) {
 
164
    case DEVICE_INIT: 
 
165
        pPointer->public.on = FALSE;
 
166
        if (hMouse == 65535) 
 
167
            rc = MouOpen((PSZ)0, &hMouse);
 
168
        if (rc != 0)
 
169
            xf86Msg(X_WARNING,"%s: cannot open mouse, rc=%d\n", 
 
170
                    pInfo->name,rc);
 
171
        else {
 
172
            pInfo->fd = hMouse;
 
173
 
 
174
            /* flush mouse queue */
 
175
            MouFlushQue(hMouse);
 
176
 
 
177
            /* check buttons */
 
178
            rc = MouGetNumButtons(&nbuttons, hMouse);
 
179
            if (rc == 0)
 
180
                xf86Msg(X_INFO,"%s: Mouse has %d button(s).\n",
 
181
                        pInfo->name,nbuttons);
 
182
            if (nbuttons==2) nbuttons++;
 
183
 
 
184
            for (i = 1; i<=nbuttons; i++)
 
185
                map[i] = i;
 
186
 
 
187
            InitPointerDeviceStruct((DevicePtr)pPointer, map, nbuttons,
 
188
                miPointerGetMotionEvents, pMse->Ctrl,
 
189
                miPointerGetMotionBufferSize());
 
190
 
 
191
            /* X valuator */
 
192
            xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
 
193
            xf86InitValuatorDefaults(pPointer, 0);
 
194
            /* y Valuator */
 
195
            InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
 
196
            xf86InitValuatorDefaults(pPointer, 1);
 
197
            xf86MotionHistoryAllocate(pInfo);
 
198
 
 
199
            /* OK, we are ready to start up the mouse thread ! */
 
200
            if (!HandleValid) {
 
201
                rc = DosCreateEventSem(NULL,&hMouseSem,DC_SEM_SHARED,TRUE);
 
202
                if (rc != 0)
 
203
                    xf86Msg(X_ERROR,"%s: could not create mouse queue semaphore, rc=%d\n",
 
204
                            pInfo->name,rc);
 
205
                MouseTid = _beginthread(os2MouseEventThread,NULL,0x4000,(void *)pInfo);
 
206
                xf86Msg(X_INFO,
 
207
                        "%s: Started Mouse event thread, Tid=%d\n",
 
208
                        pInfo->name, MouseTid);
 
209
                DosSetPriority(2,3,0,MouseTid);
 
210
            }
 
211
            HandleValid=TRUE;
 
212
        }
 
213
        break;
 
214
      
 
215
    case DEVICE_ON:
 
216
        if (!HandleValid) return -1;
 
217
        pMse->lastButtons = 0;
 
218
        pMse->emulateState = 0;
 
219
        pPointer->public.on = TRUE;
 
220
        state = 0x300;
 
221
        rc = MouSetDevStatus(&state,hMouse);
 
222
        state = 0x7f;
 
223
        rc = MouSetEventMask(&state,hMouse);
 
224
        MouFlushQue(hMouse);
 
225
        break;
 
226
 
 
227
    case DEVICE_CLOSE:
 
228
    case DEVICE_OFF:
 
229
        if (!HandleValid) return -1;
 
230
        pPointer->public.on = FALSE;
 
231
        state = 0x300;
 
232
        MouSetDevStatus(&state,hMouse);
 
233
        state = 0;
 
234
        MouSetEventMask(&state,hMouse);
 
235
        if (what == DEVICE_CLOSE) {
 
236
/* Comment out for now as this seems to break server */
 
237
#if 0
 
238
            MouClose(hMouse);
 
239
            hMouse = 65535;
 
240
            pInfo->fd = -1;
 
241
            HandleValid = FALSE;
 
242
#endif
 
243
        }
 
244
        break;
 
245
    }
 
246
    return Success;
 
247
}
 
248
 
 
249
int os2MouseQueueQuery()
 
250
{
 
251
    /* Now we check for activity on mouse handles */
 
252
    ULONG numElements,postCount;
 
253
 
 
254
    if (!HandleValid) return(1);
 
255
    DosResetEventSem(hMouseSem,&postCount);
 
256
    (void)DosQueryQueue(hMouseQueue,&numElements);
 
257
    if (numElements>0) {     /* Something in mouse queue! */
 
258
        return 0;  /* Will this work? */
 
259
    }
 
260
    return 1;
 
261
}
 
262
 
 
263
void os2MouseEventThread(void *arg)
 
264
{
 
265
    APIRET rc;
 
266
    MOUEVENTINFO mev;
 
267
    ULONG queueParam;
 
268
    USHORT waitflg;
 
269
    char queueName[128];
 
270
    MouseDevPtr pMse;
 
271
 
 
272
    iinfoPtr = (InputInfoPtr)arg;
 
273
    pMse = iinfoPtr->private;
 
274
 
 
275
    sprintf(queueName,"\\QUEUES\\XF86MOU\\%d",getpid());
 
276
    rc = DosCreateQueue(&hMouseQueue,0L,queueName);
 
277
    xf86Msg(X_INFO,"Mouse Queue created, rc=%d\n",rc);
 
278
    (void)DosPurgeQueue(hMouseQueue);
 
279
 
 
280
    while(1) {
 
281
        waitflg = 1;
 
282
        rc = MouReadEventQue(&mev,&waitflg,hMouse);
 
283
        if (rc) {
 
284
            xf86Msg(X_ERROR,
 
285
                    "Bad return code from mouse driver, rc=%d\n",
 
286
                    rc);
 
287
            xf86Msg(X_ERROR,"Mouse aborting!\n");
 
288
            break;
 
289
        }
 
290
 
 
291
        queueParam = mev.col;
 
292
        if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L)))
 
293
                break;
 
294
        queueParam = mev.row;
 
295
        if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L)))
 
296
                break;
 
297
        queueParam = mev.fs;
 
298
        if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L)))
 
299
                break;
 
300
        queueParam = 0xFFFFFFFF;
 
301
        if ((rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L)))
 
302
                break;
 
303
    }
 
304
    xf86Msg(X_ERROR,
 
305
        "An unrecoverable error in mouse queue has occured, rc=%d. Mouse is shutting down.\n",
 
306
        rc);
 
307
    DosCloseQueue(hMouseQueue);
 
308
}
 
309
 
 
310
 
 
311
static Bool
 
312
os2MousePreInit(InputInfoPtr pInfo, const char* protocol, int flags) 
 
313
{
 
314
    MouseDevPtr pMse = pInfo->private;
 
315
 
 
316
    pMse->protocol = protocol;
 
317
    xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
 
318
 
 
319
    /* Collect the options, and process the common options. */
 
320
    xf86CollectInputOptions(pInfo, NULL, NULL);
 
321
    xf86ProcessCommonOptions(pInfo, pInfo->options);
 
322
 
 
323
    /* Process common mouse options (like Emulate3Buttons, etc). */
 
324
    pMse->CommonOptions(pInfo);
 
325
 
 
326
    /* Setup the local procs. */
 
327
    pInfo->device_control = os2MouseProc;
 
328
    pInfo->read_input = os2MouseReadInput;
 
329
 
 
330
    pInfo->flags |= XI86_CONFIGURED;
 
331
    return TRUE;
 
332
}
 
333
 
 
334
OSMouseInfoPtr
 
335
xf86OSMouseInit(int flags)
 
336
{
 
337
    OSMouseInfoPtr p;
 
338
 
 
339
    p = xcalloc(sizeof(OSMouseInfoRec), 1);
 
340
    if (!p)
 
341
        return NULL;
 
342
    p->SupportedInterfaces = SupportedInterfaces;
 
343
    p->BuiltinNames = BuiltinNames;
 
344
    p->DefaultProtocol = DefaultProtocol;
 
345
    p->CheckProtocol = CheckProtocol;
 
346
    p->PreInit = os2MousePreInit;
 
347
    p->SetupAuto = SetupAuto;
 
348
    return p;
 
349
}
 
350
 
 
351
void xf86OsMouseEvents()
 
352
{
 
353
        APIRET rc;
 
354
        ULONG postCount,dataLength;
 
355
        PVOID dummy;
 
356
        int buttons;
 
357
        int state;
 
358
        int i, dx,dy;
 
359
        BYTE elemPriority;
 
360
        REQUESTDATA requestData;
 
361
 
 
362
        MouseDevPtr pMse = iinfoPtr->private;
 
363
 
 
364
        if (!HandleValid) return;
 
365
        while((rc = DosReadQueue(hMouseQueue,
 
366
                                 &requestData,&dataLength,&dummy, 
 
367
                                 0L,1L,&elemPriority,hMouseSem)) == 0) {
 
368
                dx = requestData.ulData;
 
369
                (void)DosReadQueue(hMouseQueue,
 
370
                                  &requestData,&dataLength,&dummy,
 
371
                                  0L,1L,&elemPriority,hMouseSem);
 
372
                dy = requestData.ulData;
 
373
                (void)DosReadQueue(hMouseQueue,
 
374
                                  &requestData,&dataLength,&dummy,
 
375
                                  0L,1L,&elemPriority,hMouseSem);
 
376
                state = requestData.ulData;
 
377
                (void)DosReadQueue(hMouseQueue,
 
378
                                  &requestData,&dataLength,&dummy,
 
379
                                  0L,1L,&elemPriority,hMouseSem);
 
380
                if (requestData.ulData != 0xFFFFFFFF) 
 
381
                        xf86Msg(X_ERROR,
 
382
                                "Unexpected mouse event tag, %d\n",
 
383
                                requestData.ulData);
 
384
 
 
385
                /* Contrary to other systems, OS/2 has mouse buttons *
 
386
                 * in the proper order, so we reverse them before    *
 
387
                 * sending the event.                                */
 
388
                 
 
389
                buttons = ((state & 0x06) ? 4 : 0) |
 
390
                          ((state & 0x18) ? 1 : 0) |
 
391
                          ((state & 0x60) ? 2 : 0);
 
392
                pMse->PostEvent(iinfoPtr, buttons, dx, dy, 0, 0);
 
393
        }
 
394
        DosResetEventSem(hMouseSem,&postCount);
 
395
}