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:
35
externals/SDL/src/hidapi/SDL_hidapi.h
vendored
35
externals/SDL/src/hidapi/SDL_hidapi.h
vendored
@@ -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: */
|
333
externals/SDL/src/hidapi/linux/hid.cpp
vendored
333
externals/SDL/src/hidapi/linux/hid.cpp
vendored
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
784
externals/SDL/src/joystick/bsd/SDL_sysjoystick.c
vendored
784
externals/SDL/src/joystick/bsd/SDL_sysjoystick.c
vendored
@@ -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: */
|
1066
externals/SDL/src/joystick/darwin/SDL_sysjoystick.c
vendored
1066
externals/SDL/src/joystick/darwin/SDL_sysjoystick.c
vendored
File diff suppressed because it is too large
Load Diff
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
515
externals/SDL/src/joystick/windows/SDL_mmjoystick.c
vendored
515
externals/SDL/src/joystick/windows/SDL_mmjoystick.c
vendored
@@ -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, ®size);
|
||||
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, ®size);
|
||||
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, ®size);
|
||||
}
|
||||
}
|
||||
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: */
|
@@ -1,4 +0,0 @@
|
||||
float4 main( float2 vTexcoord : TEXCOORD0, uniform sampler2D tex, uniform float4 uTintColor)
|
||||
{
|
||||
return tex2D(tex, vTexcoord) * uTintColor;
|
||||
}
|
282
externals/SDL/src/thread/windows/SDL_syscond_srw.c
vendored
282
externals/SDL/src/thread/windows/SDL_syscond_srw.c
vendored
@@ -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: */
|
@@ -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: */
|
286
externals/SDL/src/video/cocoa/SDL_cocoamousetap.m
vendored
286
externals/SDL/src/video/cocoa/SDL_cocoamousetap.m
vendored
@@ -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: */
|
@@ -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
|
@@ -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: */
|
@@ -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: */
|
@@ -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 */
|
||||
|
@@ -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_ */
|
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
@@ -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: */
|
171
externals/SDL/src/video/os2/my_gradd.h
vendored
171
externals/SDL/src/video/os2/my_gradd.h
vendored
@@ -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_ */
|
350
externals/SDL/src/video/x11/imKStoUCS.c
vendored
350
externals/SDL/src/video/x11/imKStoUCS.c
vendored
@@ -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 */
|
||||
|
32
externals/SDL/src/video/x11/imKStoUCS.h
vendored
32
externals/SDL/src/video/x11/imKStoUCS.h
vendored
@@ -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 */
|
Reference in New Issue
Block a user