Remove old files from SDL external

They were already removed in SDL upstream but the update mechanism did
not remove them in this repository.

They were causing build failures when the SDL external was used.
This commit is contained in:
Simon Bruder
2022-01-22 11:15:39 +01:00
parent 0c49a90d80
commit 9867c12dc0
86 changed files with 0 additions and 18934 deletions

View File

@@ -1,35 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#ifdef SDL_LIBUSB_DYNAMIC
#define HAVE_ENABLE_GAMECUBE_ADAPTORS
#endif
#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS
extern void SDL_EnableGameCubeAdaptors(void);
#endif
#endif /* SDL_JOYSTICK_HIDAPI */
/* vi: set sts=4 ts=4 sw=4 expandtab: */

View File

@@ -1,333 +0,0 @@
//=================== Copyright Valve Corporation, All rights reserved. =======
//
// Purpose: A wrapper around both the libusb and hidraw versions of HIDAPI
//
// The libusb version doesn't support Bluetooth, but not all Linux
// distributions allow access to /dev/hidraw*
//
// This merges the two, at a small performance cost, until distributions
// have granted access to /dev/hidraw*
//
//=============================================================================
#define NAMESPACE HIDRAW
#include "../hidapi/hidapi.h"
#undef NAMESPACE
#undef HIDAPI_H__
#define NAMESPACE HIDUSB
#include "../hidapi/hidapi.h"
#undef NAMESPACE
#undef HIDAPI_H__
#include "../hidapi/hidapi.h"
#include "../../../public/tier1/utlvector.h"
#include "../../../public/tier1/utlhashmap.h"
template <class T>
void CopyHIDDeviceInfo( T *pSrc, struct hid_device_info *pDst )
{
pDst->path = pSrc->path ? strdup( pSrc->path ) : NULL;
pDst->vendor_id = pSrc->vendor_id;
pDst->product_id = pSrc->product_id;
pDst->serial_number = pSrc->serial_number ? wcsdup( pSrc->serial_number ) : NULL;
pDst->release_number = pSrc->release_number;
pDst->manufacturer_string = pSrc->manufacturer_string ? wcsdup( pSrc->manufacturer_string ) : NULL;
pDst->product_string = pSrc->product_string ? wcsdup( pSrc->product_string ) : NULL;
pDst->usage_page = pSrc->usage_page;
pDst->usage = pSrc->usage;
pDst->interface_number = pSrc->interface_number;
pDst->next = NULL;
}
extern "C"
{
enum EHIDAPIType
{
k_EHIDAPIUnknown,
k_EHIDAPIRAW,
k_EHIDAPIUSB
};
static CUtlHashMap<uintptr_t, EHIDAPIType> s_hashDeviceToAPI;
static EHIDAPIType GetAPIForDevice( hid_device *pDevice )
{
int iIndex = s_hashDeviceToAPI.Find( (uintptr_t)pDevice );
if ( iIndex != -1 )
{
return s_hashDeviceToAPI[ iIndex ];
}
return k_EHIDAPIUnknown;
}
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
struct HIDUSB::hid_device_info *usb_devs = HIDUSB::hid_enumerate( vendor_id, product_id );
struct HIDUSB::hid_device_info *usb_dev;
struct HIDRAW::hid_device_info *raw_devs = HIDRAW::hid_enumerate( vendor_id, product_id );
struct HIDRAW::hid_device_info *raw_dev;
struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
for ( usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next )
{
bool bFound = false;
for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next )
{
if ( usb_dev->vendor_id == raw_dev->vendor_id && usb_dev->product_id == raw_dev->product_id )
{
bFound = true;
break;
}
}
//printf("%s USB device VID/PID 0x%.4x/0x%.4x, %ls %ls\n", bFound ? "Found matching" : "Added new", usb_dev->vendor_id, usb_dev->product_id, usb_dev->manufacturer_string, usb_dev->product_string );
if ( !bFound )
{
new_dev = new struct hid_device_info;
CopyHIDDeviceInfo( usb_dev, new_dev );
if ( last )
{
last->next = new_dev;
}
else
{
devs = new_dev;
}
last = new_dev;
}
}
HIDUSB::hid_free_enumeration( usb_devs );
for ( raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next )
{
new_dev = new struct hid_device_info;
CopyHIDDeviceInfo( raw_dev, new_dev );
new_dev->next = NULL;
if ( last )
{
last->next = new_dev;
}
else
{
devs = new_dev;
}
last = new_dev;
}
HIDRAW::hid_free_enumeration( raw_devs );
return devs;
}
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
{
while ( devs )
{
struct hid_device_info *next = devs->next;
free( devs->path );
free( devs->serial_number );
free( devs->manufacturer_string );
free( devs->product_string );
delete devs;
devs = next;
}
}
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
{
hid_device *pDevice = NULL;
if ( ( pDevice = (hid_device *)HIDRAW::hid_open( vendor_id, product_id, serial_number ) ) != NULL )
{
s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW );
return pDevice;
}
if ( ( pDevice = (hid_device *)HIDUSB::hid_open( vendor_id, product_id, serial_number ) ) != NULL )
{
s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB );
return pDevice;
}
return NULL;
}
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive)
{
hid_device *pDevice = NULL;
if ( ( pDevice = (hid_device *)HIDRAW::hid_open_path( path, bExclusive ) ) != NULL )
{
s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIRAW );
return pDevice;
}
if ( ( pDevice = (hid_device *)HIDUSB::hid_open_path( path, bExclusive ) ) != NULL )
{
s_hashDeviceToAPI.Insert( (uintptr_t)pDevice, k_EHIDAPIUSB );
return pDevice;
}
return NULL;
}
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_write( (HIDRAW::hid_device*)device, data, length );
case k_EHIDAPIUSB:
return HIDUSB::hid_write( (HIDUSB::hid_device*)device, data, length );
default:
return -1;
}
}
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_read_timeout( (HIDRAW::hid_device*)device, data, length, milliseconds );
case k_EHIDAPIUSB:
return HIDUSB::hid_read_timeout( (HIDUSB::hid_device*)device, data, length, milliseconds );
default:
return -1;
}
}
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_read( (HIDRAW::hid_device*)device, data, length );
case k_EHIDAPIUSB:
return HIDUSB::hid_read( (HIDUSB::hid_device*)device, data, length );
default:
return -1;
}
}
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_set_nonblocking( (HIDRAW::hid_device*)device, nonblock );
case k_EHIDAPIUSB:
return HIDUSB::hid_set_nonblocking( (HIDUSB::hid_device*)device, nonblock );
default:
return -1;
}
}
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_send_feature_report( (HIDRAW::hid_device*)device, data, length );
case k_EHIDAPIUSB:
return HIDUSB::hid_send_feature_report( (HIDUSB::hid_device*)device, data, length );
default:
return -1;
}
}
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_get_feature_report( (HIDRAW::hid_device*)device, data, length );
case k_EHIDAPIUSB:
return HIDUSB::hid_get_feature_report( (HIDUSB::hid_device*)device, data, length );
default:
return -1;
}
}
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
HIDRAW::hid_close( (HIDRAW::hid_device*)device );
break;
case k_EHIDAPIUSB:
HIDUSB::hid_close( (HIDUSB::hid_device*)device );
break;
default:
break;
}
s_hashDeviceToAPI.Remove( (uintptr_t)device );
}
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_get_manufacturer_string( (HIDRAW::hid_device*)device, string, maxlen );
case k_EHIDAPIUSB:
return HIDUSB::hid_get_manufacturer_string( (HIDUSB::hid_device*)device, string, maxlen );
default:
return -1;
}
}
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_get_product_string( (HIDRAW::hid_device*)device, string, maxlen );
case k_EHIDAPIUSB:
return HIDUSB::hid_get_product_string( (HIDUSB::hid_device*)device, string, maxlen );
default:
return -1;
}
}
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_get_serial_number_string( (HIDRAW::hid_device*)device, string, maxlen );
case k_EHIDAPIUSB:
return HIDUSB::hid_get_serial_number_string( (HIDUSB::hid_device*)device, string, maxlen );
default:
return -1;
}
}
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_get_indexed_string( (HIDRAW::hid_device*)device, string_index, string, maxlen );
case k_EHIDAPIUSB:
return HIDUSB::hid_get_indexed_string( (HIDUSB::hid_device*)device, string_index, string, maxlen );
default:
return -1;
}
}
HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
{
switch ( GetAPIForDevice( device ) )
{
case k_EHIDAPIRAW:
return HIDRAW::hid_error( (HIDRAW::hid_device*)device );
case k_EHIDAPIUSB:
return HIDUSB::hid_error( (HIDUSB::hid_device*)device );
default:
return NULL;
}
}
}

View File

@@ -1,784 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_USBHID
/*
* Joystick driver for the uhid(4) interface found in OpenBSD,
* NetBSD and FreeBSD.
*
* Maintainer: <vedge at csoft.org>
*/
#include <sys/param.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifndef __FreeBSD_kernel_version
#define __FreeBSD_kernel_version __FreeBSD_version
#endif
#if defined(HAVE_USB_H)
#include <usb.h>
#endif
#ifdef __DragonFly__
#include <bus/usb/usb.h>
#include <bus/usb/usbhid.h>
#else
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>
#endif
#if defined(HAVE_USBHID_H)
#include <usbhid.h>
#elif defined(HAVE_LIBUSB_H)
#include <libusb.h>
#elif defined(HAVE_LIBUSBHID_H)
#include <libusbhid.h>
#endif
#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__)
#ifndef __DragonFly__
#include <osreldate.h>
#endif
#if __FreeBSD_kernel_version > 800063
#include <dev/usb/usb_ioctl.h>
#endif
#include <sys/joystick.h>
#endif
#if SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
#include <machine/joystick.h>
#endif
#include "SDL_joystick.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#define MAX_UHID_JOYS 64
#define MAX_JOY_JOYS 2
#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS)
#ifdef __OpenBSD__
#define HUG_DPAD_UP 0x90
#define HUG_DPAD_DOWN 0x91
#define HUG_DPAD_RIGHT 0x92
#define HUG_DPAD_LEFT 0x93
#define HAT_CENTERED 0x00
#define HAT_UP 0x01
#define HAT_RIGHT 0x02
#define HAT_DOWN 0x04
#define HAT_LEFT 0x08
#define HAT_RIGHTUP (HAT_RIGHT|HAT_UP)
#define HAT_RIGHTDOWN (HAT_RIGHT|HAT_DOWN)
#define HAT_LEFTUP (HAT_LEFT|HAT_UP)
#define HAT_LEFTDOWN (HAT_LEFT|HAT_DOWN)
/* calculate the value from the state of the dpad */
int
dpad_to_sdl(Sint32 *dpad)
{
if (dpad[2]) {
if (dpad[0])
return HAT_RIGHTUP;
else if (dpad[1])
return HAT_RIGHTDOWN;
else
return HAT_RIGHT;
} else if (dpad[3]) {
if (dpad[0])
return HAT_LEFTUP;
else if (dpad[1])
return HAT_LEFTDOWN;
else
return HAT_LEFT;
} else if (dpad[0]) {
return HAT_UP;
} else if (dpad[1]) {
return HAT_DOWN;
}
return HAT_CENTERED;
}
#endif
struct report
{
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
void *buf; /* Buffer */
#elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
struct usb_gen_descriptor *buf; /* Buffer */
#else
struct usb_ctl_report *buf; /* Buffer */
#endif
size_t size; /* Buffer size */
int rid; /* Report ID */
enum
{
SREPORT_UNINIT,
SREPORT_CLEAN,
SREPORT_DIRTY
} status;
};
static struct
{
int uhid_report;
hid_kind_t kind;
const char *name;
} const repinfo[] = {
{UHID_INPUT_REPORT, hid_input, "input"},
{UHID_OUTPUT_REPORT, hid_output, "output"},
{UHID_FEATURE_REPORT, hid_feature, "feature"}
};
enum
{
REPORT_INPUT = 0,
REPORT_OUTPUT = 1,
REPORT_FEATURE = 2
};
enum
{
JOYAXE_X,
JOYAXE_Y,
JOYAXE_Z,
JOYAXE_SLIDER,
JOYAXE_WHEEL,
JOYAXE_RX,
JOYAXE_RY,
JOYAXE_RZ,
JOYAXE_count
};
struct joystick_hwdata
{
int fd;
char *path;
enum
{
BSDJOY_UHID, /* uhid(4) */
BSDJOY_JOY /* joy(4) */
} type;
struct report_desc *repdesc;
struct report inreport;
int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */
};
static char *joynames[MAX_JOYS];
static char *joydevnames[MAX_JOYS];
static int report_alloc(struct report *, struct report_desc *, int);
static void report_free(struct report *);
#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data)
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
#define REP_BUF_DATA(rep) ((rep)->buf)
#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data)
#else
#define REP_BUF_DATA(rep) ((rep)->buf->data)
#endif
static int numjoysticks = 0;
static int BSD_JoystickOpen(SDL_Joystick * joy, int device_index);
static void BSD_JoystickClose(SDL_Joystick * joy);
static int
BSD_JoystickInit(void)
{
char s[16];
int i, fd;
numjoysticks = 0;
SDL_memset(joynames, 0, sizeof(joynames));
SDL_memset(joydevnames, 0, sizeof(joydevnames));
for (i = 0; i < MAX_UHID_JOYS; i++) {
SDL_Joystick nj;
SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
joynames[numjoysticks] = SDL_strdup(s);
if (BSD_JoystickOpen(&nj, numjoysticks) == 0) {
BSD_JoystickClose(&nj);
numjoysticks++;
} else {
SDL_free(joynames[numjoysticks]);
joynames[numjoysticks] = NULL;
}
}
for (i = 0; i < MAX_JOY_JOYS; i++) {
SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
fd = open(s, O_RDONLY);
if (fd != -1) {
joynames[numjoysticks++] = SDL_strdup(s);
close(fd);
}
}
/* Read the default USB HID usage table. */
hid_init(NULL);
return (numjoysticks);
}
static int
BSD_JoystickGetCount(void)
{
return numjoysticks;
}
static void
BSD_JoystickDetect(void)
{
}
static const char *
BSD_JoystickGetDeviceName(int device_index)
{
if (joydevnames[device_index] != NULL) {
return (joydevnames[device_index]);
}
return (joynames[device_index]);
}
static int
BSD_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
}
static void
BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
/* Function to perform the mapping from device index to the instance id for this index */
static SDL_JoystickID
BSD_JoystickGetDeviceInstanceID(int device_index)
{
return device_index;
}
static int
usage_to_joyaxe(unsigned usage)
{
int joyaxe;
switch (usage) {
case HUG_X:
joyaxe = JOYAXE_X;
break;
case HUG_Y:
joyaxe = JOYAXE_Y;
break;
case HUG_Z:
joyaxe = JOYAXE_Z;
break;
case HUG_SLIDER:
joyaxe = JOYAXE_SLIDER;
break;
case HUG_WHEEL:
joyaxe = JOYAXE_WHEEL;
break;
case HUG_RX:
joyaxe = JOYAXE_RX;
break;
case HUG_RY:
joyaxe = JOYAXE_RY;
break;
case HUG_RZ:
joyaxe = JOYAXE_RZ;
break;
default:
joyaxe = -1;
}
return joyaxe;
}
static unsigned
hatval_to_sdl(Sint32 hatval)
{
static const unsigned hat_dir_map[8] = {
SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN,
SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP
};
unsigned result;
if ((hatval & 7) == hatval)
result = hat_dir_map[hatval];
else
result = SDL_HAT_CENTERED;
return result;
}
static int
BSD_JoystickOpen(SDL_Joystick * joy, int device_index)
{
char *path = joynames[device_index];
struct joystick_hwdata *hw;
struct hid_item hitem;
struct hid_data *hdata;
struct report *rep = NULL;
#if defined(__NetBSD__)
usb_device_descriptor_t udd;
struct usb_string_desc usd;
#endif
int fd;
int i;
fd = open(path, O_RDONLY);
if (fd == -1) {
return SDL_SetError("%s: %s", path, strerror(errno));
}
joy->instance_id = device_index;
hw = (struct joystick_hwdata *)
SDL_malloc(sizeof(struct joystick_hwdata));
if (hw == NULL) {
close(fd);
return SDL_OutOfMemory();
}
joy->hwdata = hw;
hw->fd = fd;
hw->path = SDL_strdup(path);
if (!SDL_strncmp(path, "/dev/joy", 8)) {
hw->type = BSDJOY_JOY;
joy->naxes = 2;
joy->nbuttons = 2;
joy->nhats = 0;
joy->nballs = 0;
joydevnames[device_index] = SDL_strdup("Gameport joystick");
goto usbend;
} else {
hw->type = BSDJOY_UHID;
}
{
int ax;
for (ax = 0; ax < JOYAXE_count; ax++)
hw->axis_map[ax] = -1;
}
hw->repdesc = hid_get_report_desc(fd);
if (hw->repdesc == NULL) {
SDL_SetError("%s: USB_GET_REPORT_DESC: %s", hw->path,
strerror(errno));
goto usberr;
}
rep = &hw->inreport;
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__)
rep->rid = hid_get_report_id(fd);
if (rep->rid < 0) {
#else
if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) {
#endif
rep->rid = -1; /* XXX */
}
#if defined(__NetBSD__)
if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) == -1)
goto desc_failed;
/* Get default language */
usd.usd_string_index = USB_LANGUAGE_TABLE;
usd.usd_language_id = 0;
if (ioctl(fd, USB_GET_STRING_DESC, &usd) == -1 || usd.usd_desc.bLength < 4) {
usd.usd_language_id = 0;
} else {
usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
}
usd.usd_string_index = udd.iProduct;
if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
char str[128];
char *new_name = NULL;
int i;
for (i = 0; i < (usd.usd_desc.bLength >> 1) - 1 && i < sizeof(str) - 1; i++) {
str[i] = UGETW(usd.usd_desc.bString[i]);
}
str[i] = '\0';
asprintf(&new_name, "%s @ %s", str, path);
if (new_name != NULL) {
SDL_free(joydevnames[numjoysticks]);
joydevnames[numjoysticks] = new_name;
}
}
desc_failed:
#endif
if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) {
goto usberr;
}
if (rep->size <= 0) {
SDL_SetError("%s: Input report descriptor has invalid length",
hw->path);
goto usberr;
}
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid);
#else
hdata = hid_start_parse(hw->repdesc, 1 << hid_input);
#endif
if (hdata == NULL) {
SDL_SetError("%s: Cannot start HID parser", hw->path);
goto usberr;
}
joy->naxes = 0;
joy->nbuttons = 0;
joy->nhats = 0;
joy->nballs = 0;
for (i = 0; i < JOYAXE_count; i++)
hw->axis_map[i] = -1;
while (hid_get_item(hdata, &hitem) > 0) {
char *sp;
const char *s;
switch (hitem.kind) {
case hid_collection:
switch (HID_PAGE(hitem.usage)) {
case HUP_GENERIC_DESKTOP:
switch (HID_USAGE(hitem.usage)) {
case HUG_JOYSTICK:
case HUG_GAME_PAD:
s = hid_usage_in_page(hitem.usage);
sp = SDL_malloc(SDL_strlen(s) + 5);
SDL_snprintf(sp, SDL_strlen(s) + 5, "%s (%d)",
s, device_index);
joydevnames[device_index] = sp;
}
}
break;
case hid_input:
switch (HID_PAGE(hitem.usage)) {
case HUP_GENERIC_DESKTOP:
{
unsigned usage = HID_USAGE(hitem.usage);
int joyaxe = usage_to_joyaxe(usage);
if (joyaxe >= 0) {
hw->axis_map[joyaxe] = 1;
} else if (usage == HUG_HAT_SWITCH
#ifdef __OpenBSD__
|| usage == HUG_DPAD_UP
#endif
) {
joy->nhats++;
}
break;
}
case HUP_BUTTON:
joy->nbuttons++;
break;
default:
break;
}
break;
default:
break;
}
}
hid_end_parse(hdata);
for (i = 0; i < JOYAXE_count; i++)
if (hw->axis_map[i] > 0)
hw->axis_map[i] = joy->naxes++;
if (joy->naxes == 0 && joy->nbuttons == 0 && joy->nhats == 0 && joy->nballs == 0) {
SDL_SetError("%s: Not a joystick, ignoring", hw->path);
goto usberr;
}
usbend:
/* The poll blocks the event thread. */
fcntl(fd, F_SETFL, O_NONBLOCK);
#ifdef __NetBSD__
/* Flush pending events */
if (rep) {
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size)
;
}
#endif
return (0);
usberr:
close(hw->fd);
SDL_free(hw->path);
SDL_free(hw);
return (-1);
}
static void
BSD_JoystickUpdate(SDL_Joystick * joy)
{
struct hid_item hitem;
struct hid_data *hdata;
struct report *rep;
int nbutton, naxe = -1;
Sint32 v;
#ifdef __OpenBSD__
Sint32 dpad[4] = {0, 0, 0, 0};
#endif
#if defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__)
struct joystick gameport;
static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0;
if (joy->hwdata->type == BSDJOY_JOY) {
while (read(joy->hwdata->fd, &gameport, sizeof gameport) == sizeof gameport) {
if (abs(x - gameport.x) > 8) {
x = gameport.x;
if (x < xmin) {
xmin = x;
}
if (x > xmax) {
xmax = x;
}
if (xmin == xmax) {
xmin--;
xmax++;
}
v = (Sint32) x;
v -= (xmax + xmin + 1) / 2;
v *= 32768 / ((xmax - xmin + 1) / 2);
SDL_PrivateJoystickAxis(joy, 0, v);
}
if (abs(y - gameport.y) > 8) {
y = gameport.y;
if (y < ymin) {
ymin = y;
}
if (y > ymax) {
ymax = y;
}
if (ymin == ymax) {
ymin--;
ymax++;
}
v = (Sint32) y;
v -= (ymax + ymin + 1) / 2;
v *= 32768 / ((ymax - ymin + 1) / 2);
SDL_PrivateJoystickAxis(joy, 1, v);
}
SDL_PrivateJoystickButton(joy, 0, gameport.b1);
SDL_PrivateJoystickButton(joy, 1, gameport.b2);
}
return;
}
#endif /* defined(__FREEBSD__) || SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */
rep = &joy->hwdata->inreport;
while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) {
#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__)
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid);
#else
hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input);
#endif
if (hdata == NULL) {
/*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/
continue;
}
for (nbutton = 0; hid_get_item(hdata, &hitem) > 0;) {
switch (hitem.kind) {
case hid_input:
switch (HID_PAGE(hitem.usage)) {
case HUP_GENERIC_DESKTOP:
{
unsigned usage = HID_USAGE(hitem.usage);
int joyaxe = usage_to_joyaxe(usage);
if (joyaxe >= 0) {
naxe = joy->hwdata->axis_map[joyaxe];
/* scaleaxe */
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
v -= (hitem.logical_maximum +
hitem.logical_minimum + 1) / 2;
v *= 32768 /
((hitem.logical_maximum -
hitem.logical_minimum + 1) / 2);
SDL_PrivateJoystickAxis(joy, naxe, v);
} else if (usage == HUG_HAT_SWITCH) {
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickHat(joy, 0,
hatval_to_sdl(v) -
hitem.logical_minimum);
}
#ifdef __OpenBSD__
else if (usage == HUG_DPAD_UP) {
dpad[0] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
}
else if (usage == HUG_DPAD_DOWN) {
dpad[1] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
}
else if (usage == HUG_DPAD_RIGHT) {
dpad[2] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
}
else if (usage == HUG_DPAD_LEFT) {
dpad[3] = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad));
}
#endif
break;
}
case HUP_BUTTON:
v = (Sint32) hid_get_data(REP_BUF_DATA(rep), &hitem);
SDL_PrivateJoystickButton(joy, nbutton, v);
nbutton++;
break;
default:
continue;
}
break;
default:
break;
}
}
hid_end_parse(hdata);
}
}
/* Function to close a joystick after use */
static void
BSD_JoystickClose(SDL_Joystick * joy)
{
if (SDL_strncmp(joy->hwdata->path, "/dev/joy", 8)) {
report_free(&joy->hwdata->inreport);
hid_dispose_report_desc(joy->hwdata->repdesc);
}
close(joy->hwdata->fd);
SDL_free(joy->hwdata->path);
SDL_free(joy->hwdata);
}
static void
BSD_JoystickQuit(void)
{
int i;
for (i = 0; i < MAX_JOYS; i++) {
SDL_free(joynames[i]);
SDL_free(joydevnames[i]);
}
return;
}
static SDL_JoystickGUID
BSD_JoystickGetDeviceGUID( int device_index )
{
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = BSD_JoystickGetDeviceName( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
return guid;
}
static int
report_alloc(struct report *r, struct report_desc *rd, int repind)
{
int len;
#ifdef __DragonFly__
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
#elif __FREEBSD__
# if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__)
# if (__FreeBSD_kernel_version <= 500111)
len = hid_report_size(rd, r->rid, repinfo[repind].kind);
# else
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
# endif
# else
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
# endif
#else
# ifdef USBHID_NEW
len = hid_report_size(rd, repinfo[repind].kind, r->rid);
# else
len = hid_report_size(rd, repinfo[repind].kind, &r->rid);
# endif
#endif
if (len < 0) {
return SDL_SetError("Negative HID report size");
}
r->size = len;
if (r->size > 0) {
#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
r->buf = SDL_malloc(r->size);
#else
r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) +
r->size);
#endif
if (r->buf == NULL) {
return SDL_OutOfMemory();
}
} else {
r->buf = NULL;
}
r->status = SREPORT_CLEAN;
return 0;
}
static void
report_free(struct report *r)
{
SDL_free(r->buf);
r->status = SREPORT_UNINIT;
}
static int
BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
return SDL_Unsupported();
}
SDL_JoystickDriver SDL_BSD_JoystickDriver =
{
BSD_JoystickInit,
BSD_JoystickGetCount,
BSD_JoystickDetect,
BSD_JoystickGetDeviceName,
BSD_JoystickGetDevicePlayerIndex,
BSD_JoystickSetDevicePlayerIndex,
BSD_JoystickGetDeviceGUID,
BSD_JoystickGetDeviceInstanceID,
BSD_JoystickOpen,
BSD_JoystickRumble,
BSD_JoystickUpdate,
BSD_JoystickClose,
BSD_JoystickQuit,
};
#endif /* SDL_JOYSTICK_USBHID */
/* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_JOYSTICK_IOKIT_H
#define SDL_JOYSTICK_IOKIT_H
#include <IOKit/hid/IOHIDLib.h>
#include <ForceFeedback/ForceFeedback.h>
#include <ForceFeedback/ForceFeedbackConstants.h>
struct recElement
{
IOHIDElementRef elementRef;
IOHIDElementCookie cookie;
uint32_t usagePage, usage; /* HID usage */
SInt32 min; /* reported min value possible */
SInt32 max; /* reported max value possible */
/* runtime variables used for auto-calibration */
SInt32 minReport; /* min returned value */
SInt32 maxReport; /* max returned value */
struct recElement *pNext; /* next element in list */
};
typedef struct recElement recElement;
struct joystick_hwdata
{
IOHIDDeviceRef deviceRef; /* HIDManager device handle */
io_service_t ffservice; /* Interface for force feedback, 0 = no ff */
FFDeviceObjectReference ffdevice;
FFEFFECT *ffeffect;
FFEffectObjectReference ffeffect_ref;
SDL_bool ff_initialized;
char product[256]; /* name of product */
uint32_t usage; /* usage page from IOUSBHID Parser.h which defines general usage */
uint32_t usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */
int axes; /* number of axis (calculated, not reported by device) */
int buttons; /* number of buttons (calculated, not reported by device) */
int hats; /* number of hat switches (calculated, not reported by device) */
int elements; /* number of total elements (should be total of above) (calculated, not reported by device) */
recElement *firstAxis;
recElement *firstButton;
recElement *firstHat;
SDL_bool removed;
int instance_id;
SDL_JoystickGUID guid;
struct joystick_hwdata *pNext; /* next device */
};
typedef struct joystick_hwdata recDevice;
#endif /* SDL_JOYSTICK_IOKIT_H */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,863 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
/* This is the iOS implementation of the SDL joystick API */
#include "SDL_sysjoystick_c.h"
/* needed for SDL_IPHONE_MAX_GFORCE macro */
#include "../../../include/SDL_config_iphoneos.h"
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_joystick.h"
#include "SDL_hints.h"
#include "SDL_stdinc.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#if !SDL_EVENTS_DISABLED
#include "../../events/SDL_events_c.h"
#endif
#if !TARGET_OS_TV
#import <CoreMotion/CoreMotion.h>
#endif
#ifdef SDL_JOYSTICK_MFI
#import <GameController/GameController.h>
static id connectObserver = nil;
static id disconnectObserver = nil;
#include <Availability.h>
#include <objc/message.h>
/* remove compilation warnings for strict builds by defining these selectors, even though
* they are only ever used indirectly through objc_msgSend
*/
@interface GCExtendedGamepad (SDL)
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 121000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1401000)
@property (nonatomic, readonly, nullable) GCControllerButtonInput *leftThumbstickButton;
@property (nonatomic, readonly, nullable) GCControllerButtonInput *rightThumbstickButton;
#endif
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 130000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1500000)
@property (nonatomic, readonly) GCControllerButtonInput *buttonMenu;
@property (nonatomic, readonly, nullable) GCControllerButtonInput *buttonOptions;
#endif
@end
@interface GCMicroGamepad (SDL)
#if (__IPHONE_OS_VERSION_MAX_ALLOWED < 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED < 130000) || (__MAC_OS_VERSION_MAX_ALLOWED < 1500000)
@property (nonatomic, readonly) GCControllerButtonInput *buttonMenu;
#endif
@end
#endif /* SDL_JOYSTICK_MFI */
#if !TARGET_OS_TV
static const char *accelerometerName = "iOS Accelerometer";
static CMMotionManager *motionManager = nil;
#endif /* !TARGET_OS_TV */
static SDL_JoystickDeviceItem *deviceList = NULL;
static int numjoysticks = 0;
int SDL_AppleTVRemoteOpenedAsJoystick = 0;
static SDL_JoystickDeviceItem *
GetDeviceForIndex(int device_index)
{
SDL_JoystickDeviceItem *device = deviceList;
int i = 0;
while (i < device_index) {
if (device == NULL) {
return NULL;
}
device = device->next;
i++;
}
return device;
}
static void
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
{
#ifdef SDL_JOYSTICK_MFI
const Uint16 VENDOR_APPLE = 0x05AC;
const Uint16 VENDOR_MICROSOFT = 0x045e;
const Uint16 VENDOR_SONY = 0x054C;
Uint16 *guid16 = (Uint16 *)device->guid.data;
Uint16 vendor = 0;
Uint16 product = 0;
Uint8 subtype = 0;
const char *name = NULL;
/* Explicitly retain the controller because SDL_JoystickDeviceItem is a
* struct, and ARC doesn't work with structs. */
device->controller = (__bridge GCController *) CFBridgingRetain(controller);
if (controller.vendorName) {
name = controller.vendorName.UTF8String;
}
if (!name) {
name = "MFi Gamepad";
}
device->name = SDL_strdup(name);
if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
BOOL is_xbox = [controller.vendorName containsString: @"Xbox"];
BOOL is_ps4 = [controller.vendorName containsString: @"DUALSHOCK"];
#if TARGET_OS_TV
BOOL is_MFi = (!is_xbox && !is_ps4);
#endif
int nbuttons = 0;
/* These buttons are part of the original MFi spec */
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
nbuttons += 6;
/* These buttons are available on some newer controllers */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
if ([gamepad respondsToSelector:@selector(leftThumbstickButton)] && gamepad.leftThumbstickButton) {
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK);
++nbuttons;
}
if ([gamepad respondsToSelector:@selector(rightThumbstickButton)] && gamepad.rightThumbstickButton) {
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK);
++nbuttons;
}
if ([gamepad respondsToSelector:@selector(buttonOptions)] && gamepad.buttonOptions) {
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_BACK);
++nbuttons;
}
BOOL has_direct_menu = [gamepad respondsToSelector:@selector(buttonMenu)] && gamepad.buttonMenu;
#if TARGET_OS_TV
/* On tvOS MFi controller menu button brings you to the home screen */
if (is_MFi) {
has_direct_menu = FALSE;
}
#endif
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
++nbuttons;
if (!has_direct_menu) {
device->uses_pause_handler = SDL_TRUE;
}
#pragma clang diagnostic pop
if (is_xbox) {
vendor = VENDOR_MICROSOFT;
product = 0x02E0; /* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
} else if (is_ps4) {
vendor = VENDOR_SONY;
product = 0x09CC; /* Assume DS4 Slim unless/until GCController flows VID/PID */
} else {
vendor = VENDOR_APPLE;
product = 1;
subtype = 1;
}
device->naxes = 6; /* 2 thumbsticks and 2 triggers */
device->nhats = 1; /* d-pad */
device->nbuttons = nbuttons;
} else if (controller.gamepad) {
int nbuttons = 0;
/* These buttons are part of the original MFi spec */
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
nbuttons += 7;
device->uses_pause_handler = SDL_TRUE;
vendor = VENDOR_APPLE;
product = 2;
subtype = 2;
device->naxes = 0; /* no traditional analog inputs */
device->nhats = 1; /* d-pad */
device->nbuttons = nbuttons;
}
#if TARGET_OS_TV
else if (controller.microGamepad) {
int nbuttons = 0;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A);
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); /* Button X on microGamepad */
nbuttons += 2;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
++nbuttons;
device->uses_pause_handler = SDL_TRUE;
vendor = VENDOR_APPLE;
product = 3;
subtype = 3;
device->naxes = 2; /* treat the touch surface as two axes */
device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
device->nbuttons = nbuttons;
controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE);
}
#endif /* TARGET_OS_TV */
/* We only need 16 bits for each of these; space them out to fill 128. */
/* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(device->button_mask);
if (subtype != 0) {
/* Note that this is an MFI controller and what subtype it is */
device->guid.data[14] = 'm';
device->guid.data[15] = subtype;
}
/* This will be set when the first button press of the controller is
* detected. */
controller.playerIndex = -1;
#endif /* SDL_JOYSTICK_MFI */
}
static void
IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
{
SDL_JoystickDeviceItem *device = deviceList;
#if TARGET_OS_TV
if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) {
/* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */
if (controller && !controller.extendedGamepad && !controller.gamepad && controller.microGamepad) {
return;
}
}
#endif
while (device != NULL) {
if (device->controller == controller) {
return;
}
device = device->next;
}
device = (SDL_JoystickDeviceItem *) SDL_calloc(1, sizeof(SDL_JoystickDeviceItem));
if (device == NULL) {
return;
}
device->accelerometer = accelerometer;
device->instance_id = SDL_GetNextJoystickInstanceID();
if (accelerometer) {
#if TARGET_OS_TV
SDL_free(device);
return;
#else
device->name = SDL_strdup(accelerometerName);
device->naxes = 3; /* Device acceleration in the x, y, and z axes. */
device->nhats = 0;
device->nbuttons = 0;
/* Use the accelerometer name as a GUID. */
SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name)));
#endif /* TARGET_OS_TV */
} else if (controller) {
IOS_AddMFIJoystickDevice(device, controller);
}
if (deviceList == NULL) {
deviceList = device;
} else {
SDL_JoystickDeviceItem *lastdevice = deviceList;
while (lastdevice->next != NULL) {
lastdevice = lastdevice->next;
}
lastdevice->next = device;
}
++numjoysticks;
SDL_PrivateJoystickAdded(device->instance_id);
}
static SDL_JoystickDeviceItem *
IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
{
SDL_JoystickDeviceItem *prev = NULL;
SDL_JoystickDeviceItem *next = NULL;
SDL_JoystickDeviceItem *item = deviceList;
if (device == NULL) {
return NULL;
}
next = device->next;
while (item != NULL) {
if (item == device) {
break;
}
prev = item;
item = item->next;
}
/* Unlink the device item from the device list. */
if (prev) {
prev->next = device->next;
} else if (device == deviceList) {
deviceList = device->next;
}
if (device->joystick) {
device->joystick->hwdata = NULL;
}
#ifdef SDL_JOYSTICK_MFI
@autoreleasepool {
if (device->controller) {
/* The controller was explicitly retained in the struct, so it
* should be explicitly released before freeing the struct. */
GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller));
controller.controllerPausedHandler = nil;
device->controller = nil;
}
}
#endif /* SDL_JOYSTICK_MFI */
--numjoysticks;
SDL_PrivateJoystickRemoved(device->instance_id);
SDL_free(device->name);
SDL_free(device);
return next;
}
#if TARGET_OS_TV
static void SDLCALL
SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue)
{
BOOL allowRotation = newValue != NULL && *newValue != '0';
@autoreleasepool {
for (GCController *controller in [GCController controllers]) {
if (controller.microGamepad) {
controller.microGamepad.allowsRotation = allowRotation;
}
}
}
}
#endif /* TARGET_OS_TV */
static int
IOS_JoystickInit(void)
{
@autoreleasepool {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
#if !TARGET_OS_TV
if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
/* Default behavior, accelerometer as joystick */
IOS_AddJoystickDevice(nil, SDL_TRUE);
}
#endif /* !TARGET_OS_TV */
#ifdef SDL_JOYSTICK_MFI
/* GameController.framework was added in iOS 7. */
if (![GCController class]) {
return 0;
}
for (GCController *controller in [GCController controllers]) {
IOS_AddJoystickDevice(controller, SDL_FALSE);
}
#if TARGET_OS_TV
SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
SDL_AppleTVRemoteRotationHintChanged, NULL);
#endif /* TARGET_OS_TV */
connectObserver = [center addObserverForName:GCControllerDidConnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCController *controller = note.object;
IOS_AddJoystickDevice(controller, SDL_FALSE);
}];
disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCController *controller = note.object;
SDL_JoystickDeviceItem *device = deviceList;
while (device != NULL) {
if (device->controller == controller) {
IOS_RemoveJoystickDevice(device);
break;
}
device = device->next;
}
}];
#endif /* SDL_JOYSTICK_MFI */
}
return 0;
}
static int
IOS_JoystickGetCount(void)
{
return numjoysticks;
}
static void
IOS_JoystickDetect(void)
{
}
static const char *
IOS_JoystickGetDeviceName(int device_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
return device ? device->name : "Unknown";
}
static int
IOS_JoystickGetDevicePlayerIndex(int device_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
return device ? (int)device->controller.playerIndex : -1;
}
static void
IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
if (device) {
device->controller.playerIndex = player_index;
}
}
static SDL_JoystickGUID
IOS_JoystickGetDeviceGUID( int device_index )
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
SDL_JoystickGUID guid;
if (device) {
guid = device->guid;
} else {
SDL_zero(guid);
}
return guid;
}
static SDL_JoystickID
IOS_JoystickGetDeviceInstanceID(int device_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
return device ? device->instance_id : -1;
}
static int
IOS_JoystickOpen(SDL_Joystick * joystick, int device_index)
{
SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
if (device == NULL) {
return SDL_SetError("Could not open Joystick: no hardware device for the specified index");
}
joystick->hwdata = device;
joystick->instance_id = device->instance_id;
joystick->naxes = device->naxes;
joystick->nhats = device->nhats;
joystick->nbuttons = device->nbuttons;
joystick->nballs = 0;
device->joystick = joystick;
@autoreleasepool {
if (device->accelerometer) {
#if !TARGET_OS_TV
if (motionManager == nil) {
motionManager = [[CMMotionManager alloc] init];
}
/* Shorter times between updates can significantly increase CPU usage. */
motionManager.accelerometerUpdateInterval = 0.1;
[motionManager startAccelerometerUpdates];
#endif /* !TARGET_OS_TV */
} else {
#ifdef SDL_JOYSTICK_MFI
if (device->uses_pause_handler) {
GCController *controller = device->controller;
controller.controllerPausedHandler = ^(GCController *c) {
if (joystick->hwdata) {
++joystick->hwdata->num_pause_presses;
}
};
}
#endif /* SDL_JOYSTICK_MFI */
}
}
if (device->remote) {
++SDL_AppleTVRemoteOpenedAsJoystick;
}
return 0;
}
static void
IOS_AccelerometerUpdate(SDL_Joystick * joystick)
{
#if !TARGET_OS_TV
const float maxgforce = SDL_IPHONE_MAX_GFORCE;
const SInt16 maxsint16 = 0x7FFF;
CMAcceleration accel;
@autoreleasepool {
if (!motionManager.isAccelerometerActive) {
return;
}
accel = motionManager.accelerometerData.acceleration;
}
/*
Convert accelerometer data from floating point to Sint16, which is what
the joystick system expects.
To do the conversion, the data is first clamped onto the interval
[-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied
by MAX_SINT16 so that it is mapped to the full range of an Sint16.
You can customize the clamped range of this function by modifying the
SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h.
Once converted to Sint16, the accelerometer data no longer has coherent
units. You can convert the data back to units of g-force by multiplying
it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
*/
/* clamp the data */
accel.x = SDL_min(SDL_max(accel.x, -maxgforce), maxgforce);
accel.y = SDL_min(SDL_max(accel.y, -maxgforce), maxgforce);
accel.z = SDL_min(SDL_max(accel.z, -maxgforce), maxgforce);
/* pass in data mapped to range of SInt16 */
SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16);
SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16);
SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16);
#endif /* !TARGET_OS_TV */
}
#ifdef SDL_JOYSTICK_MFI
static Uint8
IOS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad)
{
Uint8 hat = 0;
if (dpad.up.isPressed) {
hat |= SDL_HAT_UP;
} else if (dpad.down.isPressed) {
hat |= SDL_HAT_DOWN;
}
if (dpad.left.isPressed) {
hat |= SDL_HAT_LEFT;
} else if (dpad.right.isPressed) {
hat |= SDL_HAT_RIGHT;
}
if (hat == 0) {
return SDL_HAT_CENTERED;
}
return hat;
}
#endif
static void
IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
{
#if SDL_JOYSTICK_MFI
@autoreleasepool {
GCController *controller = joystick->hwdata->controller;
Uint8 hatstate = SDL_HAT_CENTERED;
int i;
int pause_button_index = 0;
if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
/* Axis order matches the XInput Windows mappings. */
Sint16 axes[] = {
(Sint16) (gamepad.leftThumbstick.xAxis.value * 32767),
(Sint16) (gamepad.leftThumbstick.yAxis.value * -32767),
(Sint16) ((gamepad.leftTrigger.value * 65535) - 32768),
(Sint16) (gamepad.rightThumbstick.xAxis.value * 32767),
(Sint16) (gamepad.rightThumbstick.yAxis.value * -32767),
(Sint16) ((gamepad.rightTrigger.value * 65535) - 32768),
};
/* Button order matches the XInput Windows mappings. */
Uint8 buttons[joystick->nbuttons];
int button_count = 0;
/* These buttons are part of the original MFi spec */
buttons[button_count++] = gamepad.buttonA.isPressed;
buttons[button_count++] = gamepad.buttonB.isPressed;
buttons[button_count++] = gamepad.buttonX.isPressed;
buttons[button_count++] = gamepad.buttonY.isPressed;
buttons[button_count++] = gamepad.leftShoulder.isPressed;
buttons[button_count++] = gamepad.rightShoulder.isPressed;
/* These buttons are available on some newer controllers */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
buttons[button_count++] = gamepad.leftThumbstickButton.isPressed;
}
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
buttons[button_count++] = gamepad.rightThumbstickButton.isPressed;
}
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
buttons[button_count++] = gamepad.buttonOptions.isPressed;
}
/* This must be the last button, so we can optionally handle it with pause_button_index below */
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
if (joystick->hwdata->uses_pause_handler) {
pause_button_index = button_count;
buttons[button_count++] = joystick->delayed_guide_button;
} else {
buttons[button_count++] = gamepad.buttonMenu.isPressed;
}
}
#pragma clang diagnostic pop
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
for (i = 0; i < SDL_arraysize(axes); i++) {
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
}
for (i = 0; i < button_count; i++) {
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
} else if (controller.gamepad) {
GCGamepad *gamepad = controller.gamepad;
/* Button order matches the XInput Windows mappings. */
Uint8 buttons[joystick->nbuttons];
int button_count = 0;
buttons[button_count++] = gamepad.buttonA.isPressed;
buttons[button_count++] = gamepad.buttonB.isPressed;
buttons[button_count++] = gamepad.buttonX.isPressed;
buttons[button_count++] = gamepad.buttonY.isPressed;
buttons[button_count++] = gamepad.leftShoulder.isPressed;
buttons[button_count++] = gamepad.rightShoulder.isPressed;
pause_button_index = button_count;
buttons[button_count++] = joystick->delayed_guide_button;
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);
for (i = 0; i < button_count; i++) {
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
}
#if TARGET_OS_TV
else if (controller.microGamepad) {
GCMicroGamepad *gamepad = controller.microGamepad;
Sint16 axes[] = {
(Sint16) (gamepad.dpad.xAxis.value * 32767),
(Sint16) (gamepad.dpad.yAxis.value * -32767),
};
for (i = 0; i < SDL_arraysize(axes); i++) {
SDL_PrivateJoystickAxis(joystick, i, axes[i]);
}
Uint8 buttons[joystick->nbuttons];
int button_count = 0;
buttons[button_count++] = gamepad.buttonA.isPressed;
buttons[button_count++] = gamepad.buttonX.isPressed;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
/* This must be the last button, so we can optionally handle it with pause_button_index below */
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
if (joystick->hwdata->uses_pause_handler) {
pause_button_index = button_count;
buttons[button_count++] = joystick->delayed_guide_button;
} else {
buttons[button_count++] = gamepad.buttonMenu.isPressed;
}
}
#pragma clang diagnostic pop
for (i = 0; i < button_count; i++) {
SDL_PrivateJoystickButton(joystick, i, buttons[i]);
}
}
#endif /* TARGET_OS_TV */
if (joystick->nhats > 0) {
SDL_PrivateJoystickHat(joystick, 0, hatstate);
}
if (joystick->hwdata->uses_pause_handler) {
for (i = 0; i < joystick->hwdata->num_pause_presses; i++) {
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_PRESSED);
SDL_PrivateJoystickButton(joystick, pause_button_index, SDL_RELEASED);
}
joystick->hwdata->num_pause_presses = 0;
}
}
#endif /* SDL_JOYSTICK_MFI */
}
static int
IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
return SDL_Unsupported();
}
static void
IOS_JoystickUpdate(SDL_Joystick * joystick)
{
SDL_JoystickDeviceItem *device = joystick->hwdata;
if (device == NULL) {
return;
}
if (device->accelerometer) {
IOS_AccelerometerUpdate(joystick);
} else if (device->controller) {
IOS_MFIJoystickUpdate(joystick);
}
}
static void
IOS_JoystickClose(SDL_Joystick * joystick)
{
SDL_JoystickDeviceItem *device = joystick->hwdata;
if (device == NULL) {
return;
}
device->joystick = NULL;
@autoreleasepool {
if (device->accelerometer) {
#if !TARGET_OS_TV
[motionManager stopAccelerometerUpdates];
#endif /* !TARGET_OS_TV */
} else if (device->controller) {
#ifdef SDL_JOYSTICK_MFI
GCController *controller = device->controller;
controller.controllerPausedHandler = nil;
controller.playerIndex = -1;
#endif
}
}
if (device->remote) {
--SDL_AppleTVRemoteOpenedAsJoystick;
}
}
static void
IOS_JoystickQuit(void)
{
@autoreleasepool {
#ifdef SDL_JOYSTICK_MFI
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
if (connectObserver) {
[center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil];
connectObserver = nil;
}
if (disconnectObserver) {
[center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil];
disconnectObserver = nil;
}
#if TARGET_OS_TV
SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION,
SDL_AppleTVRemoteRotationHintChanged, NULL);
#endif /* TARGET_OS_TV */
#endif /* SDL_JOYSTICK_MFI */
while (deviceList != NULL) {
IOS_RemoveJoystickDevice(deviceList);
}
#if !TARGET_OS_TV
motionManager = nil;
#endif /* !TARGET_OS_TV */
}
numjoysticks = 0;
}
SDL_JoystickDriver SDL_IOS_JoystickDriver =
{
IOS_JoystickInit,
IOS_JoystickGetCount,
IOS_JoystickDetect,
IOS_JoystickGetDeviceName,
IOS_JoystickGetDevicePlayerIndex,
IOS_JoystickSetDevicePlayerIndex,
IOS_JoystickGetDeviceGUID,
IOS_JoystickGetDeviceInstanceID,
IOS_JoystickOpen,
IOS_JoystickRumble,
IOS_JoystickUpdate,
IOS_JoystickClose,
IOS_JoystickQuit,
};
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,59 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_JOYSTICK_IOS_H
#define SDL_JOYSTICK_IOS_H
#include "SDL_stdinc.h"
#include "../SDL_sysjoystick.h"
@class GCController;
typedef struct joystick_hwdata
{
SDL_bool accelerometer;
SDL_bool remote;
GCController __unsafe_unretained *controller;
SDL_bool uses_pause_handler;
int num_pause_presses;
Uint32 pause_button_down_time;
char *name;
SDL_Joystick *joystick;
SDL_JoystickID instance_id;
SDL_JoystickGUID guid;
int naxes;
int nbuttons;
int nhats;
Uint16 button_mask;
struct joystick_hwdata *next;
} joystick_hwdata;
typedef joystick_hwdata SDL_JoystickDeviceItem;
#endif /* SDL_JOYSTICK_IOS_H */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,515 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_WINMM
/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
#include "../../core/windows/SDL_windows.h"
#include <mmsystem.h>
#include <regstr.h>
#include "SDL_events.h"
#include "SDL_joystick.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#ifdef REGSTR_VAL_JOYOEMNAME
#undef REGSTR_VAL_JOYOEMNAME
#endif
#define REGSTR_VAL_JOYOEMNAME "OEMName"
#define MAX_JOYSTICKS 16
#define MAX_AXES 6 /* each joystick can have up to 6 axes */
#define MAX_BUTTONS 32 /* and 32 buttons */
#define JOY_BUTTON_FLAG(n) (1<<n)
/* array to hold joystick ID values */
static UINT SYS_JoystickID[MAX_JOYSTICKS];
static JOYCAPSA SYS_Joystick[MAX_JOYSTICKS];
static char *SYS_JoystickName[MAX_JOYSTICKS];
/* The private structure used to keep track of a joystick */
struct joystick_hwdata
{
/* joystick ID */
UINT id;
/* values used to translate device-specific coordinates into
SDL-standard ranges */
struct _transaxis
{
int offset;
float scale;
} transaxis[6];
};
/* Convert a Windows Multimedia API return code to a text message */
static void SetMMerror(char *function, int code);
static char *
GetJoystickName(int index, const char *szRegKey)
{
/* added 7/24/2004 by Eckhard Stolberg */
/*
see if there is a joystick for the current
index (1-16) listed in the registry
*/
char *name = NULL;
HKEY hTopKey;
HKEY hKey;
DWORD regsize;
LONG regresult;
char regkey[256];
char regvalue[256];
char regname[256];
SDL_snprintf(regkey, SDL_arraysize(regkey),
#ifdef UNICODE
"%S\\%s\\%S",
#else
"%s\\%s\\%s",
#endif
REGSTR_PATH_JOYCONFIG, szRegKey, REGSTR_KEY_JOYCURR);
hTopKey = HKEY_LOCAL_MACHINE;
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
if (regresult != ERROR_SUCCESS) {
hTopKey = HKEY_CURRENT_USER;
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
}
if (regresult != ERROR_SUCCESS) {
return NULL;
}
/* find the registry key name for the joystick's properties */
regsize = sizeof(regname);
SDL_snprintf(regvalue, SDL_arraysize(regvalue), "Joystick%d%s", index + 1,
REGSTR_VAL_JOYOEMNAME);
regresult =
RegQueryValueExA(hKey, regvalue, 0, 0, (LPBYTE) regname, &regsize);
RegCloseKey(hKey);
if (regresult != ERROR_SUCCESS) {
return NULL;
}
/* open that registry key */
SDL_snprintf(regkey, SDL_arraysize(regkey),
#ifdef UNICODE
"%S\\%s",
#else
"%s\\%s",
#endif
REGSTR_PATH_JOYOEM, regname);
regresult = RegOpenKeyExA(hTopKey, regkey, 0, KEY_READ, &hKey);
if (regresult != ERROR_SUCCESS) {
return NULL;
}
/* find the size for the OEM name text */
regsize = sizeof(regvalue);
regresult =
RegQueryValueExA(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, NULL, &regsize);
if (regresult == ERROR_SUCCESS) {
/* allocate enough memory for the OEM name text ... */
name = (char *) SDL_malloc(regsize);
if (name) {
/* ... and read it from the registry */
regresult = RegQueryValueExA(hKey,
REGSTR_VAL_JOYOEMNAME, 0, 0,
(LPBYTE) name, &regsize);
}
}
RegCloseKey(hKey);
return (name);
}
static int numjoysticks = 0;
/* Function to scan the system for joysticks.
* Joystick 0 should be the system default joystick.
* It should return 0, or -1 on an unrecoverable fatal error.
*/
static int
WINMM_JoystickInit(void)
{
int i;
int maxdevs;
JOYINFOEX joyinfo;
JOYCAPSA joycaps;
MMRESULT result;
/* Reset the joystick ID & name mapping tables */
for (i = 0; i < MAX_JOYSTICKS; ++i) {
SYS_JoystickID[i] = 0;
SYS_JoystickName[i] = NULL;
}
/* Loop over all potential joystick devices */
numjoysticks = 0;
maxdevs = joyGetNumDevs();
for (i = JOYSTICKID1; i < maxdevs && numjoysticks < MAX_JOYSTICKS; ++i) {
joyinfo.dwSize = sizeof(joyinfo);
joyinfo.dwFlags = JOY_RETURNALL;
result = joyGetPosEx(i, &joyinfo);
if (result == JOYERR_NOERROR) {
result = joyGetDevCapsA(i, &joycaps, sizeof(joycaps));
if (result == JOYERR_NOERROR) {
SYS_JoystickID[numjoysticks] = i;
SYS_Joystick[numjoysticks] = joycaps;
SYS_JoystickName[numjoysticks] =
GetJoystickName(i, joycaps.szRegKey);
numjoysticks++;
}
}
}
return numjoysticks;
}
static int
WINMM_NumJoysticks(void)
{
return numjoysticks;
}
static void
WINMM_JoystickDetect(void)
{
}
/* Function to get the device-dependent name of a joystick */
static const char *
WINMM_JoystickGetDeviceName(int device_index)
{
if (SYS_JoystickName[device_index] != NULL) {
return (SYS_JoystickName[device_index]);
} else {
return (SYS_Joystick[device_index].szPname);
}
}
static int
WINMM_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
}
static void
WINMM_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
}
static SDL_JoystickGUID WINMM_JoystickGetDeviceGUID(int device_index)
{
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = WINMM_JoystickGetDeviceName(device_index);
SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
return guid;
}
/* Function to perform the mapping from device index to the instance id for this index */
static SDL_JoystickID WINMM_JoystickGetDeviceInstanceID(int device_index)
{
return device_index;
}
/* Function to open a joystick for use.
The joystick to open is specified by the device index.
This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error.
*/
static int
WINMM_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
int index, i;
int caps_flags[MAX_AXES - 2] =
{ JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
int axis_min[MAX_AXES], axis_max[MAX_AXES];
/* shortcut */
index = device_index;
axis_min[0] = SYS_Joystick[index].wXmin;
axis_max[0] = SYS_Joystick[index].wXmax;
axis_min[1] = SYS_Joystick[index].wYmin;
axis_max[1] = SYS_Joystick[index].wYmax;
axis_min[2] = SYS_Joystick[index].wZmin;
axis_max[2] = SYS_Joystick[index].wZmax;
axis_min[3] = SYS_Joystick[index].wRmin;
axis_max[3] = SYS_Joystick[index].wRmax;
axis_min[4] = SYS_Joystick[index].wUmin;
axis_max[4] = SYS_Joystick[index].wUmax;
axis_min[5] = SYS_Joystick[index].wVmin;
axis_max[5] = SYS_Joystick[index].wVmax;
/* allocate memory for system specific hardware data */
joystick->instance_id = device_index;
joystick->hwdata =
(struct joystick_hwdata *) SDL_malloc(sizeof(*joystick->hwdata));
if (joystick->hwdata == NULL) {
return SDL_OutOfMemory();
}
SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
/* set hardware data */
joystick->hwdata->id = SYS_JoystickID[index];
for (i = 0; i < MAX_AXES; ++i) {
if ((i < 2) || (SYS_Joystick[index].wCaps & caps_flags[i - 2])) {
joystick->hwdata->transaxis[i].offset = SDL_JOYSTICK_AXIS_MIN - axis_min[i];
joystick->hwdata->transaxis[i].scale =
(float) (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) / (axis_max[i] - axis_min[i]);
} else {
joystick->hwdata->transaxis[i].offset = 0;
joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
}
}
/* fill nbuttons, naxes, and nhats fields */
joystick->nbuttons = SYS_Joystick[index].wNumButtons;
joystick->naxes = SYS_Joystick[index].wNumAxes;
if (SYS_Joystick[index].wCaps & JOYCAPS_HASPOV) {
joystick->nhats = 1;
} else {
joystick->nhats = 0;
}
return (0);
}
static Uint8
TranslatePOV(DWORD value)
{
Uint8 pos;
pos = SDL_HAT_CENTERED;
if (value != JOY_POVCENTERED) {
if ((value > JOY_POVLEFT) || (value < JOY_POVRIGHT)) {
pos |= SDL_HAT_UP;
}
if ((value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD)) {
pos |= SDL_HAT_RIGHT;
}
if ((value > JOY_POVRIGHT) && (value < JOY_POVLEFT)) {
pos |= SDL_HAT_DOWN;
}
if (value > JOY_POVBACKWARD) {
pos |= SDL_HAT_LEFT;
}
}
return (pos);
}
static int
WINMM_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
return SDL_Unsupported();
}
static int
WINMM_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}
static SDL_bool WINMM_JoystickHasLED(SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int
WINMM_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{
return SDL_Unsupported();
}
static int
WINMM_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
{
return SDL_Unsupported();
}
static int WINMM_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
{
return SDL_Unsupported();
}
/* Function to update the state of a joystick - called as a device poll.
* This function shouldn't update the joystick structure directly,
* but instead should call SDL_PrivateJoystick*() to deliver events
* and update joystick device state.
*/
static void
WINMM_JoystickUpdate(SDL_Joystick *joystick)
{
MMRESULT result;
int i;
DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
};
DWORD pos[MAX_AXES];
struct _transaxis *transaxis;
int value;
JOYINFOEX joyinfo;
joyinfo.dwSize = sizeof(joyinfo);
joyinfo.dwFlags = JOY_RETURNALL | JOY_RETURNPOVCTS;
if (!joystick->hats) {
joyinfo.dwFlags &= ~(JOY_RETURNPOV | JOY_RETURNPOVCTS);
}
result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
if (result != JOYERR_NOERROR) {
SetMMerror("joyGetPosEx", result);
return;
}
/* joystick motion events */
pos[0] = joyinfo.dwXpos;
pos[1] = joyinfo.dwYpos;
pos[2] = joyinfo.dwZpos;
pos[3] = joyinfo.dwRpos;
pos[4] = joyinfo.dwUpos;
pos[5] = joyinfo.dwVpos;
transaxis = joystick->hwdata->transaxis;
for (i = 0; i < joystick->naxes; i++) {
if (joyinfo.dwFlags & flags[i]) {
value = (int) (((float) pos[i] + transaxis[i].offset) * transaxis[i].scale);
SDL_PrivateJoystickAxis(joystick, (Uint8) i, (Sint16) value);
}
}
/* joystick button events */
if (joyinfo.dwFlags & JOY_RETURNBUTTONS) {
for (i = 0; i < joystick->nbuttons; ++i) {
if (joyinfo.dwButtons & JOY_BUTTON_FLAG(i)) {
SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_PRESSED);
} else {
SDL_PrivateJoystickButton(joystick, (Uint8) i, SDL_RELEASED);
}
}
}
/* joystick hat events */
if (joyinfo.dwFlags & JOY_RETURNPOV) {
SDL_PrivateJoystickHat(joystick, 0, TranslatePOV(joyinfo.dwPOV));
}
}
/* Function to close a joystick after use */
static void
WINMM_JoystickClose(SDL_Joystick *joystick)
{
SDL_free(joystick->hwdata);
}
/* Function to perform any system-specific joystick related cleanup */
static void
WINMM_JoystickQuit(void)
{
int i;
for (i = 0; i < MAX_JOYSTICKS; i++) {
SDL_free(SYS_JoystickName[i]);
SYS_JoystickName[i] = NULL;
}
}
static SDL_bool
WINMM_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
return SDL_FALSE;
}
/* implementation functions */
void
SetMMerror(char *function, int code)
{
static char *error;
static char errbuf[1024];
errbuf[0] = 0;
switch (code) {
case MMSYSERR_NODRIVER:
error = "Joystick driver not present";
break;
case MMSYSERR_INVALPARAM:
case JOYERR_PARMS:
error = "Invalid parameter(s)";
break;
case MMSYSERR_BADDEVICEID:
error = "Bad device ID";
break;
case JOYERR_UNPLUGGED:
error = "Joystick not attached";
break;
case JOYERR_NOCANDO:
error = "Can't capture joystick input";
break;
default:
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
"%s: Unknown Multimedia system error: 0x%x",
function, code);
break;
}
if (!errbuf[0]) {
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
error);
}
SDL_SetError("%s", errbuf);
}
SDL_JoystickDriver SDL_WINMM_JoystickDriver =
{
WINMM_JoystickInit,
WINMM_NumJoysticks,
WINMM_JoystickDetect,
WINMM_JoystickGetDeviceName,
WINMM_JoystickGetDevicePlayerIndex,
WINMM_JoystickSetDevicePlayerIndex,
WINMM_JoystickGetDeviceGUID,
WINMM_JoystickGetDeviceInstanceID,
WINMM_JoystickOpen,
WINMM_JoystickRumble,
WINMM_JoystickRumbleTriggers,
WINMM_JoystickHasLED,
WINMM_JoystickSetLED,
WINMM_JoystickSendEffect,
WINMM_JoystickSetSensorsEnabled,
WINMM_JoystickUpdate,
WINMM_JoystickClose,
WINMM_JoystickQuit,
WINMM_JoystickGetGamepadMapping
};
#endif /* SDL_JOYSTICK_WINMM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,4 +0,0 @@
float4 main( float2 vTexcoord : TEXCOORD0, uniform sampler2D tex, uniform float4 uTintColor)
{
return tex2D(tex, vTexcoord) * uTintColor;
}

View File

@@ -1,282 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_hints.h"
#include "SDL_thread.h"
#include "../generic/SDL_syscond_c.h"
#include "SDL_sysmutex_c.h"
typedef SDL_cond * (*pfnSDL_CreateCond)(void);
typedef void (*pfnSDL_DestroyCond)(SDL_cond *);
typedef int (*pfnSDL_CondSignal)(SDL_cond *);
typedef int (*pfnSDL_CondBroadcast)(SDL_cond *);
typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *);
typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32);
typedef struct SDL_cond_impl_t
{
pfnSDL_CreateCond Create;
pfnSDL_DestroyCond Destroy;
pfnSDL_CondSignal Signal;
pfnSDL_CondBroadcast Broadcast;
pfnSDL_CondWait Wait;
pfnSDL_CondWaitTimeout WaitTimeout;
} SDL_cond_impl_t;
/* Implementation will be chosen at runtime based on available Kernel features */
static SDL_cond_impl_t SDL_cond_impl_active = {0};
/**
* Native Windows Condition Variable (SRW Locks)
*/
#ifndef CONDITION_VARIABLE_INIT
#define CONDITION_VARIABLE_INIT {0}
typedef struct CONDITION_VARIABLE {
PVOID Ptr;
} CONDITION_VARIABLE, *PCONDITION_VARIABLE;
#endif
#if __WINRT__
#define pWakeConditionVariable WakeConditionVariable
#define pWakeAllConditionVariable WakeAllConditionVariable
#define pSleepConditionVariableSRW SleepConditionVariableSRW
#else
typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE);
typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE);
typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG);
static pfnWakeConditionVariable pWakeConditionVariable = NULL;
static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL;
static pfnSleepConditionVariableSRW pSleepConditionVariableSRW = NULL;
#endif
typedef struct SDL_cond_srw
{
CONDITION_VARIABLE cond;
} SDL_cond_srw;
static SDL_cond *
SDL_CreateCond_srw(void)
{
SDL_cond_srw *cond;
/* Relies on CONDITION_VARIABLE_INIT == 0. */
cond = (SDL_cond_srw *) SDL_calloc(1, sizeof(*cond));
if (!cond) {
SDL_OutOfMemory();
}
return (SDL_cond *)cond;
}
static void
SDL_DestroyCond_srw(SDL_cond * cond)
{
if (cond) {
/* There are no kernel allocated resources */
SDL_free(cond);
}
}
static int
SDL_CondSignal_srw(SDL_cond * _cond)
{
SDL_cond_srw *cond = (SDL_cond_srw *)_cond;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
pWakeConditionVariable(&cond->cond);
return 0;
}
static int
SDL_CondBroadcast_srw(SDL_cond * _cond)
{
SDL_cond_srw *cond = (SDL_cond_srw *)_cond;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
pWakeAllConditionVariable(&cond->cond);
return 0;
}
static int
SDL_CondWaitTimeout_srw(SDL_cond * _cond, SDL_mutex * _mutex, Uint32 ms)
{
SDL_cond_srw *cond = (SDL_cond_srw *)_cond;
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
DWORD timeout;
int ret;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
if (!mutex) {
return SDL_SetError("Passed a NULL mutex");
}
if (mutex->count != 1 || mutex->owner != GetCurrentThreadId()) {
return SDL_SetError("Passed mutex is not locked or locked recursively");
}
if (ms == SDL_MUTEX_MAXWAIT) {
timeout = INFINITE;
} else {
timeout = (DWORD) ms;
}
/* The mutex must be updated to the released state */
mutex->count = 0;
mutex->owner = 0;
if (pSleepConditionVariableSRW(&cond->cond, &mutex->srw, timeout, 0) == FALSE) {
if (GetLastError() == ERROR_TIMEOUT) {
ret = SDL_MUTEX_TIMEDOUT;
} else {
ret = SDL_SetError("SleepConditionVariableSRW() failed");
}
} else {
ret = 0;
}
/* The mutex is owned by us again, regardless of status of the wait */
SDL_assert(mutex->count == 0 && mutex->owner == 0);
mutex->count = 1;
mutex->owner = GetCurrentThreadId();
return ret;
}
static int
SDL_CondWait_srw(SDL_cond * cond, SDL_mutex * mutex) {
return SDL_CondWaitTimeout_srw(cond, mutex, SDL_MUTEX_MAXWAIT);
}
static const SDL_cond_impl_t SDL_cond_impl_srw =
{
&SDL_CreateCond_srw,
&SDL_DestroyCond_srw,
&SDL_CondSignal_srw,
&SDL_CondBroadcast_srw,
&SDL_CondWait_srw,
&SDL_CondWaitTimeout_srw,
};
/**
* Generic Condition Variable implementation using SDL_mutex and SDL_sem
*/
static const SDL_cond_impl_t SDL_cond_impl_generic =
{
&SDL_CreateCond_generic,
&SDL_DestroyCond_generic,
&SDL_CondSignal_generic,
&SDL_CondBroadcast_generic,
&SDL_CondWait_generic,
&SDL_CondWaitTimeout_generic,
};
SDL_cond *
SDL_CreateCond(void)
{
if (SDL_cond_impl_active.Create == NULL) {
/* Default to generic implementation, works with all mutex implementations */
const SDL_cond_impl_t * impl = &SDL_cond_impl_generic;
if (SDL_mutex_impl_active.Type == SDL_MUTEX_INVALID) {
/* The mutex implementation isn't decided yet, trigger it */
SDL_mutex *mutex = SDL_CreateMutex();
if (!mutex) {
return NULL;
}
SDL_DestroyMutex(mutex);
SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID);
}
/* It is required SRW Locks are used */
if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) {
#if __WINRT__
/* Link statically on this platform */
impl = &SDL_cond_impl_srw;
#else
HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (kernel32) {
pWakeConditionVariable = (pfnWakeConditionVariable) GetProcAddress(kernel32, "WakeConditionVariable");
pWakeAllConditionVariable = (pfnWakeAllConditionVariable) GetProcAddress(kernel32, "WakeAllConditionVariable");
pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW) GetProcAddress(kernel32, "SleepConditionVariableSRW");
if (pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW) {
/* Use the Windows provided API */
impl = &SDL_cond_impl_srw;
}
}
if (!(kernel32 && pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW)) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "Could not load required imports for SRW Condition Variables although SRW Locks are used!");
}
#endif
}
SDL_memcpy(&SDL_cond_impl_active, impl, sizeof(SDL_cond_impl_active));
}
return SDL_cond_impl_active.Create();
}
void
SDL_DestroyCond(SDL_cond * cond)
{
SDL_cond_impl_active.Destroy(cond);
}
int
SDL_CondSignal(SDL_cond * cond)
{
return SDL_cond_impl_active.Signal(cond);
}
int
SDL_CondBroadcast(SDL_cond * cond)
{
return SDL_cond_impl_active.Broadcast(cond);
}
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
{
return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms);
}
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
{
return SDL_cond_impl_active.Wait(cond, mutex);
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,34 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_cocoamousetap_h_
#define SDL_cocoamousetap_h_
#include "SDL_cocoamouse.h"
extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata);
extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled);
extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata);
#endif /* SDL_cocoamousetap_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,286 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_COCOA
#include "SDL_cocoamousetap.h"
/* Event taps are forbidden in the Mac App Store, so we can only enable this
* code if your app doesn't need to ship through the app store.
* This code makes it so that a grabbed cursor cannot "leak" a mouse click
* past the edge of the window if moving the cursor too fast.
*/
#if SDL_MAC_NO_SANDBOX
#include "SDL_keyboard.h"
#include "SDL_cocoavideo.h"
#include "../../thread/SDL_systhread.h"
#include "../../events/SDL_mouse_c.h"
typedef struct {
CFMachPortRef tap;
CFRunLoopRef runloop;
CFRunLoopSourceRef runloopSource;
SDL_Thread *thread;
SDL_sem *runloopStartedSemaphore;
} SDL_MouseEventTapData;
static const CGEventMask movementEventsMask =
CGEventMaskBit(kCGEventLeftMouseDragged)
| CGEventMaskBit(kCGEventRightMouseDragged)
| CGEventMaskBit(kCGEventMouseMoved);
static const CGEventMask allGrabbedEventsMask =
CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp)
| CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp)
| CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp)
| CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged)
| CGEventMaskBit(kCGEventMouseMoved);
static CGEventRef
Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)refcon;
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *window = SDL_GetKeyboardFocus();
NSWindow *nswindow;
NSRect windowRect;
CGPoint eventLocation;
switch (type) {
case kCGEventTapDisabledByTimeout:
{
CGEventTapEnable(tapdata->tap, true);
return NULL;
}
case kCGEventTapDisabledByUserInput:
{
return NULL;
}
default:
break;
}
if (!window || !mouse) {
return event;
}
if (mouse->relative_mode) {
return event;
}
if (!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
return event;
}
/* This is the same coordinate system as Cocoa uses. */
nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
eventLocation = CGEventGetUnflippedLocation(event);
windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
/* This is in CGs global screenspace coordinate system, which has a
* flipped Y.
*/
CGPoint newLocation = CGEventGetLocation(event);
if (eventLocation.x < NSMinX(windowRect)) {
newLocation.x = NSMinX(windowRect);
} else if (eventLocation.x >= NSMaxX(windowRect)) {
newLocation.x = NSMaxX(windowRect) - 1.0;
}
if (eventLocation.y <= NSMinY(windowRect)) {
newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1);
} else if (eventLocation.y > NSMaxY(windowRect)) {
newLocation.y += (eventLocation.y - NSMaxY(windowRect));
}
CGWarpMouseCursorPosition(newLocation);
CGAssociateMouseAndMouseCursorPosition(YES);
if ((CGEventMaskBit(type) & movementEventsMask) == 0) {
/* For click events, we just constrain the event to the window, so
* no other app receives the click event. We can't due the same to
* movement events, since they mean that our warp cursor above
* behaves strangely.
*/
CGEventSetLocation(event, newLocation);
}
}
return event;
}
static void
SemaphorePostCallback(CFRunLoopTimerRef timer, void *info)
{
SDL_SemPost((SDL_sem*)info);
}
static int
Cocoa_MouseTapThread(void *data)
{
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data;
/* Tap was created on main thread but we own it now. */
CFMachPortRef eventTap = tapdata->tap;
if (eventTap) {
/* Try to create a runloop source we can schedule. */
CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
if (runloopSource) {
tapdata->runloopSource = runloopSource;
} else {
CFRelease(eventTap);
SDL_SemPost(tapdata->runloopStartedSemaphore);
/* TODO: Both here and in the return below, set some state in
* tapdata to indicate that initialization failed, which we should
* check in InitMouseEventTap, after we move the semaphore check
* from Quit to Init.
*/
return 1;
}
} else {
SDL_SemPost(tapdata->runloopStartedSemaphore);
return 1;
}
tapdata->runloop = CFRunLoopGetCurrent();
CFRunLoopAddSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
CFRunLoopTimerContext context = {.info = tapdata->runloopStartedSemaphore};
/* We signal the runloop started semaphore *after* the run loop has started, indicating it's safe to CFRunLoopStop it. */
CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &context);
CFRunLoopAddTimer(tapdata->runloop, timer, kCFRunLoopCommonModes);
CFRelease(timer);
/* Run the event loop to handle events in the event tap. */
CFRunLoopRun();
/* Make sure this is signaled so that SDL_QuitMouseEventTap knows it can safely SDL_WaitThread for us. */
if (SDL_SemValue(tapdata->runloopStartedSemaphore) < 1) {
SDL_SemPost(tapdata->runloopStartedSemaphore);
}
CFRunLoopRemoveSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
/* Clean up. */
CGEventTapEnable(tapdata->tap, false);
CFRelease(tapdata->runloopSource);
CFRelease(tapdata->tap);
tapdata->runloopSource = NULL;
tapdata->tap = NULL;
return 0;
}
void
Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
{
SDL_MouseEventTapData *tapdata;
driverdata->tapdata = SDL_calloc(1, sizeof(SDL_MouseEventTapData));
tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
if (tapdata->runloopStartedSemaphore) {
tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
kCGEventTapOptionDefault, allGrabbedEventsMask,
&Cocoa_MouseTapCallback, tapdata);
if (tapdata->tap) {
/* Tap starts disabled, until app requests mouse grab */
CGEventTapEnable(tapdata->tap, false);
tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
if (tapdata->thread) {
/* Success - early out. Ownership transferred to thread. */
return;
}
CFRelease(tapdata->tap);
}
SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
}
SDL_free(driverdata->tapdata);
driverdata->tapdata = NULL;
}
void
Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
{
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
if (tapdata && tapdata->tap)
{
CGEventTapEnable(tapdata->tap, !!enabled);
}
}
void
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
{
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
int status;
if (tapdata == NULL) {
/* event tap was already cleaned up (possibly due to CGEventTapCreate
* returning null.)
*/
return;
}
/* Ensure that the runloop has been started first.
* TODO: Move this to InitMouseEventTap, check for error conditions that can
* happen in Cocoa_MouseTapThread, and fall back to the non-EventTap way of
* grabbing the mouse if it fails to Init.
*/
status = SDL_SemWaitTimeout(tapdata->runloopStartedSemaphore, 5000);
if (status > -1) {
/* Then stop it, which will cause Cocoa_MouseTapThread to return. */
CFRunLoopStop(tapdata->runloop);
/* And then wait for Cocoa_MouseTapThread to finish cleaning up. It
* releases some of the pointers in tapdata. */
SDL_WaitThread(tapdata->thread, &status);
}
SDL_free(driverdata->tapdata);
driverdata->tapdata = NULL;
}
#else /* SDL_MAC_NO_SANDBOX */
void
Cocoa_InitMouseEventTap(SDL_MouseData *unused)
{
}
void
Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
{
}
void
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
{
}
#endif /* !SDL_MAC_NO_SANDBOX */
#endif /* SDL_VIDEO_DRIVER_COCOA */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,65 +0,0 @@
#ifndef VULKAN_MIR_H_
#define VULKAN_MIR_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2015-2018 The Khronos Group Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
/*
** This header is generated from the Khronos Vulkan XML API Registry.
**
*/
#define VK_KHR_mir_surface 1
#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
typedef struct VkMirSurfaceCreateInfoKHR {
VkStructureType sType;
const void* pNext;
VkMirSurfaceCreateFlagsKHR flags;
MirConnection* connection;
MirSurface* mirSurface;
} VkMirSurfaceCreateInfoKHR;
typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection);
#ifndef VK_NO_PROTOTYPES
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
VkInstance instance,
const VkMirSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex,
MirConnection* connection);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,167 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#define DEBUG_DYNAMIC_KMSDRM_LEGACY 0
#include "SDL_kmsdrm_legacy_dyn.h"
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
#include "SDL_name.h"
#include "SDL_loadso.h"
typedef struct
{
void *lib;
const char *libname;
} kmsdrmdynlib;
#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL
#endif
#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM
#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL
#endif
static kmsdrmdynlib kmsdrmlibs[] = {
{NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM},
{NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC}
};
static void *
KMSDRM_LEGACY_GetSym(const char *fnname, int *pHasModule)
{
int i;
void *fn = NULL;
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].lib != NULL) {
fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname);
if (fn != NULL)
break;
}
}
#if DEBUG_DYNAMIC_KMSDRM_LEGACY
if (fn != NULL)
SDL_Log("KMSDRM_LEGACY: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn);
else
SDL_Log("KMSDRM_LEGACY: Symbol '%s' NOT FOUND!\n", fnname);
#endif
if (fn == NULL)
*pHasModule = 0; /* kill this module. */
return fn;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */
/* Define all the function pointers and wrappers... */
#define SDL_KMSDRM_LEGACY_MODULE(modname) int SDL_KMSDRM_LEGACY_HAVE_##modname = 0;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn = NULL;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name = NULL;
#include "SDL_kmsdrm_legacy_sym.h"
static int kmsdrm_load_refcount = 0;
void
SDL_KMSDRM_LEGACY_UnloadSymbols(void)
{
/* Don't actually unload if more than one module is using the libs... */
if (kmsdrm_load_refcount > 0) {
if (--kmsdrm_load_refcount == 0) {
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
int i;
#endif
/* set all the function pointers to NULL. */
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 0;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = NULL;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = NULL;
#include "SDL_kmsdrm_legacy_sym.h"
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].lib != NULL) {
SDL_UnloadObject(kmsdrmlibs[i].lib);
kmsdrmlibs[i].lib = NULL;
}
}
#endif
}
}
}
/* returns non-zero if all needed symbols were loaded. */
int
SDL_KMSDRM_LEGACY_LoadSymbols(void)
{
int rc = 1; /* always succeed if not using Dynamic KMSDRM_LEGACY stuff. */
/* deal with multiple modules needing these symbols... */
if (kmsdrm_load_refcount++ == 0) {
#ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC
int i;
int *thismod = NULL;
for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) {
if (kmsdrmlibs[i].libname != NULL) {
kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname);
}
}
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */
#include "SDL_kmsdrm_legacy_sym.h"
#define SDL_KMSDRM_LEGACY_MODULE(modname) thismod = &SDL_KMSDRM_LEGACY_HAVE_##modname;
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = (SDL_DYNKMSDRM_LEGACYFN_##fn) KMSDRM_LEGACY_GetSym(#fn,thismod);
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = *(SDL_DYNKMSDRM_LEGACYCONST_##name*) KMSDRM_LEGACY_GetSym(#name,thismod);
#include "SDL_kmsdrm_legacy_sym.h"
if ((SDL_KMSDRM_LEGACY_HAVE_LIBDRM) && (SDL_KMSDRM_LEGACY_HAVE_GBM)) {
/* all required symbols loaded. */
SDL_ClearError();
} else {
/* in case something got loaded... */
SDL_KMSDRM_LEGACY_UnloadSymbols();
rc = 0;
}
#else /* no dynamic KMSDRM_LEGACY */
#define SDL_KMSDRM_LEGACY_MODULE(modname) SDL_KMSDRM_LEGACY_HAVE_##modname = 1; /* default yes */
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) KMSDRM_LEGACY_##fn = fn;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type,name) KMSDRM_LEGACY_##name = name;
#include "SDL_kmsdrm_legacy_sym.h"
#endif
}
return rc;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,53 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_kmsdrmdyn_h_
#define SDL_kmsdrmdyn_h_
#include "../../SDL_internal.h"
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#ifdef __cplusplus
extern "C" {
#endif
int SDL_KMSDRM_LEGACY_LoadSymbols(void);
void SDL_KMSDRM_LEGACY_UnloadSymbols(void);
/* Declare all the function pointers and wrappers... */
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params) \
typedef rc (*SDL_DYNKMSDRM_LEGACYFN_##fn) params; \
extern SDL_DYNKMSDRM_LEGACYFN_##fn KMSDRM_LEGACY_##fn;
#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name) \
typedef type SDL_DYNKMSDRM_LEGACYCONST_##name; \
extern SDL_DYNKMSDRM_LEGACYCONST_##name KMSDRM_LEGACY_##name;
#include "SDL_kmsdrm_legacy_sym.h"
#ifdef __cplusplus
}
#endif
#endif /* SDL_kmsdrmdyn_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,42 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_events.h"
#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif
void KMSDRM_LEGACY_PumpEvents(_THIS)
{
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Poll();
#endif
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */

View File

@@ -1,31 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_kmsdrmevents_h_
#define SDL_kmsdrmevents_h_
extern void KMSDRM_LEGACY_PumpEvents(_THIS);
extern void KMSDRM_LEGACY_EventInit(_THIS);
extern void KMSDRM_LEGACY_EventQuit(_THIS);
#endif /* SDL_kmsdrmevents_h_ */

View File

@@ -1,502 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_mouse.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/default_cursor.h"
static SDL_Cursor *KMSDRM_LEGACY_CreateDefaultCursor(void);
static SDL_Cursor *KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
static int KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor);
static void KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y);
static int KMSDRM_LEGACY_WarpMouseGlobal(int x, int y);
static SDL_Cursor *
KMSDRM_LEGACY_CreateDefaultCursor(void)
{
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
}
/* Evaluate if a given cursor size is supported or not. Notably, current Intel gfx only support 64x64 and up. */
static SDL_bool
KMSDRM_LEGACY_IsCursorSizeSupported (int w, int h, uint32_t bo_format) {
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
int ret;
uint32_t bo_handle;
struct gbm_bo *bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm, w, h, bo_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
if (!bo) {
SDL_SetError("Could not create GBM cursor BO width size %dx%d for size testing", w, h);
goto cleanup;
}
bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(bo).u32;
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, bo_handle, w, h);
if (ret) {
goto cleanup;
}
else {
KMSDRM_LEGACY_gbm_bo_destroy(bo);
return SDL_TRUE;
}
cleanup:
if (bo) {
KMSDRM_LEGACY_gbm_bo_destroy(bo);
}
return SDL_FALSE;
}
/* Create a cursor from a surface */
static SDL_Cursor *
KMSDRM_LEGACY_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
SDL_PixelFormat *pixlfmt = surface->format;
KMSDRM_LEGACY_CursorData *curdata;
SDL_Cursor *cursor;
SDL_bool cursor_supported = SDL_FALSE;
int i, ret, usable_cursor_w, usable_cursor_h;
uint32_t bo_format, bo_stride;
char *buffer = NULL;
size_t bufsize;
switch(pixlfmt->format) {
case SDL_PIXELFORMAT_RGB332:
bo_format = GBM_FORMAT_RGB332;
break;
case SDL_PIXELFORMAT_ARGB4444:
bo_format = GBM_FORMAT_ARGB4444;
break;
case SDL_PIXELFORMAT_RGBA4444:
bo_format = GBM_FORMAT_RGBA4444;
break;
case SDL_PIXELFORMAT_ABGR4444:
bo_format = GBM_FORMAT_ABGR4444;
break;
case SDL_PIXELFORMAT_BGRA4444:
bo_format = GBM_FORMAT_BGRA4444;
break;
case SDL_PIXELFORMAT_ARGB1555:
bo_format = GBM_FORMAT_ARGB1555;
break;
case SDL_PIXELFORMAT_RGBA5551:
bo_format = GBM_FORMAT_RGBA5551;
break;
case SDL_PIXELFORMAT_ABGR1555:
bo_format = GBM_FORMAT_ABGR1555;
break;
case SDL_PIXELFORMAT_BGRA5551:
bo_format = GBM_FORMAT_BGRA5551;
break;
case SDL_PIXELFORMAT_RGB565:
bo_format = GBM_FORMAT_RGB565;
break;
case SDL_PIXELFORMAT_BGR565:
bo_format = GBM_FORMAT_BGR565;
break;
case SDL_PIXELFORMAT_RGB888:
case SDL_PIXELFORMAT_RGB24:
bo_format = GBM_FORMAT_RGB888;
break;
case SDL_PIXELFORMAT_BGR888:
case SDL_PIXELFORMAT_BGR24:
bo_format = GBM_FORMAT_BGR888;
break;
case SDL_PIXELFORMAT_RGBX8888:
bo_format = GBM_FORMAT_RGBX8888;
break;
case SDL_PIXELFORMAT_BGRX8888:
bo_format = GBM_FORMAT_BGRX8888;
break;
case SDL_PIXELFORMAT_ARGB8888:
bo_format = GBM_FORMAT_ARGB8888;
break;
case SDL_PIXELFORMAT_RGBA8888:
bo_format = GBM_FORMAT_RGBA8888;
break;
case SDL_PIXELFORMAT_ABGR8888:
bo_format = GBM_FORMAT_ABGR8888;
break;
case SDL_PIXELFORMAT_BGRA8888:
bo_format = GBM_FORMAT_BGRA8888;
break;
case SDL_PIXELFORMAT_ARGB2101010:
bo_format = GBM_FORMAT_ARGB2101010;
break;
default:
SDL_SetError("Unsupported pixel format for cursor");
return NULL;
}
if (!KMSDRM_LEGACY_gbm_device_is_format_supported(viddata->gbm, bo_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) {
SDL_SetError("Unsupported pixel format for cursor");
return NULL;
}
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (!cursor) {
SDL_OutOfMemory();
return NULL;
}
curdata = (KMSDRM_LEGACY_CursorData *) SDL_calloc(1, sizeof(*curdata));
if (!curdata) {
SDL_OutOfMemory();
SDL_free(cursor);
return NULL;
}
/* We have to know beforehand if a cursor with the same size as the surface is supported.
* If it's not, we have to find an usable cursor size and use an intermediate and clean buffer.
* If we can't find a cursor size supported by the hardware, we won't go on trying to
* call SDL_SetCursor() later. */
usable_cursor_w = surface->w;
usable_cursor_h = surface->h;
while (usable_cursor_w <= MAX_CURSOR_W && usable_cursor_h <= MAX_CURSOR_H) {
if (KMSDRM_LEGACY_IsCursorSizeSupported(usable_cursor_w, usable_cursor_h, bo_format)) {
cursor_supported = SDL_TRUE;
break;
}
usable_cursor_w += usable_cursor_w;
usable_cursor_h += usable_cursor_h;
}
if (!cursor_supported) {
SDL_SetError("Could not find a cursor size supported by the kernel driver");
goto cleanup;
}
curdata->hot_x = hot_x;
curdata->hot_y = hot_y;
curdata->w = usable_cursor_w;
curdata->h = usable_cursor_h;
curdata->bo = KMSDRM_LEGACY_gbm_bo_create(viddata->gbm, usable_cursor_w, usable_cursor_h, bo_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
if (!curdata->bo) {
SDL_SetError("Could not create GBM cursor BO");
goto cleanup;
}
bo_stride = KMSDRM_LEGACY_gbm_bo_get_stride(curdata->bo);
bufsize = bo_stride * curdata->h;
if (surface->pitch != bo_stride) {
/* pitch doesn't match stride, must be copied to temp buffer */
buffer = SDL_malloc(bufsize);
if (!buffer) {
SDL_OutOfMemory();
goto cleanup;
}
if (SDL_MUSTLOCK(surface)) {
if (SDL_LockSurface(surface) < 0) {
/* Could not lock surface */
goto cleanup;
}
}
/* Clean the whole temporary buffer */
SDL_memset(buffer, 0x00, bo_stride * curdata->h);
/* Copy to temporary buffer */
for (i = 0; i < surface->h; i++) {
SDL_memcpy(buffer + (i * bo_stride),
((char *)surface->pixels) + (i * surface->pitch),
surface->w * pixlfmt->BytesPerPixel);
}
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
if (KMSDRM_LEGACY_gbm_bo_write(curdata->bo, buffer, bufsize)) {
SDL_SetError("Could not write to GBM cursor BO");
goto cleanup;
}
/* Free temporary buffer */
SDL_free(buffer);
buffer = NULL;
} else {
/* surface matches BO format */
if (SDL_MUSTLOCK(surface)) {
if (SDL_LockSurface(surface) < 0) {
/* Could not lock surface */
goto cleanup;
}
}
ret = KMSDRM_LEGACY_gbm_bo_write(curdata->bo, surface->pixels, bufsize);
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
if (ret) {
SDL_SetError("Could not write to GBM cursor BO");
goto cleanup;
}
}
cursor->driverdata = curdata;
return cursor;
cleanup:
if (buffer) {
SDL_free(buffer);
}
if (cursor) {
SDL_free(cursor);
}
if (curdata) {
if (curdata->bo) {
KMSDRM_LEGACY_gbm_bo_destroy(curdata->bo);
}
SDL_free(curdata);
}
return NULL;
}
/* Show the specified cursor, or hide if cursor is NULL */
static int
KMSDRM_LEGACY_ShowCursor(SDL_Cursor * cursor)
{
SDL_VideoDevice *dev = SDL_GetVideoDevice();
SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
SDL_Mouse *mouse;
KMSDRM_LEGACY_CursorData *curdata;
SDL_VideoDisplay *display = NULL;
SDL_DisplayData *dispdata = NULL;
int ret;
uint32_t bo_handle;
mouse = SDL_GetMouse();
if (!mouse) {
return SDL_SetError("No mouse.");
}
if (mouse->focus) {
display = SDL_GetDisplayForWindow(mouse->focus);
if (display) {
dispdata = (SDL_DisplayData*) display->driverdata;
}
}
if (!cursor) {
/* Hide current cursor */
if (mouse->cur_cursor && mouse->cur_cursor->driverdata) {
curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata;
if (curdata->crtc_id != 0) {
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, curdata->crtc_id, 0, 0, 0);
if (ret) {
SDL_SetError("Could not hide current cursor with drmModeSetCursor().");
return ret;
}
/* Mark previous cursor as not-displayed */
curdata->crtc_id = 0;
return 0;
}
}
/* otherwise if possible, hide global cursor */
if (dispdata && dispdata->crtc_id != 0) {
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, 0, 0, 0);
if (ret) {
SDL_SetError("Could not hide display's cursor with drmModeSetCursor().");
return ret;
}
return 0;
}
return SDL_SetError("Couldn't find cursor to hide.");
}
/* If cursor != NULL, show new cursor on display */
if (!display) {
return SDL_SetError("Could not get display for mouse.");
}
if (!dispdata) {
return SDL_SetError("Could not get display driverdata.");
}
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
if (!curdata || !curdata->bo) {
return SDL_SetError("Cursor not initialized properly.");
}
bo_handle = KMSDRM_LEGACY_gbm_bo_get_handle(curdata->bo).u32;
if (curdata->hot_x == 0 && curdata->hot_y == 0) {
ret = KMSDRM_LEGACY_drmModeSetCursor(viddata->drm_fd, dispdata->crtc_id, bo_handle,
curdata->w, curdata->h);
} else {
ret = KMSDRM_LEGACY_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc_id, bo_handle,
curdata->w, curdata->h, curdata->hot_x, curdata->hot_y);
}
if (ret) {
SDL_SetError("drmModeSetCursor failed.");
return ret;
}
curdata->crtc_id = dispdata->crtc_id;
return 0;
}
/* Free a window manager cursor */
static void
KMSDRM_LEGACY_FreeCursor(SDL_Cursor * cursor)
{
KMSDRM_LEGACY_CursorData *curdata;
int drm_fd;
if (cursor) {
curdata = (KMSDRM_LEGACY_CursorData *) cursor->driverdata;
if (curdata) {
if (curdata->bo) {
if (curdata->crtc_id != 0) {
drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo));
/* Hide the cursor if previously shown on a CRTC */
KMSDRM_LEGACY_drmModeSetCursor(drm_fd, curdata->crtc_id, 0, 0, 0);
curdata->crtc_id = 0;
}
KMSDRM_LEGACY_gbm_bo_destroy(curdata->bo);
curdata->bo = NULL;
}
SDL_free(cursor->driverdata);
}
SDL_free(cursor);
}
}
/* Warp the mouse to (x,y) */
static void
KMSDRM_LEGACY_WarpMouse(SDL_Window * window, int x, int y)
{
/* Only one global/fullscreen window is supported */
KMSDRM_LEGACY_WarpMouseGlobal(x, y);
}
/* Warp the mouse to (x,y) */
static int
KMSDRM_LEGACY_WarpMouseGlobal(int x, int y)
{
KMSDRM_LEGACY_CursorData *curdata;
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
/* Update internal mouse position. */
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
/* And now update the cursor graphic position on screen. */
curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata;
if (curdata->bo) {
if (curdata->crtc_id != 0) {
int ret, drm_fd;
drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo));
ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, curdata->crtc_id, x, y);
if (ret) {
SDL_SetError("drmModeMoveCursor() failed.");
}
return ret;
} else {
return SDL_SetError("Cursor is not currently shown.");
}
} else {
return SDL_SetError("Cursor not initialized properly.");
}
} else {
return SDL_SetError("No mouse or current cursor.");
}
}
void
KMSDRM_LEGACY_InitMouse(_THIS)
{
/* FIXME: Using UDEV it should be possible to scan all mice
* but there's no point in doing so as there's no multimice support...yet!
*/
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = KMSDRM_LEGACY_CreateCursor;
mouse->ShowCursor = KMSDRM_LEGACY_ShowCursor;
mouse->MoveCursor = KMSDRM_LEGACY_MoveCursor;
mouse->FreeCursor = KMSDRM_LEGACY_FreeCursor;
mouse->WarpMouse = KMSDRM_LEGACY_WarpMouse;
mouse->WarpMouseGlobal = KMSDRM_LEGACY_WarpMouseGlobal;
SDL_SetDefaultCursor(KMSDRM_LEGACY_CreateDefaultCursor());
}
void
KMSDRM_LEGACY_QuitMouse(_THIS)
{
/* TODO: ? */
}
/* This is called when a mouse motion event occurs */
static void
KMSDRM_LEGACY_MoveCursor(SDL_Cursor * cursor)
{
SDL_Mouse *mouse = SDL_GetMouse();
KMSDRM_LEGACY_CursorData *curdata;
int drm_fd, ret;
/* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
That's why we move the cursor graphic ONLY. */
if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
curdata = (KMSDRM_LEGACY_CursorData *) mouse->cur_cursor->driverdata;
drm_fd = KMSDRM_LEGACY_gbm_device_get_fd(KMSDRM_LEGACY_gbm_bo_get_device(curdata->bo));
ret = KMSDRM_LEGACY_drmModeMoveCursor(drm_fd, curdata->crtc_id, mouse->x, mouse->y);
if (ret) {
SDL_SetError("drmModeMoveCursor() failed.");
}
}
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,45 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_KMSDRM_LEGACY_mouse_h_
#define SDL_KMSDRM_LEGACY_mouse_h_
#include <gbm.h>
#define MAX_CURSOR_W 512
#define MAX_CURSOR_H 512
typedef struct _KMSDRM_LEGACY_CursorData
{
struct gbm_bo *bo;
uint32_t crtc_id;
int hot_x, hot_y;
int w, h;
} KMSDRM_LEGACY_CursorData;
extern void KMSDRM_LEGACY_InitMouse(_THIS);
extern void KMSDRM_LEGACY_QuitMouse(_THIS);
#endif /* SDL_KMSDRM_LEGACY_mouse_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,152 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
#include "SDL_log.h"
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_opengles.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#ifndef EGL_PLATFORM_GBM_MESA
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif
/* EGL implementation of SDL OpenGL support */
int
KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path) {
NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm;
return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA);
}
SDL_EGL_CreateContext_impl(KMSDRM_LEGACY)
int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval) {
if (!_this->egl_data) {
return SDL_SetError("EGL not initialized");
}
if (interval == 0 || interval == 1) {
_this->egl_data->egl_swapinterval = interval;
} else {
return SDL_SetError("Only swap intervals of 0 or 1 are supported");
}
return 0;
}
int
KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window) {
SDL_WindowData *windata = ((SDL_WindowData *) window->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
KMSDRM_LEGACY_FBInfo *fb_info;
int ret, timeout;
/* Recreate the GBM / EGL surfaces if the display mode has changed */
if (windata->egl_surface_dirty) {
KMSDRM_LEGACY_CreateSurfaces(_this, window);
}
/* Wait for confirmation that the next front buffer has been flipped, at which
point the previous front buffer can be released */
timeout = 0;
if (_this->egl_data->egl_swapinterval == 1) {
timeout = -1;
}
if (!KMSDRM_LEGACY_WaitPageFlip(_this, windata, timeout)) {
return 0;
}
/* Release the previous front buffer */
if (windata->curr_bo) {
KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->curr_bo);
/* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Released GBM surface %p", (void *)windata->curr_bo); */
windata->curr_bo = NULL;
}
windata->curr_bo = windata->next_bo;
/* Make the current back buffer the next front buffer */
if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, windata->egl_surface))) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed.");
return 0;
}
/* Lock the next front buffer so it can't be allocated as a back buffer */
windata->next_bo = KMSDRM_LEGACY_gbm_surface_lock_front_buffer(windata->gs);
if (!windata->next_bo) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer");
return 0;
/* } else {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Locked GBM surface %p", (void *)windata->next_bo); */
}
fb_info = KMSDRM_LEGACY_FBFromBO(_this, windata->next_bo);
if (!fb_info) {
return 0;
}
if (!windata->curr_bo) {
/* On the first swap, immediately present the new front buffer. Before
drmModePageFlip can be used the CRTC has to be configured to use
the current connector and mode with drmModeSetCrtc */
ret = KMSDRM_LEGACY_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id, 0,
0, &dispdata->conn->connector_id, 1, &dispdata->mode);
if (ret) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not configure CRTC");
}
} else {
/* On subsequent swaps, queue the new front buffer to be flipped during
the next vertical blank */
ret = KMSDRM_LEGACY_drmModePageFlip(viddata->drm_fd, dispdata->crtc_id, fb_info->fb_id,
DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip);
/* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &windata->waiting_for_flip)",
viddata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
if (_this->egl_data->egl_swapinterval == 1) {
if (ret == 0) {
windata->waiting_for_flip = SDL_TRUE;
} else {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
}
}
/* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
Run your SDL2 program with "SDL_KMSDRM_LEGACY_DOUBLE_BUFFER=1 <program_name>" to enable this. */
if (_this->egl_data->egl_swapinterval == 1 && windata->double_buffer) {
KMSDRM_LEGACY_WaitPageFlip(_this, windata, -1);
}
}
return 0;
}
SDL_EGL_MakeCurrent_impl(KMSDRM_LEGACY)
#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,48 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_kmsdrmopengles_h_
#define SDL_kmsdrmopengles_h_
#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
/* OpenGLES functions */
#define KMSDRM_LEGACY_GLES_GetAttribute SDL_EGL_GetAttribute
#define KMSDRM_LEGACY_GLES_GetProcAddress SDL_EGL_GetProcAddress
#define KMSDRM_LEGACY_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
#define KMSDRM_LEGACY_GLES_DeleteContext SDL_EGL_DeleteContext
#define KMSDRM_LEGACY_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
extern int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval);
extern int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path);
extern SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window);
extern int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window);
extern int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */
#endif /* SDL_kmsdrmopengles_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,99 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* *INDENT-OFF* */
#ifndef SDL_KMSDRM_LEGACY_MODULE
#define SDL_KMSDRM_LEGACY_MODULE(modname)
#endif
#ifndef SDL_KMSDRM_LEGACY_SYM
#define SDL_KMSDRM_LEGACY_SYM(rc,fn,params)
#endif
#ifndef SDL_KMSDRM_LEGACY_SYM_CONST
#define SDL_KMSDRM_LEGACY_SYM_CONST(type, name)
#endif
SDL_KMSDRM_LEGACY_MODULE(LIBDRM)
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeResources,(drmModeResPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
SDL_KMSDRM_LEGACY_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
SDL_KMSDRM_LEGACY_SYM(drmModeResPtr,drmModeGetResources,(int fd))
SDL_KMSDRM_LEGACY_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id))
SDL_KMSDRM_LEGACY_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
SDL_KMSDRM_LEGACY_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
SDL_KMSDRM_LEGACY_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t *connectors, int count,
drmModeModeInfoPtr mode))
SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
uint32_t width, uint32_t height))
SDL_KMSDRM_LEGACY_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
uint32_t width, uint32_t height,
int32_t hot_x, int32_t hot_y))
SDL_KMSDRM_LEGACY_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
SDL_KMSDRM_LEGACY_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
SDL_KMSDRM_LEGACY_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
SDL_KMSDRM_LEGACY_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
SDL_KMSDRM_LEGACY_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data))
SDL_KMSDRM_LEGACY_MODULE(GBM)
SDL_KMSDRM_LEGACY_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
SDL_KMSDRM_LEGACY_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm,
uint32_t format, uint32_t usage))
SDL_KMSDRM_LEGACY_SYM(void,gbm_device_destroy,(struct gbm_device *gbm))
SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_create_device,(int fd))
SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count))
SDL_KMSDRM_LEGACY_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_set_user_data,(struct gbm_bo *bo, void *data,
void (*destroy_user_data)(struct gbm_bo *, void *)))
SDL_KMSDRM_LEGACY_SYM(void *,gbm_bo_get_user_data,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(void,gbm_bo_destroy,(struct gbm_bo *bo))
SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_bo_create,(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t usage))
SDL_KMSDRM_LEGACY_SYM(struct gbm_surface *,gbm_surface_create,(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t flags))
SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf))
SDL_KMSDRM_LEGACY_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf))
SDL_KMSDRM_LEGACY_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo))
#undef SDL_KMSDRM_LEGACY_MODULE
#undef SDL_KMSDRM_LEGACY_SYM
#undef SDL_KMSDRM_LEGACY_SYM_CONST
/* *INDENT-ON* */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,934 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_KMSDRM
/* SDL internals */
#include "../SDL_sysvideo.h"
#include "SDL_syswm.h"
#include "SDL_log.h"
#include "SDL_hints.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif
/* KMS/DRM declarations */
#include "SDL_kmsdrm_legacy_video.h"
#include "SDL_kmsdrm_legacy_events.h"
#include "SDL_kmsdrm_legacy_opengles.h"
#include "SDL_kmsdrm_legacy_mouse.h"
#include "SDL_kmsdrm_legacy_dyn.h"
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <poll.h>
#define KMSDRM_LEGACY_DRI_PATH "/dev/dri/"
static int
check_modestting(int devindex)
{
SDL_bool available = SDL_FALSE;
char device[512];
int drm_fd;
SDL_snprintf(device, sizeof (device), "%scard%d", KMSDRM_LEGACY_DRI_PATH, devindex);
drm_fd = open(device, O_RDWR | O_CLOEXEC);
if (drm_fd >= 0) {
if (SDL_KMSDRM_LEGACY_LoadSymbols()) {
drmModeRes *resources = KMSDRM_LEGACY_drmModeGetResources(drm_fd);
if (resources) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%scard%d connector, encoder and CRTC counts are: %d %d %d",
KMSDRM_LEGACY_DRI_PATH, devindex,
resources->count_connectors, resources->count_encoders, resources->count_crtcs);
if (resources->count_connectors > 0 && resources->count_encoders > 0 && resources->count_crtcs > 0) {
available = SDL_TRUE;
}
KMSDRM_LEGACY_drmModeFreeResources(resources);
}
SDL_KMSDRM_LEGACY_UnloadSymbols();
}
close(drm_fd);
}
return available;
}
static int get_dricount(void)
{
int devcount = 0;
struct dirent *res;
struct stat sb;
DIR *folder;
if (!(stat(KMSDRM_LEGACY_DRI_PATH, &sb) == 0
&& S_ISDIR(sb.st_mode))) {
printf("The path %s cannot be opened or is not available\n",
KMSDRM_LEGACY_DRI_PATH);
return 0;
}
if (access(KMSDRM_LEGACY_DRI_PATH, F_OK) == -1) {
printf("The path %s cannot be opened\n",
KMSDRM_LEGACY_DRI_PATH);
return 0;
}
folder = opendir(KMSDRM_LEGACY_DRI_PATH);
if (folder) {
while ((res = readdir(folder))) {
int len = SDL_strlen(res->d_name);
if (len > 4 && SDL_strncmp(res->d_name, "card", 4) == 0) {
devcount++;
}
}
closedir(folder);
}
return devcount;
}
static int
get_driindex(void)
{
const int devcount = get_dricount();
int i;
for (i = 0; i < devcount; i++) {
if (check_modestting(i)) {
return i;
}
}
return -ENOENT;
}
static int
KMSDRM_LEGACY_Available(void)
{
int ret = -ENOENT;
ret = get_driindex();
if (ret >= 0)
return 1;
return ret;
}
static void
KMSDRM_LEGACY_DeleteDevice(SDL_VideoDevice * device)
{
if (device->driverdata) {
SDL_free(device->driverdata);
device->driverdata = NULL;
}
SDL_free(device);
SDL_KMSDRM_LEGACY_UnloadSymbols();
}
static SDL_VideoDevice *
KMSDRM_LEGACY_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
SDL_VideoData *viddata;
if (!KMSDRM_LEGACY_Available()) {
return NULL;
}
if (!devindex || (devindex > 99)) {
devindex = get_driindex();
}
if (devindex < 0) {
SDL_SetError("devindex (%d) must be between 0 and 99.\n", devindex);
return NULL;
}
if (!SDL_KMSDRM_LEGACY_LoadSymbols()) {
return NULL;
}
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return NULL;
}
viddata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (!viddata) {
SDL_OutOfMemory();
goto cleanup;
}
viddata->devindex = devindex;
viddata->drm_fd = -1;
device->driverdata = viddata;
/* Setup all functions which we can handle */
device->VideoInit = KMSDRM_LEGACY_VideoInit;
device->VideoQuit = KMSDRM_LEGACY_VideoQuit;
device->GetDisplayModes = KMSDRM_LEGACY_GetDisplayModes;
device->SetDisplayMode = KMSDRM_LEGACY_SetDisplayMode;
device->CreateSDLWindow = KMSDRM_LEGACY_CreateWindow;
device->CreateSDLWindowFrom = KMSDRM_LEGACY_CreateWindowFrom;
device->SetWindowTitle = KMSDRM_LEGACY_SetWindowTitle;
device->SetWindowIcon = KMSDRM_LEGACY_SetWindowIcon;
device->SetWindowPosition = KMSDRM_LEGACY_SetWindowPosition;
device->SetWindowSize = KMSDRM_LEGACY_SetWindowSize;
device->ShowWindow = KMSDRM_LEGACY_ShowWindow;
device->HideWindow = KMSDRM_LEGACY_HideWindow;
device->RaiseWindow = KMSDRM_LEGACY_RaiseWindow;
device->MaximizeWindow = KMSDRM_LEGACY_MaximizeWindow;
device->MinimizeWindow = KMSDRM_LEGACY_MinimizeWindow;
device->RestoreWindow = KMSDRM_LEGACY_RestoreWindow;
device->SetWindowGrab = KMSDRM_LEGACY_SetWindowGrab;
device->DestroyWindow = KMSDRM_LEGACY_DestroyWindow;
device->GetWindowWMInfo = KMSDRM_LEGACY_GetWindowWMInfo;
#if SDL_VIDEO_OPENGL_EGL
device->GL_LoadLibrary = KMSDRM_LEGACY_GLES_LoadLibrary;
device->GL_GetProcAddress = KMSDRM_LEGACY_GLES_GetProcAddress;
device->GL_UnloadLibrary = KMSDRM_LEGACY_GLES_UnloadLibrary;
device->GL_CreateContext = KMSDRM_LEGACY_GLES_CreateContext;
device->GL_MakeCurrent = KMSDRM_LEGACY_GLES_MakeCurrent;
device->GL_SetSwapInterval = KMSDRM_LEGACY_GLES_SetSwapInterval;
device->GL_GetSwapInterval = KMSDRM_LEGACY_GLES_GetSwapInterval;
device->GL_SwapWindow = KMSDRM_LEGACY_GLES_SwapWindow;
device->GL_DeleteContext = KMSDRM_LEGACY_GLES_DeleteContext;
#endif
device->PumpEvents = KMSDRM_LEGACY_PumpEvents;
device->free = KMSDRM_LEGACY_DeleteDevice;
return device;
cleanup:
if (device)
SDL_free(device);
if (viddata)
SDL_free(viddata);
return NULL;
}
VideoBootStrap KMSDRM_LEGACY_bootstrap = {
"KMSDRM_LEGACY",
"KMS/DRM Video Driver",
KMSDRM_LEGACY_CreateDevice
};
static void
KMSDRM_LEGACY_FBDestroyCallback(struct gbm_bo *bo, void *data)
{
KMSDRM_LEGACY_FBInfo *fb_info = (KMSDRM_LEGACY_FBInfo *)data;
if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) {
KMSDRM_LEGACY_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id);
}
SDL_free(fb_info);
}
KMSDRM_LEGACY_FBInfo *
KMSDRM_LEGACY_FBFromBO(_THIS, struct gbm_bo *bo)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
unsigned w,h;
int ret;
Uint32 stride, handle;
/* Check for an existing framebuffer */
KMSDRM_LEGACY_FBInfo *fb_info = (KMSDRM_LEGACY_FBInfo *)KMSDRM_LEGACY_gbm_bo_get_user_data(bo);
if (fb_info) {
return fb_info;
}
/* Create a structure that contains enough info to remove the framebuffer
when the backing buffer is destroyed */
fb_info = (KMSDRM_LEGACY_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_LEGACY_FBInfo));
if (!fb_info) {
SDL_OutOfMemory();
return NULL;
}
fb_info->drm_fd = viddata->drm_fd;
/* Create framebuffer object for the buffer */
w = KMSDRM_LEGACY_gbm_bo_get_width(bo);
h = KMSDRM_LEGACY_gbm_bo_get_height(bo);
stride = KMSDRM_LEGACY_gbm_bo_get_stride(bo);
handle = KMSDRM_LEGACY_gbm_bo_get_handle(bo).u32;
ret = KMSDRM_LEGACY_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle,
&fb_info->fb_id);
if (ret) {
SDL_free(fb_info);
return NULL;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p",
fb_info->fb_id, w, h, stride, (void *)bo);
/* Associate our DRM framebuffer with this buffer object */
KMSDRM_LEGACY_gbm_bo_set_user_data(bo, fb_info, KMSDRM_LEGACY_FBDestroyCallback);
return fb_info;
}
static void
KMSDRM_LEGACY_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
{
*((SDL_bool *) data) = SDL_FALSE;
}
SDL_bool
KMSDRM_LEGACY_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout) {
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
drmEventContext ev = {0};
struct pollfd pfd = {0};
ev.version = DRM_EVENT_CONTEXT_VERSION;
ev.page_flip_handler = KMSDRM_LEGACY_FlipHandler;
pfd.fd = viddata->drm_fd;
pfd.events = POLLIN;
while (windata->waiting_for_flip) {
pfd.revents = 0;
if (poll(&pfd, 1, timeout) < 0) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
return SDL_FALSE;
}
if (pfd.revents & (POLLHUP | POLLERR)) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
return SDL_FALSE;
}
if (pfd.revents & POLLIN) {
/* Page flip? If so, drmHandleEvent will unset windata->waiting_for_flip */
KMSDRM_LEGACY_drmHandleEvent(viddata->drm_fd, &ev);
} else {
/* Timed out and page flip didn't happen */
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Dropping frame while waiting_for_flip");
return SDL_FALSE;
}
}
return SDL_TRUE;
}
/*****************************************************************************/
/* SDL Video and Display initialization/handling functions */
/* _this is a SDL_VideoDevice * */
/*****************************************************************************/
static void
KMSDRM_LEGACY_DestroySurfaces(_THIS, SDL_Window * window)
{
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
KMSDRM_LEGACY_WaitPageFlip(_this, windata, -1);
if (windata->curr_bo) {
KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->curr_bo);
windata->curr_bo = NULL;
}
if (windata->next_bo) {
KMSDRM_LEGACY_gbm_surface_release_buffer(windata->gs, windata->next_bo);
windata->next_bo = NULL;
}
#if SDL_VIDEO_OPENGL_EGL
SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (windata->egl_surface != EGL_NO_SURFACE) {
SDL_EGL_DestroySurface(_this, windata->egl_surface);
windata->egl_surface = EGL_NO_SURFACE;
}
#endif
if (windata->gs) {
KMSDRM_LEGACY_gbm_surface_destroy(windata->gs);
windata->gs = NULL;
}
}
int
KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
SDL_DisplayData *dispdata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
Uint32 width = dispdata->mode.hdisplay;
Uint32 height = dispdata->mode.vdisplay;
Uint32 surface_fmt = GBM_FORMAT_XRGB8888;
Uint32 surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
#if SDL_VIDEO_OPENGL_EGL
EGLContext egl_context;
#endif
if (!KMSDRM_LEGACY_gbm_device_is_format_supported(viddata->gbm, surface_fmt, surface_flags)) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "GBM surface format not supported. Trying anyway.");
}
#if SDL_VIDEO_OPENGL_EGL
SDL_EGL_SetRequiredVisualId(_this, surface_fmt);
egl_context = (EGLContext)SDL_GL_GetCurrentContext();
#endif
KMSDRM_LEGACY_DestroySurfaces(_this, window);
windata->gs = KMSDRM_LEGACY_gbm_surface_create(viddata->gbm, width, height, surface_fmt, surface_flags);
if (!windata->gs) {
return SDL_SetError("Could not create GBM surface");
}
#if SDL_VIDEO_OPENGL_EGL
windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs);
if (windata->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Could not create EGL window surface");
}
SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
windata->egl_surface_dirty = 0;
#endif
return 0;
}
int
KMSDRM_LEGACY_VideoInit(_THIS)
{
int i, j, ret = 0;
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_DisplayData *dispdata = NULL;
drmModeRes *resources = NULL;
drmModeEncoder *encoder = NULL;
char devname[32];
SDL_VideoDisplay display = {0};
dispdata = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
if (!dispdata) {
return SDL_OutOfMemory();
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_LEGACY_VideoInit()");
/* Open /dev/dri/cardNN */
SDL_snprintf(devname, sizeof(devname), "/dev/dri/card%d", viddata->devindex);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", devname);
viddata->drm_fd = open(devname, O_RDWR | O_CLOEXEC);
if (viddata->drm_fd < 0) {
ret = SDL_SetError("Could not open %s", devname);
goto cleanup;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd);
viddata->gbm = KMSDRM_LEGACY_gbm_create_device(viddata->drm_fd);
if (!viddata->gbm) {
ret = SDL_SetError("Couldn't create gbm device.");
goto cleanup;
}
/* Get all of the available connectors / devices / crtcs */
resources = KMSDRM_LEGACY_drmModeGetResources(viddata->drm_fd);
if (!resources) {
ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd);
goto cleanup;
}
for (i = 0; i < resources->count_connectors; i++) {
drmModeConnector *conn = KMSDRM_LEGACY_drmModeGetConnector(viddata->drm_fd, resources->connectors[i]);
if (!conn) {
continue;
}
if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found connector %d with %d modes.",
conn->connector_id, conn->count_modes);
dispdata->conn = conn;
break;
}
KMSDRM_LEGACY_drmModeFreeConnector(conn);
}
if (!dispdata->conn) {
ret = SDL_SetError("No currently active connector found.");
goto cleanup;
}
/* Try to find the connector's current encoder */
for (i = 0; i < resources->count_encoders; i++) {
encoder = KMSDRM_LEGACY_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
if (!encoder) {
continue;
}
if (encoder->encoder_id == dispdata->conn->encoder_id) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
break;
}
KMSDRM_LEGACY_drmModeFreeEncoder(encoder);
encoder = NULL;
}
if (!encoder) {
/* No encoder was connected, find the first supported one */
for (i = 0; i < resources->count_encoders; i++) {
encoder = KMSDRM_LEGACY_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]);
if (!encoder) {
continue;
}
for (j = 0; j < dispdata->conn->count_encoders; j++) {
if (dispdata->conn->encoders[j] == encoder->encoder_id) {
break;
}
}
if (j != dispdata->conn->count_encoders) {
break;
}
KMSDRM_LEGACY_drmModeFreeEncoder(encoder);
encoder = NULL;
}
}
if (!encoder) {
ret = SDL_SetError("No connected encoder found.");
goto cleanup;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Found encoder %d.", encoder->encoder_id);
/* Try to find a CRTC connected to this encoder */
dispdata->saved_crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
if (!dispdata->saved_crtc) {
/* No CRTC was connected, find the first CRTC that can be connected */
for (i = 0; i < resources->count_crtcs; i++) {
if (encoder->possible_crtcs & (1 << i)) {
encoder->crtc_id = resources->crtcs[i];
dispdata->saved_crtc = KMSDRM_LEGACY_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id);
break;
}
}
}
if (!dispdata->saved_crtc) {
ret = SDL_SetError("No CRTC found.");
goto cleanup;
}
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Saved crtc_id %u, fb_id %u, (%u,%u), %ux%u",
dispdata->saved_crtc->crtc_id, dispdata->saved_crtc->buffer_id, dispdata->saved_crtc->x,
dispdata->saved_crtc->y, dispdata->saved_crtc->width, dispdata->saved_crtc->height);
dispdata->crtc_id = encoder->crtc_id;
/* Figure out the default mode to be set. If the current CRTC's mode isn't
valid, select the first mode supported by the connector
FIXME find first mode that specifies DRM_MODE_TYPE_PREFERRED */
dispdata->mode = dispdata->saved_crtc->mode;
if (dispdata->saved_crtc->mode_valid == 0) {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO,
"Current mode is invalid, selecting connector's mode #0.");
dispdata->mode = dispdata->conn->modes[0];
}
/* Setup the single display that's available */
display.desktop_mode.w = dispdata->mode.hdisplay;
display.desktop_mode.h = dispdata->mode.vdisplay;
display.desktop_mode.refresh_rate = dispdata->mode.vrefresh;
#if 1
display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888;
#else
/* FIXME */
drmModeFB *fb = drmModeGetFB(viddata->drm_fd, dispdata->saved_crtc->buffer_id);
display.desktop_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
drmModeFreeFB(fb);
#endif
display.current_mode = display.desktop_mode;
display.driverdata = dispdata;
SDL_AddVideoDisplay(&display, SDL_FALSE);
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Init();
#endif
KMSDRM_LEGACY_InitMouse(_this);
return ret;
cleanup:
if (encoder)
KMSDRM_LEGACY_drmModeFreeEncoder(encoder);
if (resources)
KMSDRM_LEGACY_drmModeFreeResources(resources);
if (ret != 0) {
/* Error (complete) cleanup */
if (dispdata->conn) {
KMSDRM_LEGACY_drmModeFreeConnector(dispdata->conn);
dispdata->conn = NULL;
}
if (dispdata->saved_crtc) {
KMSDRM_LEGACY_drmModeFreeCrtc(dispdata->saved_crtc);
dispdata->saved_crtc = NULL;
}
if (viddata->gbm) {
KMSDRM_LEGACY_gbm_device_destroy(viddata->gbm);
viddata->gbm = NULL;
}
if (viddata->drm_fd >= 0) {
close(viddata->drm_fd);
viddata->drm_fd = -1;
}
SDL_free(dispdata);
}
return ret;
}
void
KMSDRM_LEGACY_VideoQuit(_THIS)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(0);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_LEGACY_VideoQuit()");
if (_this->gl_config.driver_loaded) {
SDL_GL_UnloadLibrary();
}
/* Clear out the window list */
SDL_free(viddata->windows);
viddata->windows = NULL;
viddata->max_windows = 0;
viddata->num_windows = 0;
/* Restore saved CRTC settings */
if (viddata->drm_fd >= 0 && dispdata && dispdata->conn && dispdata->saved_crtc) {
drmModeConnector *conn = dispdata->conn;
drmModeCrtc *crtc = dispdata->saved_crtc;
int ret = KMSDRM_LEGACY_drmModeSetCrtc(viddata->drm_fd, crtc->crtc_id, crtc->buffer_id,
crtc->x, crtc->y, &conn->connector_id, 1, &crtc->mode);
if (ret != 0) {
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not restore original CRTC mode");
}
}
if (dispdata && dispdata->conn) {
KMSDRM_LEGACY_drmModeFreeConnector(dispdata->conn);
dispdata->conn = NULL;
}
if (dispdata && dispdata->saved_crtc) {
KMSDRM_LEGACY_drmModeFreeCrtc(dispdata->saved_crtc);
dispdata->saved_crtc = NULL;
}
if (viddata->gbm) {
KMSDRM_LEGACY_gbm_device_destroy(viddata->gbm);
viddata->gbm = NULL;
}
if (viddata->drm_fd >= 0) {
close(viddata->drm_fd);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Closed DRM FD %d", viddata->drm_fd);
viddata->drm_fd = -1;
}
#ifdef SDL_INPUT_LINUXEV
SDL_EVDEV_Quit();
#endif
}
void
KMSDRM_LEGACY_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
SDL_DisplayData *dispdata = display->driverdata;
drmModeConnector *conn = dispdata->conn;
SDL_DisplayMode mode;
int i;
for (i = 0; i < conn->count_modes; i++) {
SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData));
if (modedata) {
modedata->mode_index = i;
}
mode.w = conn->modes[i].hdisplay;
mode.h = conn->modes[i].vdisplay;
mode.refresh_rate = conn->modes[i].vrefresh;
mode.format = SDL_PIXELFORMAT_ARGB8888;
mode.driverdata = modedata;
if (!SDL_AddDisplayMode(display, &mode)) {
SDL_free(modedata);
}
}
}
int
KMSDRM_LEGACY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata;
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
drmModeConnector *conn = dispdata->conn;
int i;
if (!modedata) {
return SDL_SetError("Mode doesn't have an associated index");
}
dispdata->mode = conn->modes[modedata->mode_index];
for (i = 0; i < viddata->num_windows; i++) {
SDL_Window *window = viddata->windows[i];
SDL_WindowData *windata = (SDL_WindowData *)window->driverdata;
#if SDL_VIDEO_OPENGL_EGL
/* Can't recreate EGL surfaces right now, need to wait until SwapWindow
so the correct thread-local surface and context state are available */
windata->egl_surface_dirty = 1;
#else
if (KMSDRM_LEGACY_CreateSurfaces(_this, window)) {
return -1;
}
#endif
/* Tell app about the resize */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode->w, mode->h);
}
return 0;
}
int
KMSDRM_LEGACY_CreateWindow(_THIS, SDL_Window * window)
{
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
SDL_WindowData *windata;
SDL_VideoDisplay *display;
#if SDL_VIDEO_OPENGL_EGL
if (!_this->egl_data) {
if (SDL_GL_LoadLibrary(NULL) < 0) {
goto error;
}
}
#endif
/* Allocate window internal data */
windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
if (!windata) {
SDL_OutOfMemory();
goto error;
}
/* Windows have one size for now */
display = SDL_GetDisplayForWindow(window);
window->w = display->desktop_mode.w;
window->h = display->desktop_mode.h;
/* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
/* In case we want low-latency, double-buffer video, we take note here */
windata->double_buffer = SDL_FALSE;
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
windata->double_buffer = SDL_TRUE;
}
/* Setup driver data for this window */
windata->viddata = viddata;
window->driverdata = windata;
if (KMSDRM_LEGACY_CreateSurfaces(_this, window)) {
goto error;
}
/* Add window to the internal list of tracked windows. Note, while it may
seem odd to support multiple fullscreen windows, some apps create an
extra window as a dummy surface when working with multiple contexts */
if (viddata->num_windows >= viddata->max_windows) {
int new_max_windows = viddata->max_windows + 1;
viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows,
new_max_windows * sizeof(SDL_Window *));
viddata->max_windows = new_max_windows;
if (!viddata->windows) {
SDL_OutOfMemory();
goto error;
}
}
viddata->windows[viddata->num_windows++] = window;
/* Focus on the newly created window */
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
return 0;
error:
KMSDRM_LEGACY_DestroyWindow(_this, window);
return -1;
}
void
KMSDRM_LEGACY_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *windata = (SDL_WindowData *) window->driverdata;
SDL_VideoData *viddata;
int i, j;
if (!windata) {
return;
}
/* Remove from the internal window list */
viddata = windata->viddata;
for (i = 0; i < viddata->num_windows; i++) {
if (viddata->windows[i] == window) {
viddata->num_windows--;
for (j = i; j < viddata->num_windows; j++) {
viddata->windows[j] = viddata->windows[j + 1];
}
break;
}
}
KMSDRM_LEGACY_DestroySurfaces(_this, window);
window->driverdata = NULL;
SDL_free(windata);
}
int
KMSDRM_LEGACY_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
return -1;
}
void
KMSDRM_LEGACY_SetWindowTitle(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
}
void
KMSDRM_LEGACY_SetWindowPosition(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_SetWindowSize(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_ShowWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_HideWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_RaiseWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_MaximizeWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_MinimizeWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_RestoreWindow(_THIS, SDL_Window * window)
{
}
void
KMSDRM_LEGACY_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
}
/*****************************************************************************/
/* SDL Window Manager function */
/*****************************************************************************/
SDL_bool
KMSDRM_LEGACY_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
if (info->version.major <= SDL_MAJOR_VERSION) {
return SDL_TRUE;
} else {
SDL_SetError("application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
/* Failed to get window manager information */
return SDL_FALSE;
}
#endif /* SDL_VIDEO_DRIVER_KMSDRM */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,132 +0,0 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef __SDL_KMSDRM_LEGACYVIDEO_H__
#define __SDL_KMSDRM_LEGACYVIDEO_H__
#include "../SDL_sysvideo.h"
#include <fcntl.h>
#include <unistd.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <gbm.h>
#if SDL_VIDEO_OPENGL_EGL
#include <EGL/egl.h>
#endif
typedef struct SDL_VideoData
{
int devindex; /* device index that was passed on creation */
int drm_fd; /* DRM file desc */
struct gbm_device *gbm;
SDL_Window **windows;
int max_windows;
int num_windows;
} SDL_VideoData;
typedef struct SDL_DisplayModeData
{
int mode_index;
} SDL_DisplayModeData;
typedef struct SDL_DisplayData
{
uint32_t crtc_id;
drmModeConnector *conn;
drmModeModeInfo mode;
drmModeCrtc *saved_crtc; /* CRTC to restore on quit */
} SDL_DisplayData;
typedef struct SDL_WindowData
{
SDL_VideoData *viddata;
struct gbm_surface *gs;
struct gbm_bo *curr_bo;
struct gbm_bo *next_bo;
struct gbm_bo *crtc_bo;
SDL_bool waiting_for_flip;
SDL_bool double_buffer;
#if SDL_VIDEO_OPENGL_EGL
int egl_surface_dirty;
EGLSurface egl_surface;
#endif
} SDL_WindowData;
typedef struct KMSDRM_LEGACY_FBInfo
{
int drm_fd; /* DRM file desc */
uint32_t fb_id; /* DRM framebuffer ID */
} KMSDRM_LEGACY_FBInfo;
/* Helper functions */
int KMSDRM_LEGACY_CreateSurfaces(_THIS, SDL_Window * window);
KMSDRM_LEGACY_FBInfo *KMSDRM_LEGACY_FBFromBO(_THIS, struct gbm_bo *bo);
SDL_bool KMSDRM_LEGACY_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout);
/****************************************************************************/
/* SDL_VideoDevice functions declaration */
/****************************************************************************/
/* Display and window functions */
int KMSDRM_LEGACY_VideoInit(_THIS);
void KMSDRM_LEGACY_VideoQuit(_THIS);
void KMSDRM_LEGACY_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
int KMSDRM_LEGACY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
int KMSDRM_LEGACY_CreateWindow(_THIS, SDL_Window * window);
int KMSDRM_LEGACY_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
void KMSDRM_LEGACY_SetWindowTitle(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
void KMSDRM_LEGACY_SetWindowPosition(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowSize(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_ShowWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_HideWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_RaiseWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_MaximizeWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_MinimizeWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_RestoreWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
void KMSDRM_LEGACY_DestroyWindow(_THIS, SDL_Window * window);
/* Window manager function */
SDL_bool KMSDRM_LEGACY_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
/* OpenGL/OpenGL ES functions */
int KMSDRM_LEGACY_GLES_LoadLibrary(_THIS, const char *path);
void *KMSDRM_LEGACY_GLES_GetProcAddress(_THIS, const char *proc);
void KMSDRM_LEGACY_GLES_UnloadLibrary(_THIS);
SDL_GLContext KMSDRM_LEGACY_GLES_CreateContext(_THIS, SDL_Window * window);
int KMSDRM_LEGACY_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
int KMSDRM_LEGACY_GLES_SetSwapInterval(_THIS, int interval);
int KMSDRM_LEGACY_GLES_GetSwapInterval(_THIS);
int KMSDRM_LEGACY_GLES_SwapWindow(_THIS, SDL_Window * window);
void KMSDRM_LEGACY_GLES_DeleteContext(_THIS, SDL_GLContext context);
#endif /* __SDL_KMSDRM_LEGACYVIDEO_H__ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,171 +0,0 @@
/*
gradd.h structures and constants -- only the ones used by SDL_os2vman.c.
Based on public knowledge from around the internet including pages from
http://www.osfree.org and http://www.edm2.com
*/
#ifndef my_gradd_h_
#define my_gradd_h_
typedef struct _INITPROCOUT {
ULONG ulLength; /* Length of the INITPROCOUT data structure, in bytes. */
ULONG ulVRAMVirt; /* 32-bit virtual address of VRAM. */
} INITPROCOUT;
typedef INITPROCOUT *PINITPROCOUT;
#define RC_SUCCESS 0
typedef ULONG GID;
typedef ULONG (_System FNVMIENTRY) (
GID gid, ULONG ulFunction,
PVOID pIn,
PVOID pOut /* PINITPROCOUT */
);
#define VMI_CMD_INITPROC 1
#define VMI_CMD_TERMPROC 3
#define VMI_CMD_QUERYMODES 5
#define VMI_CMD_SETMODE 6
#define VMI_CMD_PALETTE 7
#define VMI_CMD_BITBLT 8
#define VMI_CMD_LINE 9
#define VMI_CMD_REQUESTHW 14
#define VMI_CMD_QUERYCURRENTMODE 0x1001
#define QUERYMODE_NUM_MODES 0x01
#define QUERYMODE_MODE_DATA 0x02
typedef struct _HWPALETTEINFO {
ULONG ulLength; /* Size of the HWPALETTEINFO data structure, in bytes. */
ULONG fFlags; /* Palette flag. */
ULONG ulStartIndex; /* Starting palette index. */
ULONG ulNumEntries; /* Number of palette slots to query or set. */
PRGB2 pRGBs; /* Pointer to the array of RGB values. */
} HWPALETTEINFO;
typedef HWPALETTEINFO *PHWPALETTEINFO;
#define PALETTE_GET 0x01
#define PALETTE_SET 0x02
typedef struct _BMAPINFO {
ULONG ulLength; /* Length of the BMAPINFO data structure, in bytes. */
ULONG ulType; /* Description of the Blt. */
ULONG ulWidth; /* Width in pels of the bit map. */
ULONG ulHeight; /* Height in pels of the bit map. */
ULONG ulBpp; /* Number of bits per pel/color depth. */
ULONG ulBytesPerLine; /* Number of aligned bytes per line. */
PBYTE pBits; /* Pointer to bit-map bits. */
} BMAPINFO;
typedef BMAPINFO *PBMAPINFO;
#define BMAP_VRAM 0
#define BMAP_MEMORY 1
typedef struct _LINEPACK {
ULONG ulStyleStep; /* Value to be added to ulStyleValue. */
ULONG ulStyleValue; /* Style value at the current pel. */
ULONG ulFlags; /* Flags used for the LINEPACK data structure. */
struct _LINEPACK *plpkNext; /* Pointer to next LINEPACK data structure. */
ULONG ulAbsDeltaX; /* Clipped Bresenham Delta X, absolute. */
ULONG ulAbsDeltaY; /* Clipped Bresenham Delta Y, absolute. */
POINTL ptlClipStart; /* Pointer to location for device to perform Bresenham algorithm. */
POINTL ptlClipEnd; /* Ending location for Bresenham algorithm (see ptlClipStart). */
POINTL ptlStart; /* Pointer to starting location for line. */
POINTL ptlEnd; /* Ending location for line. */
LONG lClipStartError;/* Standard Bresenham error at the clipped start point. */
} LINEPACK;
typedef LINEPACK *PLINEPACK;
typedef struct _LINEINFO {
ULONG ulLength; /* Length of LINEINFO data structure. */
ULONG ulType; /* Defines line type. */
ULONG ulStyleMask; /* A 32-bit style mask. */
ULONG cLines; /* Count of lines to be drawn. */
ULONG ulFGColor; /* Line Foreground color. */
ULONG ulBGColor; /* Line Background color. */
USHORT usForeROP; /* Line Foreground mix. */
USHORT usBackROP; /* Line Background mix. */
PBMAPINFO pDstBmapInfo; /* Pointer to destination surface bit map. */
PLINEPACK alpkLinePack; /* Pointer to LINEPACK data structure. */
PRECTL prclBounds; /* Pointer to bounding rect of a clipped line. */
} LINEINFO;
typedef LINEINFO *PLINEINFO;
#define LINE_DO_FIRST_PEL 0x02
#define LINE_DIR_Y_POSITIVE 0x04
#define LINE_HORIZONTAL 0x08
#define LINE_DIR_X_POSITIVE 0x20
#define LINE_VERTICAL 0x1000
#define LINE_DO_LAST_PEL 0x4000
#define LINE_SOLID 0x01
typedef struct _BLTRECT {
ULONG ulXOrg; /* X origin of the destination Blt. */
ULONG ulYOrg; /* Y origin of the destination Blt. */
ULONG ulXExt; /* X extent of the BitBlt. */
ULONG ulYExt; /* Y extent of the BitBlt. */
} BLTRECT;
typedef BLTRECT *PBLTRECT;
typedef struct _BITBLTINFO {
ULONG ulLength; /* Length of the BITBLTINFO data structure, in bytes. */
ULONG ulBltFlags; /* Flags for rendering of rasterized data. */
ULONG cBlits; /* Count of Blts to be performed. */
ULONG ulROP; /* Raster operation. */
ULONG ulMonoBackROP; /* Background mix if B_APPLY_BACK_ROP is set. */
ULONG ulSrcFGColor; /* Monochrome source Foreground color. */
ULONG ulSrcBGColor; /* Monochrome source Background color and transparent color. */
ULONG ulPatFGColor; /* Monochrome pattern Foreground color. */
ULONG ulPatBGColor; /* Monochrome pattern Background color. */
PBYTE abColors; /* Pointer to color translation table. */
PBMAPINFO pSrcBmapInfo; /* Pointer to source bit map (BMAPINFO) */
PBMAPINFO pDstBmapInfo; /* Pointer to destination bit map (BMAPINFO). */
PBMAPINFO pPatBmapInfo; /* Pointer to pattern bit map (BMAPINFO). */
PPOINTL aptlSrcOrg; /* Pointer to array of source origin POINTLs. */
PPOINTL aptlPatOrg; /* Pointer to array of pattern origin POINTLs. */
PBLTRECT abrDst; /* Pointer to array of Blt rects. */
PRECTL prclSrcBounds; /* Pointer to source bounding rect of source Blts. */
PRECTL prclDstBounds; /* Pointer to destination bounding rect of destination Blts. */
} BITBLTINFO;
typedef BITBLTINFO *PBITBLTINFO;
#define BF_DEFAULT_STATE 0x0
#define BF_ROP_INCL_SRC (0x01 << 2)
#define BF_PAT_HOLLOW (0x01 << 8)
typedef struct _GDDMODEINFO {
ULONG ulLength; /* Size of the GDDMODEINFO data structure, in bytes. */
ULONG ulModeId; /* ID used to make SETMODE request. */
ULONG ulBpp; /* Number of colors (bpp). */
ULONG ulHorizResolution;/* Number of horizontal pels. */
ULONG ulVertResolution; /* Number of vertical scan lines. */
ULONG ulRefreshRate; /* Refresh rate in Hz. */
PBYTE pbVRAMPhys; /* Physical address of VRAM. */
ULONG ulApertureSize; /* Size of VRAM, in bytes. */
ULONG ulScanLineSize; /* Size of one scan line, in bytes. */
ULONG fccColorEncoding, ulTotalVRAMSize, cColors;
} GDDMODEINFO;
typedef GDDMODEINFO *PGDDMODEINFO;
typedef struct _HWREQIN {
ULONG ulLength; /* Size of the HWREQIN data structure, in bytes. */
ULONG ulFlags; /* Request option flags. */
ULONG cScrChangeRects; /* Count of screen rectangles affected by HWREQIN. */
PRECTL arectlScreen; /* Array of screen rectangles affected by HWREQIN. */
} HWREQIN;
typedef HWREQIN *PHWREQIN;
#define REQUEST_HW 0x01
/*
BOOL GreDeath(HDC hdc, PVOID pInstance, LONG lFunction);
LONG GreResurrection(HDC hdc, LONG cbVmem, PULONG pReserved, PVOID pInstance, LONG lFunction);
*/
#define GreDeath(h) (BOOL)Gre32Entry3((ULONG)(h), 0, 0x40B7L)
#define GreResurrection(h,n,r) (LONG)Gre32Entry5((ULONG)(h), (ULONG)(n), (ULONG)(r), 0, 0x40B8L)
ULONG _System Gre32Entry3(ULONG, ULONG, ULONG);
ULONG _System Gre32Entry5(ULONG, ULONG, ULONG, ULONG, ULONG);
#endif /* my_gradd_h_ */

View File

@@ -1,350 +0,0 @@
/*
Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
Copyright © 2009 Red Hat, Inc.
Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_X11
#include <X11/X.h>
#include "imKStoUCS.h"
static unsigned short const keysym_to_unicode_1a1_1ff[] = {
0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */
0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */
0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */
0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */
0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */
0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */
0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */
0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */
0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */
0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */
0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */
0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */
};
static unsigned short const keysym_to_unicode_2a1_2fe[] = {
0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */
0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */
0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */
0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */
0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */
0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */
};
static unsigned short const keysym_to_unicode_3a2_3fe[] = {
0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */
0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */
0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */
0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */
0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */
0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */
0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */
0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */
0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */
0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */
};
static unsigned short const keysym_to_unicode_4a1_4df[] = {
0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */
0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */
0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */
0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */
0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */
0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */
0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */
0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */
};
static unsigned short const keysym_to_unicode_590_5fe[] = {
0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */
0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */
0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */
0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */
0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */
0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */
0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */
0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */
0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */
0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */
0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */
};
static unsigned short keysym_to_unicode_680_6ff[] = {
0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */
0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */
0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */
0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */
0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */
0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */
0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */
0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */
0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */
0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */
0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */
0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */
0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */
0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */
0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */
0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */
};
static unsigned short const keysym_to_unicode_7a1_7f9[] = {
0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */
0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */
0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */
0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */
0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */
0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */
0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */
0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */
0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */
0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */
0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */
0x03c8, 0x03c9 /* 0x07f8-0x07ff */
};
static unsigned short const keysym_to_unicode_8a4_8fe[] = {
0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */
0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */
0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */
0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x21d2, 0x0000, /* 0x08c8-0x08cf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */
0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, /* 0x08e8-0x08ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */
0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */
};
static unsigned short const keysym_to_unicode_9df_9f8[] = {
0x2422, /* 0x09d8-0x09df */
0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */
0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */
0x2502 /* 0x09f8-0x09ff */
};
static unsigned short const keysym_to_unicode_aa1_afe[] = {
0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */
0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */
0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */
0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */
0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */
0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */
0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x2030, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */
0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */
0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */
0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */
0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */
0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */
};
/* none of the APL keysyms match the Unicode characters */
static unsigned short const keysym_to_unicode_cdf_cfa[] = {
0x2017, /* 0x0cd8-0x0cdf */
0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */
0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */
0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */
0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */
};
static unsigned short const keysym_to_unicode_da1_df9[] = {
0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */
0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */
0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */
0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */
0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */
0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */
0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */
0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */
0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */
0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */
0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */
0x0e58, 0x0e59 /* 0x0df8-0x0dff */
};
static unsigned short const keysym_to_unicode_ea0_eff[] = {
0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */
0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */
0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */
0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */
0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */
0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */
0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */
0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */
0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */
0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */
0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */
0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */
};
static unsigned short keysym_to_unicode_12a1_12fe[] = {
0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */
0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */
0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */
0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */
0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */
0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */
};
static unsigned short const keysym_to_unicode_13bc_13be[] = {
0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */
};
static unsigned short keysym_to_unicode_14a1_14ff[] = {
0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */
0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */
0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */
0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */
0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */
0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */
0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */
0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */
0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */
0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */
0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */
0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */
};
static unsigned short keysym_to_unicode_15d0_15f6[] = {
0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */
0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */
0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */
0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */
0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */
};
static unsigned short keysym_to_unicode_16a0_16f6[] = {
0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */
0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */
0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */
0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */
0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */
0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */
};
static unsigned short const keysym_to_unicode_1e9f_1eff[] = {
0x0303,
0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */
0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */
0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */
0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */
0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */
0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */
0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */
0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */
0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */
0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */
0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */
0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */
};
static unsigned short const keysym_to_unicode_20a0_20ac[] = {
0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */
0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */
};
unsigned int
X11_KeySymToUcs4(KeySym keysym)
{
/* 'Unicode keysym' */
if ((keysym & 0xff000000) == 0x01000000)
return (keysym & 0x00ffffff);
if (keysym > 0 && keysym < 0x100)
return keysym;
else if (keysym > 0x1a0 && keysym < 0x200)
return keysym_to_unicode_1a1_1ff[keysym - 0x1a1];
else if (keysym > 0x2a0 && keysym < 0x2ff)
return keysym_to_unicode_2a1_2fe[keysym - 0x2a1];
else if (keysym > 0x3a1 && keysym < 0x3ff)
return keysym_to_unicode_3a2_3fe[keysym - 0x3a2];
else if (keysym > 0x4a0 && keysym < 0x4e0)
return keysym_to_unicode_4a1_4df[keysym - 0x4a1];
else if (keysym > 0x589 && keysym < 0x5ff)
return keysym_to_unicode_590_5fe[keysym - 0x590];
else if (keysym > 0x67f && keysym < 0x700)
return keysym_to_unicode_680_6ff[keysym - 0x680];
else if (keysym > 0x7a0 && keysym < 0x7fa)
return keysym_to_unicode_7a1_7f9[keysym - 0x7a1];
else if (keysym > 0x8a3 && keysym < 0x8ff)
return keysym_to_unicode_8a4_8fe[keysym - 0x8a4];
else if (keysym > 0x9de && keysym < 0x9f9)
return keysym_to_unicode_9df_9f8[keysym - 0x9df];
else if (keysym > 0xaa0 && keysym < 0xaff)
return keysym_to_unicode_aa1_afe[keysym - 0xaa1];
else if (keysym > 0xcde && keysym < 0xcfb)
return keysym_to_unicode_cdf_cfa[keysym - 0xcdf];
else if (keysym > 0xda0 && keysym < 0xdfa)
return keysym_to_unicode_da1_df9[keysym - 0xda1];
else if (keysym > 0xe9f && keysym < 0xf00)
return keysym_to_unicode_ea0_eff[keysym - 0xea0];
else if (keysym > 0x12a0 && keysym < 0x12ff)
return keysym_to_unicode_12a1_12fe[keysym - 0x12a1];
else if (keysym > 0x13bb && keysym < 0x13bf)
return keysym_to_unicode_13bc_13be[keysym - 0x13bc];
else if (keysym > 0x14a0 && keysym < 0x1500)
return keysym_to_unicode_14a1_14ff[keysym - 0x14a1];
else if (keysym > 0x15cf && keysym < 0x15f7)
return keysym_to_unicode_15d0_15f6[keysym - 0x15d0];
else if (keysym > 0x169f && keysym < 0x16f7)
return keysym_to_unicode_16a0_16f6[keysym - 0x16a0];
else if (keysym > 0x1e9e && keysym < 0x1f00)
return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f];
else if (keysym > 0x209f && keysym < 0x20ad)
return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
else
return 0;
}
#endif /* SDL_VIDEO_DRIVER_X11 */

View File

@@ -1,32 +0,0 @@
#ifndef _imKStoUCS_h
#define _imKStoUCS_h
/*
Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
Copyright © 2009 Red Hat, Inc.
Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
extern unsigned int X11_KeySymToUcs4(KeySym keysym);
#endif /* _imKStoUCS_h */