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