src/video/x11/SDL_x11mouse.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 04 Jan 2009 18:29:20 +0000
changeset 2992 dbff5769d742
parent 2962 1e242954330b
child 3002 0deb3e94c251
permissions -rw-r--r--
The core pointer is comprised of merging the inputs of all mice.
If there are other mice, they should show up in the device list, and
we want to report events from those devices instead of the core events.
However, if XInput isn't supported or we can't find other mice in the
device list, we'll add the core pointer and interpret normal mouse events.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 #include "SDL_x11video.h"
    24 #include "SDL_x11mouse.h"
    25 #include "../../events/SDL_mouse_c.h"
    26 
    27 #if SDL_VIDEO_DRIVER_X11_XINPUT
    28 static void
    29 X11_FreeMouse(SDL_Mouse * mouse)
    30 {
    31     X11_MouseData *data = (X11_MouseData *) mouse->driverdata;
    32 
    33     if (data) {
    34         XCloseDevice(data->display, data->device);
    35         SDL_free(data);
    36     }
    37 }
    38 #endif
    39 
    40 void
    41 X11_InitMouse(_THIS)
    42 {
    43     SDL_Mouse mouse;
    44 #if SDL_VIDEO_DRIVER_X11_XINPUT
    45     Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    46     X11_MouseData *data;
    47     int i, j, n;
    48     XDeviceInfo *DevList;
    49     XAnyClassPtr deviceClass;
    50     int event_code;
    51     XEventClass xEvent;
    52 #endif
    53     int num_mice = 0;
    54 
    55 #if SDL_VIDEO_DRIVER_X11_XINPUT
    56     /* we're getting the list of input devices */
    57     n = 0;
    58     if (SDL_X11_HAVE_XINPUT) {
    59         DevList = XListInputDevices(display, &n);
    60     }
    61 
    62     /* we're aquiring valuators: mice, tablets, etc. */
    63     for (i = 0; i < n; ++i) {
    64         /* if it's the core pointer or core keyborard we don't want it */
    65         if ((DevList[i].use != IsXPointer && DevList[i].use != IsXKeyboard)) {
    66             /* we have to check all of the device classes */
    67             deviceClass = DevList[i].inputclassinfo;
    68             for (j = 0; j < DevList[i].num_classes; ++j) {
    69                 if (deviceClass->class == ValuatorClass) {      /* bingo ;) */
    70                     XValuatorInfo *valInfo;
    71 
    72                     data = (X11_MouseData *) SDL_calloc(1, sizeof(*data));
    73                     if (!data) {
    74                         continue;
    75                     }
    76                     data->display = display;
    77                     data->device = XOpenDevice(display, DevList[i].id);
    78 
    79                     /* motion events */
    80                     DeviceMotionNotify(data->device, event_code, xEvent);
    81                     if (xEvent) {
    82                         data->xevents[data->num_xevents++] = xEvent;
    83                         data->motion = event_code;
    84                     }
    85 
    86                     /* button events */
    87                     DeviceButtonPress(data->device, event_code, xEvent);
    88                     if (xEvent) {
    89                         data->xevents[data->num_xevents++] = xEvent;
    90                         data->button_pressed = event_code;
    91                     }
    92                     DeviceButtonRelease(data->device, event_code, xEvent);
    93                     if (xEvent) {
    94                         data->xevents[data->num_xevents++] = xEvent;
    95                         data->button_released = event_code;
    96                     }
    97 
    98                     /* proximity events */
    99                     ProximityIn(data->device, event_code, xEvent);
   100                     if (xEvent) {
   101                         data->xevents[data->num_xevents++] = xEvent;
   102                         data->proximity_in = event_code;
   103                     }
   104                     ProximityOut(data->device, event_code, xEvent);
   105                     if (xEvent) {
   106                         data->xevents[data->num_xevents++] = xEvent;
   107                         data->proximity_out = event_code;
   108                     }
   109 
   110                     SDL_zero(mouse);
   111                     mouse.id = DevList[i].id;
   112                     mouse.FreeMouse = X11_FreeMouse;
   113                     mouse.driverdata = data;
   114 
   115                     /* lets get the device parameters */
   116                     valInfo = (XValuatorInfo *) deviceClass;
   117                     /* if the device reports pressure, lets check it parameteres */
   118                     if (valInfo->num_axes > 2) {
   119                         SDL_AddMouse(&mouse, DevList[i].name,
   120                                      valInfo->axes[2].max_value,
   121                                      valInfo->axes[2].min_value, 1);
   122                     } else {
   123                         SDL_AddMouse(&mouse, DevList[i].name, 0, 0, 1);
   124                     }
   125                     if (DevList[i].use == IsXExtensionPointer) {
   126                         ++num_mice;
   127                     }
   128                     break;
   129                 }
   130                 /* if it's not class we're interested in, lets go further */
   131                 deviceClass =
   132                     (XAnyClassPtr) ((char *) deviceClass +
   133                                     deviceClass->length);
   134             }
   135         }
   136     }
   137     XFreeDeviceList(DevList);
   138 #endif
   139 
   140     if (num_mice == 0) {
   141         SDL_zero(mouse);
   142         SDL_AddMouse(&mouse, "CorePointer", 0, 0, 1);
   143     }
   144 }
   145 
   146 void
   147 X11_QuitMouse(_THIS)
   148 {
   149     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   150 
   151     /* !!! FIXME: use XCloseDevice()? Or maybe handle under SDL_MouseQuit()? */
   152 
   153     /* let's delete all of the mice */
   154     SDL_MouseQuit();
   155 }
   156 
   157 /* vi: set ts=4 sw=4 expandtab: */