Beispiel #1
0
/*
 * Helper function to determine pre-calculated offset to certain joystick mappings
 */
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
    SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
    ControllerMapping_t *mapping;

    mapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
#if SDL_JOYSTICK_XINPUT
    if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
        mapping = s_pXInputMapping;
    }
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
    if (!mapping && s_pEmscriptenMapping) {
        mapping = s_pEmscriptenMapping;
    }
#endif
    if (!mapping) {
        const char *name = SDL_JoystickNameForIndex(device_index);
        if (name) {
            if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box")) {
                mapping = s_pXInputMapping;
            }
        }
    }
    return mapping;
}
Beispiel #2
0
static SDL_bool
HasExtension(const char *extension, const char *extensions)
{
    const char *start;
    const char *where, *terminator;

    /* Extension names should not have spaces. */
    where = SDL_strchr(extension, ' ');
    if (where || *extension == '\0')
        return SDL_FALSE;

    if (!extensions)
        return SDL_FALSE;

    /* It takes a bit of care to be fool-proof about parsing the
     * OpenGL extensions string. Don't be fooled by sub-strings,
     * etc. */

    start = extensions;

    for (;;) {
        where = SDL_strstr(start, extension);
        if (!where)
            break;

        terminator = where + SDL_strlen(extension);
        if (where == start || *(where - 1) == ' ')
            if (*terminator == ' ' || *terminator == '\0')
                return SDL_TRUE;

        start = terminator;
    }
    return SDL_FALSE;
}
Beispiel #3
0
static int glXExtensionSupported(_THIS, const char *extension)
{
	const char *extensions;
	const char *start;
	const char *where, *terminator;

	/* Extension names should not have spaces. */
	where = SDL_strchr(extension, ' ');
	if ( where || *extension == '\0' ) {
	      return 0;
	}

	extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen);
	/* It takes a bit of care to be fool-proof about parsing the
	 * OpenGL extensions string. Don't be fooled by sub-strings, etc.
	 */
	
	start = extensions;
	
	for (;;) {
		where = SDL_strstr(start, extension);
		if (!where) break;
		
		terminator = where + strlen(extension);
		if (where == start || *(where - 1) == ' ')
	        if (*terminator == ' ' || *terminator == '\0') return 1;
						  
		start = terminator;
	}
	return 0;
}
Beispiel #4
0
static int glXExtensionSupported(_THIS, const char *extension)
{
	const char *extensions;
	const char *start;
	const char *where, *terminator;

	
	where = SDL_strchr(extension, ' ');
	if ( where || *extension == '\0' ) {
	      return 0;
	}

	extensions = this->gl_data->glXQueryExtensionsString(GFX_Display,SDL_Screen);

	
	if (extensions == NULL) {
	      return 0;
	}
	
	start = extensions;
	
	for (;;) {
		where = SDL_strstr(start, extension);
		if (!where) break;
		
		terminator = where + strlen(extension);
		if (where == start || *(where - 1) == ' ')
	        if (*terminator == ' ' || *terminator == '\0') return 1;
						  
		start = terminator;
	}
	return 0;
}
Beispiel #5
0
/*
 * Helper function to determine pre-calculated offset to certain joystick mappings
 */
static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
    SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
    ControllerMapping_t *mapping;

    mapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
#if SDL_JOYSTICK_XINPUT
    if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
        mapping = s_pXInputMapping;
    }
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
    if (!mapping && s_pEmscriptenMapping) {
        mapping = s_pEmscriptenMapping;
    }
#endif
#ifdef __LINUX__
    if (!mapping) {
        const char *name = SDL_JoystickNameForIndex(device_index);
        if (name) {
            if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
                /* The Linux driver xpad.c maps the wireless dpad to buttons */
                SDL_bool existing;
                mapping = SDL_PrivateAddMappingForGUID(jGUID,
"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
                              &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
            }
        }
    }
#endif /* __LINUX__ */

    if (!mapping) {
        const char *name = SDL_JoystickNameForIndex(device_index);
        if (name) {
            if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box")) {
                mapping = s_pXInputMapping;
            }
        }
    }
    return mapping;
}
Beispiel #6
0
/* See if an image is contained in a data source */
int IMG_isSVG(SDL_RWops *src)
{
    Sint64 start;
    int is_SVG;
    char magic[4096];
    size_t magic_len;

    if ( !src )
        return 0;
    start = SDL_RWtell(src);
    is_SVG = 0;
    magic_len = SDL_RWread(src, magic, 1, sizeof(magic) - 1);
    magic[magic_len] = '\0';
    if ( SDL_strstr(magic, "<svg") ) {
        is_SVG = 1;
    }
    SDL_RWseek(src, start, RW_SEEK_SET);
    return(is_SVG);
}
Beispiel #7
0
static void
InitIME()
{
    static SDL_bool inited = SDL_FALSE;
#ifdef HAVE_FCITX_FRONTEND_H
    const char *im_module = SDL_getenv("SDL_IM_MODULE");
    const char *xmodifiers = SDL_getenv("XMODIFIERS");
#endif

    if (inited == SDL_TRUE)
        return;

    inited = SDL_TRUE;

    /* See if fcitx IME support is being requested */
#ifdef HAVE_FCITX_FRONTEND_H
    if (!SDL_IME_Init_Real &&
        ((im_module && SDL_strcmp(im_module, "fcitx") == 0) ||
         (!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) {
        SDL_IME_Init_Real = SDL_Fcitx_Init;
        SDL_IME_Quit_Real = SDL_Fcitx_Quit;
        SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus;
        SDL_IME_Reset_Real = SDL_Fcitx_Reset;
        SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent;
        SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect;
        SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents;
    }
#endif /* HAVE_FCITX_FRONTEND_H */

    /* default to IBus */
#ifdef HAVE_IBUS_IBUS_H
    if (!SDL_IME_Init_Real) {
        SDL_IME_Init_Real = SDL_IBus_Init;
        SDL_IME_Quit_Real = SDL_IBus_Quit;
        SDL_IME_SetFocus_Real = SDL_IBus_SetFocus;
        SDL_IME_Reset_Real = SDL_IBus_Reset;
        SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent;
        SDL_IME_UpdateTextRect_Real = SDL_IBus_UpdateTextRect;
        SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents;
    }
#endif /* HAVE_IBUS_IBUS_H */
}
int
X11_VideoInit(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;

    /* Get the window class name, usually the name of the application */
    data->classname = get_classname();

    /* Get the process PID to be associated to the window */
    data->pid = getpid();

    /* I have no idea how random this actually is, or has to be. */
    data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this));

    /* Open a connection to the X input manager */
#ifdef X_HAVE_UTF8_STRING
    if (SDL_X11_HAVE_UTF8) {
        /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that 
           Compose keys will work correctly. */
        char *prev_locale = setlocale(LC_ALL, NULL);
        char *prev_xmods  = X11_XSetLocaleModifiers(NULL);
        const char *new_xmods = "";
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
        const char *env_xmods = SDL_getenv("XMODIFIERS");
#endif
        SDL_bool has_dbus_ime_support = SDL_FALSE;

        if (prev_locale) {
            prev_locale = SDL_strdup(prev_locale);
        }

        if (prev_xmods) {
            prev_xmods = SDL_strdup(prev_xmods);
        }

        /* IBus resends some key events that were filtered by XFilterEvents
           when it is used via XIM which causes issues. Prevent this by forcing
           @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via 
           the DBus implementation, which also has support for pre-editing. */
#ifdef HAVE_IBUS_IBUS_H
        if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
            has_dbus_ime_support = SDL_TRUE;
        }
#endif
#ifdef HAVE_FCITX_FRONTEND_H
        if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
            has_dbus_ime_support = SDL_TRUE;
        }
#endif
        if (has_dbus_ime_support) {
            new_xmods = "@im=none";
        }

        setlocale(LC_ALL, "");
        X11_XSetLocaleModifiers(new_xmods);

        data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);

        /* Reset the locale + X locale modifiers back to how they were,
           locale first because the X locale modifiers depend on it. */
        setlocale(LC_ALL, prev_locale);
        X11_XSetLocaleModifiers(prev_xmods);

        if (prev_locale) {
            SDL_free(prev_locale);
        }

        if (prev_xmods) {
            SDL_free(prev_xmods);
        }
    }
#endif

    /* Look up some useful Atoms */
#define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False)
    GET_ATOM(WM_PROTOCOLS);
    GET_ATOM(WM_DELETE_WINDOW);
    GET_ATOM(WM_TAKE_FOCUS);
    GET_ATOM(_NET_WM_STATE);
    GET_ATOM(_NET_WM_STATE_HIDDEN);
    GET_ATOM(_NET_WM_STATE_FOCUSED);
    GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
    GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
    GET_ATOM(_NET_WM_STATE_FULLSCREEN);
    GET_ATOM(_NET_WM_STATE_ABOVE);
    GET_ATOM(_NET_WM_STATE_SKIP_TASKBAR);
    GET_ATOM(_NET_WM_STATE_SKIP_PAGER);
    GET_ATOM(_NET_WM_ALLOWED_ACTIONS);
    GET_ATOM(_NET_WM_ACTION_FULLSCREEN);
    GET_ATOM(_NET_WM_NAME);
    GET_ATOM(_NET_WM_ICON_NAME);
    GET_ATOM(_NET_WM_ICON);
    GET_ATOM(_NET_WM_PING);
    GET_ATOM(_NET_WM_WINDOW_OPACITY);
    GET_ATOM(_NET_WM_USER_TIME);
    GET_ATOM(_NET_ACTIVE_WINDOW);
    GET_ATOM(_NET_FRAME_EXTENTS);
    GET_ATOM(UTF8_STRING);
    GET_ATOM(PRIMARY);
    GET_ATOM(XdndEnter);
    GET_ATOM(XdndPosition);
    GET_ATOM(XdndStatus);
    GET_ATOM(XdndTypeList);
    GET_ATOM(XdndActionCopy);
    GET_ATOM(XdndDrop);
    GET_ATOM(XdndFinished);
    GET_ATOM(XdndSelection);
    GET_ATOM(XKLAVIER_STATE);

    /* Detect the window manager */
    X11_CheckWindowManager(_this);

    if (X11_InitModes(_this) < 0) {
        return -1;
    }

    X11_InitXinput2(_this);

    if (X11_InitKeyboard(_this) != 0) {
        return -1;
    }
    X11_InitMouse(_this);

    X11_InitTouch(_this);

#if SDL_USE_LIBDBUS
    SDL_DBus_Init();
#endif

    return 0;
}
Beispiel #9
0
/* We can't really tell what device is being used for XInput, but we can guess
   and we'll be correct for the case where only one device is connected.
 */
static void
GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
{
#ifndef __WINRT__   /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */

    PRAWINPUTDEVICELIST devices = NULL;
    UINT i, j, device_count = 0;

    if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
        return;  /* oh well. */
    }

    devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
    if (devices == NULL) {
        return;
    }

    if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) {
        SDL_free(devices);
        return;  /* oh well. */
    }

    for (i = 0; i < device_count; i++) {
        RID_DEVICE_INFO rdi;
        char devName[128];
        UINT rdiSize = sizeof(rdi);
        UINT nameSize = SDL_arraysize(devName);

        rdi.cbSize = sizeof(rdi);
        if ((devices[i].dwType == RIM_TYPEHID) &&
            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
            (SDL_strstr(devName, "IG_") != NULL)) {
            SDL_bool found = SDL_FALSE;
            for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
                if (j == userid) {
                    continue;
                }
                if (!s_arrXInputDevicePath[j]) {
                    continue;
                }
                if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
                    found = SDL_TRUE;
                    break;
                }
            }
            if (found) {
                /* We already have this device in our XInput device list */
                continue;
            }

            /* We don't actually know if this is the right device for this
             * userid, but we'll record it so we'll at least be consistent
             * when the raw device list changes.
             */
            *pVID = (Uint16)rdi.hid.dwVendorId;
            *pPID = (Uint16)rdi.hid.dwProductId;
            *pVersion = (Uint16)rdi.hid.dwVersionNumber;
            if (s_arrXInputDevicePath[userid]) {
                SDL_free(s_arrXInputDevicePath[userid]);
            }
            s_arrXInputDevicePath[userid] = SDL_strdup(devName);
            break;
        }
    }
    SDL_free(devices);
#endif  /* ifndef __WINRT__ */
}
Beispiel #10
0
int
X11_InitKeyboard(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    int i = 0;
    int j = 0;
    int min_keycode, max_keycode;
    struct {
        SDL_Scancode scancode;
        KeySym keysym;
        int value;
    } fingerprint[] = {
        { SDL_SCANCODE_HOME, XK_Home, 0 },
        { SDL_SCANCODE_PAGEUP, XK_Prior, 0 },
        { SDL_SCANCODE_UP, XK_Up, 0 },
        { SDL_SCANCODE_LEFT, XK_Left, 0 },
        { SDL_SCANCODE_DELETE, XK_Delete, 0 },
        { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 },
    };
    int best_distance;
    int best_index;
    int distance;
    BOOL xkb_repeat = 0;
    
    X11_XAutoRepeatOn(data->display);

#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
    {
        int xkb_major = XkbMajorVersion;
        int xkb_minor = XkbMinorVersion;

        if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
            data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
        }

        /* This will remove KeyRelease events for held keys */
        X11_XkbSetDetectableAutoRepeat(data->display, True, &xkb_repeat);
    }
#endif
    
    /* Open a connection to the X input manager */
#ifdef X_HAVE_UTF8_STRING
    if (SDL_X11_HAVE_UTF8) {
        /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that 
           Compose keys will work correctly. */
        char *prev_locale = setlocale(LC_ALL, NULL);
        char *prev_xmods  = X11_XSetLocaleModifiers(NULL);
        const char *new_xmods = "";
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H)
        const char *env_xmods = SDL_getenv("XMODIFIERS");
#endif
        SDL_bool has_dbus_ime_support = SDL_FALSE;

        if (prev_locale) {
            prev_locale = SDL_strdup(prev_locale);
        }

        if (prev_xmods) {
            prev_xmods = SDL_strdup(prev_xmods);
        }

        /* IBus resends some key events that were filtered by XFilterEvents
           when it is used via XIM which causes issues. Prevent this by forcing
           @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via 
           the DBus implementation, which also has support for pre-editing. */
#ifdef HAVE_IBUS_IBUS_H
        if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) {
            has_dbus_ime_support = SDL_TRUE;
        }
#endif
#ifdef HAVE_FCITX_FRONTEND_H
        if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) {
            has_dbus_ime_support = SDL_TRUE;
        }
#endif
        if (has_dbus_ime_support || !xkb_repeat) {
            new_xmods = "@im=none";
        }

        setlocale(LC_ALL, "");
        X11_XSetLocaleModifiers(new_xmods);

        data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname);

        /* Reset the locale + X locale modifiers back to how they were,
           locale first because the X locale modifiers depend on it. */
        setlocale(LC_ALL, prev_locale);
        X11_XSetLocaleModifiers(prev_xmods);

        if (prev_locale) {
            SDL_free(prev_locale);
        }

        if (prev_xmods) {
            SDL_free(prev_xmods);
        }
    }
#endif
    /* Try to determine which scancodes are being used based on fingerprint */
    best_distance = SDL_arraysize(fingerprint) + 1;
    best_index = -1;
    X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode);
    for (i = 0; i < SDL_arraysize(fingerprint); ++i) {
        fingerprint[i].value =
            X11_XKeysymToKeycode(data->display, fingerprint[i].keysym) -
            min_keycode;
    }
    for (i = 0; i < SDL_arraysize(scancode_set); ++i) {
        /* Make sure the scancode set isn't too big */
        if ((max_keycode - min_keycode + 1) <= scancode_set[i].table_size) {
            continue;
        }
        distance = 0;
        for (j = 0; j < SDL_arraysize(fingerprint); ++j) {
            if (fingerprint[j].value < 0
                || fingerprint[j].value >= scancode_set[i].table_size) {
                distance += 1;
            } else if (scancode_set[i].table[fingerprint[j].value] != fingerprint[j].scancode) {
                distance += 1;
            }
        }
        if (distance < best_distance) {
            best_distance = distance;
            best_index = i;
        }
    }
    if (best_index >= 0 && best_distance <= 2) {
#ifdef DEBUG_KEYBOARD
        printf("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", best_index, min_keycode, max_keycode, scancode_set[best_index].table_size);
#endif
        SDL_memcpy(&data->key_layout[min_keycode], scancode_set[best_index].table,
                   sizeof(SDL_Scancode) * scancode_set[best_index].table_size);
    } else {
        SDL_Keycode keymap[SDL_NUM_SCANCODES];

        printf
            ("Keyboard layout unknown, please send the following to the SDL mailing list ([email protected]):\n");

        /* Determine key_layout - only works on US QWERTY layout */
        SDL_GetDefaultKeymap(keymap);
        for (i = min_keycode; i <= max_keycode; ++i) {
            KeySym sym;
            sym = X11_KeyCodeToSym(_this, (KeyCode) i, 0);
            if (sym != NoSymbol) {
                SDL_Scancode scancode;
                printf("code = %d, sym = 0x%X (%s) ", i - min_keycode,
                       (unsigned int) sym, X11_XKeysymToString(sym));
                scancode = X11_KeyCodeToSDLScancode(_this, i);
                data->key_layout[i] = scancode;
                if (scancode == SDL_SCANCODE_UNKNOWN) {
                    printf("scancode not found\n");
                } else {
                    printf("scancode = %d (%s)\n", scancode, SDL_GetScancodeName(scancode));
                }
            }
        }
    }

    X11_UpdateKeymap(_this);

    SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");

#ifdef SDL_USE_IME
    SDL_IME_Init();
#endif

    return 0;
}
Beispiel #11
0
static void CheckMounts(const char *mtab)
{
	FILE *mntfp;
	struct mntent *mntent;
	struct stat stbuf;

	mntfp = setmntent(mtab, "r");
	if ( mntfp != NULL ) {
		char *tmp;
		char *mnt_type;
		size_t mnt_type_len;
		char *mnt_dev;
		size_t mnt_dev_len;

		while ( (mntent=getmntent(mntfp)) != NULL ) {
			mnt_type_len = SDL_strlen(mntent->mnt_type) + 1;
			mnt_type = SDL_stack_alloc(char, mnt_type_len);
			if (mnt_type == NULL)
				continue;  /* maybe you'll get lucky next time. */

			mnt_dev_len = SDL_strlen(mntent->mnt_fsname) + 1;
			mnt_dev = SDL_stack_alloc(char, mnt_dev_len);
			if (mnt_dev == NULL) {
				SDL_stack_free(mnt_type);
				continue;
			}

			SDL_strlcpy(mnt_type, mntent->mnt_type, mnt_type_len);
			SDL_strlcpy(mnt_dev, mntent->mnt_fsname, mnt_dev_len);

			/* Handle "supermount" filesystem mounts */
			if ( SDL_strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) {
				tmp = SDL_strstr(mntent->mnt_opts, "fs=");
				if ( tmp ) {
					SDL_stack_free(mnt_type);
					mnt_type = SDL_strdup(tmp + SDL_strlen("fs="));
					if ( mnt_type ) {
						tmp = SDL_strchr(mnt_type, ',');
						if ( tmp ) {
							*tmp = '\0';
						}
					}
				}
				tmp = SDL_strstr(mntent->mnt_opts, "dev=");
				if ( tmp ) {
					SDL_stack_free(mnt_dev);
					mnt_dev = SDL_strdup(tmp + SDL_strlen("dev="));
					if ( mnt_dev ) {
						tmp = SDL_strchr(mnt_dev, ',');
						if ( tmp ) {
							*tmp = '\0';
						}
					}
				}
			}
			if ( SDL_strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) {
#ifdef DEBUG_CDROM
  fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n",
	mtab, mnt_dev, mntent->mnt_dir, mnt_type);
#endif
				if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) {
					AddDrive(mnt_dev, &stbuf);
				}
			}
			SDL_stack_free(mnt_dev);
			SDL_stack_free(mnt_type);
		}
		endmntent(mntfp);
	}
Beispiel #12
0
/*
 * Add or update an entry into the Mappings Database
 */
int
SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw)
{
    const char *platform = SDL_GetPlatform();
    int controllers = 0;
    char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
    size_t db_size, platform_len;

    if (rw == NULL) {
        return SDL_SetError("Invalid RWops");
    }
    db_size = (size_t)SDL_RWsize(rw);

    buf = (char *)SDL_malloc(db_size + 1);
    if (buf == NULL) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        return SDL_SetError("Could allocate space to not read DB into memory");
    }

    if (SDL_RWread(rw, buf, db_size, 1) != 1) {
        if (freerw) {
            SDL_RWclose(rw);
        }
        SDL_free(buf);
        return SDL_SetError("Could not read DB");
    }

    if (freerw) {
        SDL_RWclose(rw);
    }

    buf[db_size] = '\0';
    line = buf;

    while (line < buf + db_size) {
        line_end = SDL_strchr(line, '\n');
        if (line_end != NULL) {
            *line_end = '\0';
        } else {
            line_end = buf + db_size;
        }

        /* Extract and verify the platform */
        tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
        if (tmp != NULL) {
            tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
            comma = SDL_strchr(tmp, ',');
            if (comma != NULL) {
                platform_len = comma - tmp + 1;
                if (platform_len + 1 < SDL_arraysize(line_platform)) {
                    SDL_strlcpy(line_platform, tmp, platform_len);
                    if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
                        SDL_GameControllerAddMapping(line) > 0) {
                        controllers++;
                    }
                }
            }
        }

        line = line_end + 1;
    }

    SDL_free(buf);
    return controllers;
}
Beispiel #13
0
static SDL_bool
SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
{
    static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
    static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };

    static const GUID *s_XInputProductGUID[] = {
        &IID_ValveStreamingGamepad,
        &IID_X360WiredGamepad,         /* Microsoft's wired X360 controller for Windows. */
        &IID_X360WirelessGamepad,      /* Microsoft's wireless X360 controller for Windows. */
        &IID_XOneWiredGamepad,         /* Microsoft's wired Xbox One controller for Windows. */
        &IID_XOneWirelessGamepad,      /* Microsoft's wireless Xbox One controller for Windows. */
        &IID_XOneNewWirelessGamepad,   /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */
        &IID_XOneSWirelessGamepad,     /* Microsoft's wireless Xbox One S controller for Windows. */
        &IID_XOneSBluetoothGamepad,    /* Microsoft's Bluetooth Xbox One S controller for Windows. */
        &IID_XOneEliteWirelessGamepad  /* Microsoft's wireless Xbox One Elite controller for Windows. */
    };

    size_t iDevice;
    UINT i;

    if (!SDL_XINPUT_Enabled()) {
        return SDL_FALSE;
    }

    /* Check for well known XInput device GUIDs */
    /* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
    for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
        if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
            return SDL_TRUE;
        }
    }

    /* Go through RAWINPUT (WinXP and later) to find HID devices. */
    /* Cache this if we end up using it. */
    if (SDL_RawDevList == NULL) {
        if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
            return SDL_FALSE;  /* oh well. */
        }

        SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
        if (SDL_RawDevList == NULL) {
            SDL_OutOfMemory();
            return SDL_FALSE;
        }

        if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) {
            SDL_free(SDL_RawDevList);
            SDL_RawDevList = NULL;
            return SDL_FALSE;  /* oh well. */
        }
    }

    for (i = 0; i < SDL_RawDevListCount; i++) {
        RID_DEVICE_INFO rdi;
        char devName[128];
        UINT rdiSize = sizeof(rdi);
        UINT nameSize = SDL_arraysize(devName);

        rdi.cbSize = sizeof(rdi);
        if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
            (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
            (SDL_strstr(devName, "IG_") != NULL)) {
            return SDL_TRUE;
        }
    }

    return SDL_FALSE;
}
Beispiel #14
0
static SDL_bool JS_ConfigJoystick(SDL_Joystick *joystick, int fd)
{
	SDL_bool handled;
	unsigned char n;
	int tmp_naxes, tmp_nhats, tmp_nballs;
	const char *name;
	char *env, env_name[128];
	int i;

	handled = SDL_FALSE;

	/* Default joystick device settings */
	if ( ioctl(fd, JSIOCGAXES, &n) < 0 ) {
		joystick->naxes = 2;
	} else {
		joystick->naxes = n;
	}
	if ( ioctl(fd, JSIOCGBUTTONS, &n) < 0 ) {
		joystick->nbuttons = 2;
	} else {
		joystick->nbuttons = n;
	}

	name = SDL_SYS_JoystickName(joystick->index);

	/* Generic analog joystick support */
	if ( SDL_strstr(name, "Analog") == name && SDL_strstr(name, "-hat") ) {
		if ( SDL_sscanf(name,"Analog %d-axis %*d-button %d-hat",
			&tmp_naxes, &tmp_nhats) == 2 ) {

			joystick->naxes = tmp_naxes;
			joystick->nhats = tmp_nhats;

			handled = SDL_TRUE;
		}
	}

	/* Special joystick support */
	for ( i=0; i < SDL_arraysize(special_joysticks); ++i ) {
		if ( SDL_strcmp(name, special_joysticks[i].name) == 0 ) {

			joystick->naxes = special_joysticks[i].naxes;
			joystick->nhats = special_joysticks[i].nhats;
			joystick->nballs = special_joysticks[i].nballs;

			handled = SDL_TRUE;
			break;
		}
	}

	/* User environment joystick support */
	if ( (env = SDL_getenv("SDL_LINUX_JOYSTICK")) ) {
		*env_name = '\0';
		if ( *env == '\'' && SDL_sscanf(env, "'%[^']s'", env_name) == 1 )
			env += SDL_strlen(env_name)+2;
		else if ( SDL_sscanf(env, "%s", env_name) == 1 )
			env += SDL_strlen(env_name);

		if ( SDL_strcmp(name, env_name) == 0 ) {

			if ( SDL_sscanf(env, "%d %d %d", &tmp_naxes, &tmp_nhats,
				&tmp_nballs) == 3 ) {

				joystick->naxes = tmp_naxes;
				joystick->nhats = tmp_nhats;
				joystick->nballs = tmp_nballs;

				handled = SDL_TRUE;
			}
		}
	}

	/* Remap hats and balls */
	if (handled) {
		if ( joystick->nhats > 0 ) {
			if ( allocate_hatdata(joystick) < 0 ) {
				joystick->nhats = 0;
			}
		}
		if ( joystick->nballs > 0 ) {
			if ( allocate_balldata(joystick) < 0 ) {
				joystick->nballs = 0;
			}
		}
	}

	return(handled);
}
int WIN_GL_SetupWindow(_THIS)
{
	int retval;
#if SDL_VIDEO_OPENGL
	int i;
	int iAttribs[64];
	int *iAttr;
	int *iAccelAttr = NULL;
	float fAttribs[1] = { 0 };
	const GLubyte *(WINAPI *glGetStringFunc)(GLenum);
	const char *wglext;

	/* load the gl driver from a default path */
	if ( ! this->gl_config.driver_loaded ) {
		/* no driver has been loaded, use default (ourselves) */
		if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) {
			return(-1);
		}
	}

	/* Set up the pixel format descriptor with our needed format */
	SDL_memset(&GL_pfd, 0, sizeof(GL_pfd));
	GL_pfd.nSize = sizeof(GL_pfd);
	GL_pfd.nVersion = 1;
	GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
	if ( this->gl_config.double_buffer ) {
		GL_pfd.dwFlags |= PFD_DOUBLEBUFFER;
	}
	if ( this->gl_config.stereo ) {
		GL_pfd.dwFlags |= PFD_STEREO;
	}
	GL_pfd.iPixelType = PFD_TYPE_RGBA;
	GL_pfd.cColorBits = this->gl_config.buffer_size;
	GL_pfd.cRedBits = this->gl_config.red_size;
	GL_pfd.cGreenBits = this->gl_config.green_size;
	GL_pfd.cBlueBits = this->gl_config.blue_size;
	GL_pfd.cAlphaBits = this->gl_config.alpha_size;
	GL_pfd.cAccumRedBits = this->gl_config.accum_red_size;
	GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size;
	GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size;
	GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size;
	GL_pfd.cAccumBits =
		(GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits +
		 GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits);
	GL_pfd.cDepthBits = this->gl_config.depth_size;
	GL_pfd.cStencilBits = this->gl_config.stencil_size;

	/* setup WGL_ARB_pixel_format attribs */
	iAttr = &iAttribs[0];

	*iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
	*iAttr++ = GL_TRUE;
	*iAttr++ = WGL_RED_BITS_ARB;
	*iAttr++ = this->gl_config.red_size;
	*iAttr++ = WGL_GREEN_BITS_ARB;
	*iAttr++ = this->gl_config.green_size;
	*iAttr++ = WGL_BLUE_BITS_ARB;
	*iAttr++ = this->gl_config.blue_size;

	/* We always choose either FULL or NO accel on Windows, because of flaky
	   drivers. If the app didn't specify, we use FULL, because that's
	   probably what they wanted (and if you didn't care and got FULL, that's
	   a perfectly valid result in any case. */
	*iAttr++ = WGL_ACCELERATION_ARB;
	iAccelAttr = iAttr;
	if (this->gl_config.accelerated) {
		*iAttr++ = WGL_FULL_ACCELERATION_ARB;
	} else {
		*iAttr++ = WGL_NO_ACCELERATION_ARB;
	}

	if ( this->gl_config.alpha_size ) {
		*iAttr++ = WGL_ALPHA_BITS_ARB;
		*iAttr++ = this->gl_config.alpha_size;
	}

	*iAttr++ = WGL_DOUBLE_BUFFER_ARB;
	*iAttr++ = this->gl_config.double_buffer;

	*iAttr++ = WGL_DEPTH_BITS_ARB;
	*iAttr++ = this->gl_config.depth_size;

	if ( this->gl_config.stencil_size ) {
		*iAttr++ = WGL_STENCIL_BITS_ARB;
		*iAttr++ = this->gl_config.stencil_size;
	}

	if ( this->gl_config.accum_red_size ) {
		*iAttr++ = WGL_ACCUM_RED_BITS_ARB;
		*iAttr++ = this->gl_config.accum_red_size;
	}

	if ( this->gl_config.accum_green_size ) {
		*iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
		*iAttr++ = this->gl_config.accum_green_size;
	}

	if ( this->gl_config.accum_blue_size ) {
		*iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
		*iAttr++ = this->gl_config.accum_blue_size;
	}

	if ( this->gl_config.accum_alpha_size ) {
		*iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
		*iAttr++ = this->gl_config.accum_alpha_size;
	}

	if ( this->gl_config.stereo ) {
		*iAttr++ = WGL_STEREO_ARB;
		*iAttr++ = GL_TRUE;
	}

	if ( this->gl_config.multisamplebuffers ) {
		*iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
		*iAttr++ = this->gl_config.multisamplebuffers;
	}

	if ( this->gl_config.multisamplesamples ) {
		*iAttr++ = WGL_SAMPLES_ARB;
		*iAttr++ = this->gl_config.multisamplesamples;
	}

	*iAttr = 0;

	for ( i=0; ; ++i ) {
		/* Get the window device context for our OpenGL drawing */
		GL_hdc = GetDC(SDL_Window);
		if ( GL_hdc == NULL ) {
			SDL_SetError("Unable to get DC for SDL_Window");
			return(-1);
		}

		/* Choose and set the closest available pixel format */
		pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
		/* App said "don't care about accel" and FULL accel failed. Try NO. */
		if ( ( !pixel_format ) && ( this->gl_config.accelerated < 0 ) ) {
			*iAccelAttr = WGL_NO_ACCELERATION_ARB;
			pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs);
			*iAccelAttr = WGL_FULL_ACCELERATION_ARB;  /* if we try again. */
		}
		if ( !pixel_format ) {
			pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd);
		}
		if ( !pixel_format ) {
			SDL_SetError("No matching GL pixel format available");
			return(-1);
		}
		if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) {
			if ( i == 0 ) {
				/* First time through, try resetting the window */
				if ( WIN_GL_ResetWindow(this) < 0 ) {
					return(-1);
				}
				continue;
			}
			SDL_SetError("Unable to set HDC pixel format");
			return(-1);
		}
		/* We either succeeded or failed by this point */
		break;
	}
	DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd);

	GL_hrc = this->gl_data->wglCreateContext(GL_hdc);
	if ( GL_hrc == NULL ) {
		SDL_SetError("Unable to create GL context");
		return(-1);
	}
	if ( WIN_GL_MakeCurrent(this) < 0 ) {
		return(-1);
	}
	gl_active = 1;

	/* Get the wglGetPixelFormatAttribivARB pointer for the context */
	if ( this->gl_data->WGL_ARB_pixel_format ) {
		this->gl_data->wglGetPixelFormatAttribivARB =
			(BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *))
			this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB");
	} else {
		this->gl_data->wglGetPixelFormatAttribivARB = NULL;
	}

	/* Vsync control under Windows.  Checking glGetString here is
	 * somewhat a documented and reliable hack - it was originally
	 * as a feature added by mistake, but since so many people rely
	 * on it, it will not be removed.  strstr should be safe here.*/
	glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString");
	if ( glGetStringFunc ) {
		wglext = (const char *)glGetStringFunc(GL_EXTENSIONS);
	} else {
		/* Uh oh, something is seriously wrong here... */
		wglext = NULL;
	}
	if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) {
		this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT");
		this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT");
	} else {
		this->gl_data->wglSwapIntervalEXT = NULL;
		this->gl_data->wglGetSwapIntervalEXT = NULL;
	}
	if ( this->gl_config.swap_control >= 0 ) {
		if ( this->gl_data->wglSwapIntervalEXT ) {
			this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
		}
	}
#else
	SDL_SetError("WIN driver not configured with OpenGL");
#endif
	if ( gl_active ) {
		retval = 0;
	} else {
		retval = -1;
	}
	return(retval);
}
Beispiel #16
0
static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext)
{
    size_t ext_len;
    const char *ext_override;
    const char *egl_extstr;
    const char *ext_start;

    /* Invalid extensions can be rejected early */
    if (ext == NULL || *ext == 0 || SDL_strchr(ext, ' ') != NULL) {
        /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid EGL extension"); */
        return SDL_FALSE;
    }

    /* Extensions can be masked with an environment variable.
     * Unlike the OpenGL override, this will use the set bits of an integer
     * to disable the extension.
     *  Bit   Action
     *  0     If set, the display extension is masked and not present to SDL.
     *  1     If set, the client extension is masked and not present to SDL.
     */
    ext_override = SDL_getenv(ext);
    if (ext_override != NULL) {
        int disable_ext = SDL_atoi(ext_override);
        if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) {
            return SDL_FALSE;
        } else if (disable_ext & 0x02 && type == SDL_EGL_CLIENT_EXTENSION) {
            return SDL_FALSE;
        }
    }

    ext_len = SDL_strlen(ext);
    switch (type) {
    case SDL_EGL_DISPLAY_EXTENSION:
        egl_extstr = _this->egl_data->eglQueryString(_this->egl_data->egl_display, EGL_EXTENSIONS);
        break;
    case SDL_EGL_CLIENT_EXTENSION:
        /* EGL_EXT_client_extensions modifies eglQueryString to return client extensions
         * if EGL_NO_DISPLAY is passed. Implementations without it are required to return NULL.
         * This behavior is included in EGL 1.5.
         */
        egl_extstr = _this->egl_data->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
        break;
    default:
        /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid extension type"); */
        return SDL_FALSE;
    }

    if (egl_extstr != NULL) {
        ext_start = egl_extstr;

        while (*ext_start) {
            ext_start = SDL_strstr(ext_start, ext);
            if (ext_start == NULL) {
                return SDL_FALSE;
            }
            /* Check if the match is not just a substring of one of the extensions */
            if (ext_start == egl_extstr || *(ext_start - 1) == ' ') {
                if (ext_start[ext_len] == ' ' || ext_start[ext_len] == 0) {
                    return SDL_TRUE;
                }
            }
            /* If the search stopped in the middle of an extension, skip to the end of it */
            ext_start += ext_len;
            while (*ext_start != ' ' && *ext_start != 0) {
                ext_start++;
            }
        }
    }

    return SDL_FALSE;
}