Example #1
0
static bool linuxraw_joypad_init(void *data)
{
   unsigned i;
   settings_t *settings = config_get_ptr();

   g_epoll              = epoll_create(MAX_USERS + 1);
   if (g_epoll < 0)
      return false;

   (void)data;

   for (i = 0; i < MAX_USERS; i++)
   {
      char path[PATH_MAX_LENGTH]  = {0};
      autoconfig_params_t params  = {{0}};
      struct linuxraw_joypad *pad = (struct linuxraw_joypad*)&linuxraw_pads[i];

      if (!pad)
         continue;

      params.idx = i;

      pad->fd    = -1;
      pad->ident = settings->input.device_names[i];
      
      snprintf(path, sizeof(path), "/dev/input/js%u", i);

      if (linuxraw_joypad_init_pad(path, pad))
      {
         strlcpy(params.name,   pad->ident, sizeof(params.name)); 
         strlcpy(params.driver, "linuxraw", sizeof(params.driver));

         /* TODO - implement VID/PID? */
         input_config_autoconfigure_joypad(&params);
         linuxraw_poll_pad(pad);
      }
      else
         input_config_autoconfigure_joypad(&params);
   }

   g_notify = inotify_init();
   if (g_notify >= 0)
   {
      struct epoll_event event;

      linuxraw_joypad_setup_notify();

      event.events = EPOLLIN;
      event.data.ptr = NULL;
      epoll_ctl(g_epoll, EPOLL_CTL_ADD, g_notify, &event);
   }

   g_hotplug = true;

   return true;
}
Example #2
0
static bool linuxraw_joypad_init(void *data)
{
   unsigned i;
   settings_t *settings = config_get_ptr();

   if (!epoll_new(true))
      return false;

   (void)data;

   for (i = 0; i < MAX_USERS; i++)
   {
      char path[PATH_MAX_LENGTH]  = {0};
      autoconfig_params_t params  = {{0}};
      struct linuxraw_joypad *pad = (struct linuxraw_joypad*)&linuxraw_pads[i];

      if (!pad)
         continue;

      params.idx = i;

      pad->fd    = -1;
      pad->ident = settings->input.device_names[i];
      
      snprintf(path, sizeof(path), "/dev/input/js%u", i);

      if (linuxraw_joypad_init_pad(path, pad))
      {
         strlcpy(params.name,   pad->ident, sizeof(params.name)); 
         strlcpy(params.driver, "linuxraw", sizeof(params.driver));

         /* TODO - implement VID/PID? */
         input_config_autoconfigure_joypad(&params);
         linuxraw_poll_pad(pad);
      }
      else
         input_config_autoconfigure_joypad(&params);
   }

   g_inotify = inotify_init();

   if (g_inotify >= 0)
   {
      fcntl(g_inotify, F_SETFL, fcntl(g_inotify, F_GETFL) | O_NONBLOCK);
      inotify_add_watch(g_inotify, "/dev/input", IN_DELETE | IN_CREATE | IN_ATTRIB);
      epoll_add(g_inotify, NULL);
   }

   g_hotplug = true;

   return true;
}
Example #3
0
static void hid_manager_device_attached(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
{
    char device_name[1024];
    CFStringRef device_name_ref;
    struct apple_pad_connection* connection = (struct apple_pad_connection*)calloc(1, sizeof(*connection));
    
    connection->device = device;
    connection->slot = MAX_PLAYERS;
    
    IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
    IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
    IOHIDDeviceRegisterRemovalCallback(device, hid_device_removed, connection);
    
    device_name_ref = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
    CFStringGetCString(device_name_ref, device_name, sizeof(device_name), kCFStringEncodingUTF8);
    
    connection->slot = apple_joypad_connect(device_name, connection);
    
    if (apple_joypad_has_interface(connection->slot))
        IOHIDDeviceRegisterInputReportCallback(device, connection->data + 1, sizeof(connection->data) - 1, hid_device_report, connection);
    else
        IOHIDDeviceRegisterInputValueCallback(device, hid_device_input_callback, connection);

    if (device_name[0] != '\0')
    {
       strlcpy(g_settings.input.device_names[connection->slot], device_name, sizeof(g_settings.input.device_names));
       input_config_autoconfigure_joypad(connection->slot, device_name, apple_joypad.ident);
       RARCH_LOG("Port %d: %s.\n", connection->slot, device_name);
    }
}
Example #4
0
static bool psp_joypad_init(void)
{
   unsigned autoconf_pad;

   for (autoconf_pad = 0; autoconf_pad < MAX_PADS; autoconf_pad++)
   {
      strlcpy(g_settings.input.device_names[autoconf_pad], psp_joypad_name(autoconf_pad), sizeof(g_settings.input.device_names[autoconf_pad]));
      input_config_autoconfigure_joypad(autoconf_pad, psp_joypad_name(autoconf_pad), psp_joypad.ident);
   }

   return true;
}
Example #5
0
static void add_device(void* context, IOReturn result,
      void* sender, IOHIDDeviceRef device)
{
   char device_name[PATH_MAX_LENGTH];
   CFStringRef device_name_ref;
   CFNumberRef vendorID, productID;
   struct pad_connection* connection = (struct pad_connection*)
      calloc(1, sizeof(*connection));

   connection->device_handle = device;
   connection->slot          = MAX_USERS;

   IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);

   /* Move the device's run loop to this thread. */
   IOHIDDeviceScheduleWithRunLoop(device, CFRunLoopGetCurrent(),
         kCFRunLoopCommonModes);
   IOHIDDeviceRegisterRemovalCallback(device, remove_device, connection);

#ifndef IOS
   device_name_ref = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
   CFStringGetCString(device_name_ref, device_name,
         sizeof(device_name), kCFStringEncodingUTF8);
#endif

   vendorID = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
   CFNumberGetValue(vendorID, kCFNumberIntType, &connection->v_id);

   productID = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
   CFNumberGetValue(productID, kCFNumberIntType, &connection->p_id);

   connection->slot = pad_connection_pad_init(slots, device_name,
         connection, &hid_pad_connection_send_control);

   if (pad_connection_has_interface(slots, connection->slot))
      IOHIDDeviceRegisterInputReportCallback(device,
            connection->data + 1, sizeof(connection->data) - 1,
            hid_device_report, connection);
   else
      IOHIDDeviceRegisterInputValueCallback(device,
            hid_device_input_callback, connection);

   if (device_name[0] == '\0')
      return;

   strlcpy(g_settings.input.device_names[connection->slot],
         device_name, sizeof(g_settings.input.device_names));

   input_config_autoconfigure_joypad(connection->slot,
         device_name, connection->v_id, connection->p_id, apple_hid_joypad.ident);
   RARCH_LOG("Port %d: %s.\n", connection->slot, device_name);
}
Example #6
0
static void qnx_input_autodetect_gamepad(qnx_input_t *qnx,
      qnx_input_device_t* controller, int port)
{
   char name_buf[256]   = {0};
   settings_t *settings = config_get_ptr();

   if (!qnx)
      return;

   name_buf[0] = '\0';

   /* ID: A-BBBB-CCCC-D.D
    * A is the device's index in the array 
    * returned by screen_get_context_property_pv()
    * BBBB is the device's Vendor ID (in hexadecimal)
    * CCCC is the device's Product ID (also in hexadecimal)
    * D.D is the device's version number
    */
   if (controller)
   {
#ifdef HAVE_BB10
      if (strstr(controller->id, "057E-0306"))
         strlcpy(name_buf, "Wiimote", sizeof(name_buf));
      else
#endif
         if (strstr(controller->id, "0A5C-8502"))
            strlcpy(name_buf, "BlackBerry BT Keyboard", sizeof(name_buf));
#ifdef HAVE_BB10
         else if (strstr(controller->id, "qwerty:bb35"))
            strlcpy(name_buf, "BlackBerry Q10 Keypad", sizeof(name_buf));
#endif
   }

   if (!string_is_empty(name_buf))
   {
      autoconfig_params_t params = {{0}};

      strlcpy(settings->input.device_names[port],
            name_buf, sizeof(settings->input.device_names[port]));

      params.idx = port;
      strlcpy(params.name, name_buf, sizeof(params.name));
      params.vid = *controller->vid;
      params.pid = *controller->pid;
      strlcpy(params.driver, qnx->joypad->ident, sizeof(params.driver));
      input_config_autoconfigure_joypad(&params);

      controller->port = port;
      qnx->port_device[port] = controller;
      qnx->pads_connected++;
   }
}
Example #7
0
static bool linuxraw_joypad_init(void)
{
   g_epoll = epoll_create(MAX_PLAYERS + 1);
   if (g_epoll < 0)
      return false;

   for (unsigned i = 0; i < MAX_PLAYERS; i++)
   {
      struct linuxraw_joypad *pad = &g_pads[i];
      pad->fd = -1;
      pad->ident = g_settings.input.device_names[i];
      
      char path[PATH_MAX];
      snprintf(path, sizeof(path), "/dev/input/js%u", i);

      if (linuxraw_joypad_init_pad(path, pad))
      {
         input_config_autoconfigure_joypad(i, pad->ident, "linuxraw");
         poll_pad(pad);
      }
      else
         input_config_autoconfigure_joypad(i, NULL, NULL);
   }

   g_notify = inotify_init();
   if (g_notify >= 0)
   {
      linuxraw_joypad_setup_notify();

      struct epoll_event event;
      event.events = EPOLLIN;
      event.data.ptr = NULL;
      epoll_ctl(g_epoll, EPOLL_CTL_ADD, g_notify, &event);
   }

   g_hotplug = true;

   return true;
}
Example #8
0
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
{
   (void)p;
   if (g_joypad_cnt == MAX_PLAYERS)
      return DIENUM_STOP;

   LPDIRECTINPUTDEVICE8 *pad = &g_pads[g_joypad_cnt].joypad;

#ifdef __cplusplus
   if (FAILED(IDirectInput8_CreateDevice(g_ctx, inst->guidInstance, pad, NULL)))
#else
   if (FAILED(IDirectInput8_CreateDevice(g_ctx, &inst->guidInstance, pad, NULL)))
#endif
   return DIENUM_CONTINUE;
   
   g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
   
#ifdef HAVE_WINXINPUT
   int last_xbox_pad_index = 0;
   bool is_360_pad = name_is_360_pad(inst->tszProductName);
   
   if (is_360_pad)
   {
      if (last_xbox_pad_index < 4)
         g_xbox_pad_indexes[g_joypad_cnt] = last_xbox_pad_index;
      ++last_xbox_pad_index;
      
      goto enum_iteration_done;
   }
#endif

   IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
   IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver.video_window,
         DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

   IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb, 
         *pad, DIDFT_ABSAXIS);
         
#ifdef HAVE_WINXINPUT
   if (!is_360_pad)
#endif
   {
      strlcpy(g_settings.input.device_names[g_joypad_cnt], dinput_joypad_name(g_joypad_cnt), sizeof(g_settings.input.device_names[g_joypad_cnt]));
      input_config_autoconfigure_joypad(g_joypad_cnt, dinput_joypad_name(g_joypad_cnt), dinput_joypad.ident);
   }

enum_iteration_done:
   g_joypad_cnt++;
   return DIENUM_CONTINUE; 
}
Example #9
0
static void ps3_joypad_autodetect_add(unsigned autoconf_pad)
{
   settings_t *settings = config_get_ptr();
   autoconfig_params_t params = {{0}};
   strlcpy(settings->input.device_names[autoconf_pad],
         "SixAxis Controller",
         sizeof(settings->input.device_names[autoconf_pad]));

   /* TODO - implement VID/PID? */
   params.idx = autoconf_pad;
   strlcpy(params.name, ps3_joypad_name(autoconf_pad), sizeof(params.name));
   strlcpy(params.driver, ps3_joypad.ident, sizeof(params.driver));
   input_config_autoconfigure_joypad(&params);
}
Example #10
0
static void libusb_hid_device_add_autodetect(unsigned idx,
      const char *device_name, const char *driver_name,
      uint16_t dev_vid, uint16_t dev_pid)
{
   autoconfig_params_t params = {{0}};

   params.idx = idx;
   params.vid = dev_vid;
   params.pid = dev_pid;

   strlcpy(params.name, device_name, sizeof(params.name));
   strlcpy(params.driver, driver_name, sizeof(params.driver));

   input_config_autoconfigure_joypad(&params);
}
Example #11
0
static void iohidmanager_hid_device_add_autodetect(unsigned idx,
      const char *device_name, const char *driver_name,
      uint16_t dev_vid, uint16_t dev_pid)
{
   autoconfig_params_t params = {{0}};

   params.idx = idx;
   params.vid = dev_vid;
   params.pid = dev_pid;

   strlcpy(params.name, device_name, sizeof(params.name));
   strlcpy(params.driver, driver_name, sizeof(params.driver));

   input_config_autoconfigure_joypad(&params);
   RARCH_LOG("Port %d: %s.\n", idx, device_name);
}
Example #12
0
static void qnx_input_autodetect_gamepad(void *data,
      input_device_t* controller, int port)
{
   char name_buf[256];
   qnx_input_t *qnx = (qnx_input_t*)data;

   if (!qnx)
      return;

   name_buf[0] = '\0';

   /* ID: A-BBBB-CCCC-D.D
    * A is the device's index in the array 
    * returned by screen_get_context_property_pv()
    * BBBB is the device's Vendor ID (in hexadecimal)
    * CCCC is the device's Product ID (also in hexadecimal)
    * D.D is the device's version number
    */
   if (controller)
   {
#ifdef HAVE_BB10
      if (strstr(controller->id, "057E-0306"))
         strlcpy(name_buf, "Wiimote", sizeof(name_buf));
      else
#endif
         if (strstr(controller->id, "0A5C-8502"))
            strlcpy(name_buf, "BlackBerry BT Keyboard", sizeof(name_buf));
#ifdef HAVE_BB10
         else if (strstr(controller->id, "qwerty:bb35"))
            strlcpy(name_buf, "BlackBerry Q10 Keypad", sizeof(name_buf));
#endif
   }

   if (name_buf[0] != '\0')
   {
      strlcpy(g_settings.input.device_names[port],
            name_buf, sizeof(g_settings.input.device_names[port]));

      input_config_autoconfigure_joypad(port, name_buf,
            controller->vid, controller->vid,
            qnx->joypad);

      controller->port = port;
      qnx->port_device[port] = controller;
      qnx->pads_connected++;
   }
}
Example #13
0
static void wiiu_joypad_autodetect_add(unsigned autoconf_pad)
{
   settings_t *settings = config_get_ptr();
   autoconfig_params_t params = {{0}};

   if (!settings->input.autodetect_enable)
      return;

   strlcpy(settings->input.device_names[autoconf_pad],
         wiiu_joypad_name(autoconf_pad),
         sizeof(settings->input.device_names[autoconf_pad]));

   /* TODO - implement VID/PID? */
   params.idx = autoconf_pad;
   strlcpy(params.name, wiiu_joypad_name(autoconf_pad), sizeof(params.name));
   strlcpy(params.driver, wiiu_joypad.ident, sizeof(params.driver));
   input_config_autoconfigure_joypad(&params);
}
Example #14
0
static bool ps3_joypad_init(void)
{
   unsigned autoconf_pad;

   cellPadInit(MAX_PADS);

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      strlcpy(g_settings.input.device_names[autoconf_pad],
            "SixAxis Controller",
            sizeof(g_settings.input.device_names[autoconf_pad]));
      /* TODO - implement VID/PID? */
      input_config_autoconfigure_joypad(autoconf_pad,
            ps3_joypad_name(autoconf_pad),
            0, 0,
            ps3_joypad.ident);
   }

   return true;
}
Example #15
0
static bool android_joypad_init(void *data)
{
   unsigned autoconf_pad;
   settings_t *settings       = config_get_ptr();
   autoconfig_params_t params = {{0}};

   (void)data;

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      strlcpy(settings->input.device_names[autoconf_pad],
            android_joypad_name(autoconf_pad),
            sizeof(settings->input.device_names[autoconf_pad]));

      /* TODO - implement VID/PID? */
      params.idx = autoconf_pad;
      strlcpy(params.name, android_joypad_name(autoconf_pad), sizeof(params.name));
      strlcpy(params.driver, android_joypad.ident, sizeof(params.driver));

      if (!input_config_autoconfigure_joypad(&params))
      {
         settings->input.binds[autoconf_pad][RARCH_MENU_TOGGLE].joykey = AKEYCODE_BACK;
      }
   }

   engine_handle_dpad = engine_handle_dpad_default;
   if ((dlopen("/system/lib/libandroid.so", RTLD_LOCAL | RTLD_LAZY)) == 0)
   {
      RARCH_WARN("Unable to open libandroid.so\n");
      return true;
   }

   if ((p_AMotionEvent_getAxisValue = dlsym(RTLD_DEFAULT,
               "AMotionEvent_getAxisValue")))
   {
      RARCH_LOG("Set engine_handle_dpad to 'Get Axis Value' (for reading extra analog sticks)");
      engine_handle_dpad = engine_handle_dpad_getaxisvalue;
   }

   return true;
}
static bool xdk_joypad_init(void)
{
   unsigned autoconf_pad;

#ifdef _XBOX1
   XInitDevices(0, NULL);

   dwDeviceMask = XGetDevices(XDEVICE_TYPE_GAMEPAD);

   /* Check the device status. */
   switch(XGetDeviceEnumerationStatus())
   {
      case XDEVICE_ENUMERATION_IDLE:
         RARCH_LOG("Input state status: XDEVICE_ENUMERATION_IDLE\n");
         break;
      case XDEVICE_ENUMERATION_BUSY:
         RARCH_LOG("Input state status: XDEVICE_ENUMERATION_BUSY\n");
         break;
   }

   while(XGetDeviceEnumerationStatus() == XDEVICE_ENUMERATION_BUSY) {}
#endif

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      strlcpy(g_settings.input.device_names[autoconf_pad],
            "XInput Controller",
            sizeof(g_settings.input.device_names[autoconf_pad]));
      
      /* TODO - implement VID/PID? */
      input_config_autoconfigure_joypad(autoconf_pad,
            xdk_joypad_name(autoconf_pad), 
            0, 0,
            xdk_joypad.ident);
   }

   return true;
}
Example #17
0
static bool qnx_joypad_init(void *data)
{
   unsigned autoconf_pad;
   settings_t *settings = config_get_ptr();

   (void)data;

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      autoconfig_params_t params = {{0}};

      strlcpy(settings->input.device_names[autoconf_pad], "None",
            sizeof(settings->input.device_names[autoconf_pad]));

      /* TODO - implement VID/PID? */
      params.idx = autoconf_pad;
      strlcpy(params.name, qnx_joypad_name(autoconf_pad), sizeof(params.name));
      strlcpy(params.driver, qnx_joypad.ident, sizeof(params.driver));
      input_config_autoconfigure_joypad(&params);
   }

   return true;
}
Example #18
0
static void handle_hotplug(unsigned port, uint32_t ptype)
{
   pad_type[port] = ptype;

   if (ptype != WPAD_EXP_NOCONTROLLER)
   {
      autoconfig_params_t params = {{0}};
      settings_t *settings       = config_get_ptr();

      if (!settings->input.autodetect_enable)
         return;

      strlcpy(settings->input.device_names[port],
            gx_joypad_name(port),
            sizeof(settings->input.device_names[port]));

      /* TODO - implement VID/PID? */
      params.idx = port;
      strlcpy(params.name, gx_joypad_name(port), sizeof(params.name));
      strlcpy(params.driver, gx_joypad.ident, sizeof(params.driver));
      input_config_autoconfigure_joypad(&params);
   }
}
Example #19
0
static void handle_plugged_pad(void)
{
   size_t event_size = sizeof(struct inotify_event) + NAME_MAX + 1;
   uint8_t *event_buf = (uint8_t*)calloc(1, event_size);
   if (!event_buf)
      return;

   int rc;
   while ((rc = read(g_notify, event_buf, event_size)) >= 0)
   {
      struct inotify_event *event = NULL;
      // Can read multiple events in one read() call.
      for (int i = 0; i < rc; i += event->len + sizeof(struct inotify_event))
      {
         event = (struct inotify_event*)&event_buf[i];

         if (strstr(event->name, "js") != event->name)
            continue;

         unsigned index = strtoul(event->name + 2, NULL, 0);
         if (index >= MAX_PLAYERS)
            continue;

         if (event->mask & IN_DELETE)
         {
            if (g_pads[index].fd >= 0)
            {
               if (g_hotplug)
               {
                  char msg[512];
                  snprintf(msg, sizeof(msg), "Joypad #%u (%s) disconnected.", index, g_pads[index].ident);
#ifndef IS_JOYCONFIG
                  msg_queue_push(g_extern.msg_queue, msg, 0, 60);
#endif
               }

               RARCH_LOG("[Joypad]: Joypad %s disconnected.\n", g_pads[index].ident);
               close(g_pads[index].fd);
               memset(g_pads[index].buttons, 0, sizeof(g_pads[index].buttons));
               memset(g_pads[index].axes, 0, sizeof(g_pads[index].axes));
               g_pads[index].fd = -1;
               *g_pads[index].ident = '\0';

               input_config_autoconfigure_joypad(index, NULL, NULL);
            }
         }
         // Sometimes, device will be created before acess to it is established.
         else if (event->mask & (IN_CREATE | IN_ATTRIB))
         {
            char path[PATH_MAX];
            snprintf(path, sizeof(path), "/dev/input/%s", event->name);
            bool ret = linuxraw_joypad_init_pad(path, &g_pads[index]);

            if (*g_pads[index].ident && ret)
               input_config_autoconfigure_joypad(index, g_pads[index].ident, "linuxraw");
         }
      }
   }

   free(event_buf);
}
Example #20
0
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
{
    bool is_xinput_pad;
    LPDIRECTINPUTDEVICE8 *pad = NULL;
    driver_t *driver     = driver_get_ptr();
    settings_t *settings = config_get_ptr();

    (void)p;

    if (g_joypad_cnt == MAX_USERS)
        return DIENUM_STOP;

    pad = &g_pads[g_joypad_cnt].joypad;

#ifdef __cplusplus
    if (FAILED(IDirectInput8_CreateDevice(
                   g_dinput_ctx, inst->guidInstance, pad, NULL)))
#else
    if (FAILED(IDirectInput8_CreateDevice(
                   g_dinput_ctx, &inst->guidInstance, pad, NULL)))
#endif
        return DIENUM_CONTINUE;

    g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);

#ifdef HAVE_XINPUT
#if 0
    is_xinput_pad = g_xinput_block_pads
                    && name_is_xinput_pad(inst->tszProductName);
#endif
    is_xinput_pad = g_xinput_block_pads
                    && guid_is_xinput_device(&inst->guidProduct);

    if (is_xinput_pad)
    {
        if (g_last_xinput_pad_idx < 4)
            g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_idx++;
        goto enum_iteration_done;
    }
#endif

    IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
    IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)driver->video_window,
                                            DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

    IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb,
                                    *pad, DIDFT_ABSAXIS);

#ifdef HAVE_XINPUT
    if (!is_xinput_pad)
#endif
    {
        autoconfig_params_t params = {{0}};

        strlcpy(settings->input.device_names[g_joypad_cnt],
                dinput_joypad_name(g_joypad_cnt),
                sizeof(settings->input.device_names[g_joypad_cnt]));

        /* TODO - implement VID/PID? */
        params.idx = g_joypad_cnt;
        strlcpy(params.name, dinput_joypad_name(g_joypad_cnt), sizeof(params.name));
        strlcpy(params.driver, dinput_joypad.ident, sizeof(params.driver));
        input_config_autoconfigure_joypad(&params);
    }

enum_iteration_done:
    g_joypad_cnt++;
    return DIENUM_CONTINUE;
}
Example #21
0
static void handle_plugged_pad(void)
{
   int i, rc;
   size_t event_size  = sizeof(struct inotify_event) + NAME_MAX + 1;
   uint8_t *event_buf = (uint8_t*)calloc(1, event_size);

   if (!event_buf)
      return;

   while ((rc = read(g_notify, event_buf, event_size)) >= 0)
   {
      struct inotify_event *event = NULL;

      /* Can read multiple events in one read() call. */

      for (i = 0; i < rc; i += event->len + sizeof(struct inotify_event))
      {
         unsigned idx;
         autoconfig_params_t params = {{0}};

         event = (struct inotify_event*)&event_buf[i];

         if (strstr(event->name, "js") != event->name)
            continue;

         idx = strtoul(event->name + 2, NULL, 0);
         if (idx >= MAX_USERS)
            continue;

         if (event->mask & IN_DELETE)
         {
            if (linuxraw_pads[idx].fd >= 0)
            {
               if (g_hotplug)
                  input_config_autoconfigure_disconnect(idx, linuxraw_pads[idx].ident);

               close(linuxraw_pads[idx].fd);
               linuxraw_pads[idx].buttons = 0;
               memset(linuxraw_pads[idx].axes, 0, sizeof(linuxraw_pads[idx].axes));
               linuxraw_pads[idx].fd = -1;
               *linuxraw_pads[idx].ident = '\0';

               /* TODO - implement VID/PID? */
               params.idx = idx;
               input_config_autoconfigure_joypad(&params);
            }
         }
         /* Sometimes, device will be created before acess to it is established. */
         else if (event->mask & (IN_CREATE | IN_ATTRIB))
         {
            bool ret;
            char path[PATH_MAX_LENGTH] = {0};

            snprintf(path, sizeof(path), "/dev/input/%s", event->name);
            ret = linuxraw_joypad_init_pad(path, &linuxraw_pads[idx]);

            if (*linuxraw_pads[idx].ident && ret)
            {
               params.idx = idx;
               strlcpy(params.name,   linuxraw_pads[idx].ident, sizeof(params.name));
               strlcpy(params.driver, linuxraw_joypad.ident, sizeof(params.driver));
               /* TODO - implement VID/PID? */
               input_config_autoconfigure_joypad(&params);
            }
         }
      }
   }

   free(event_buf);
}
Example #22
0
static void sdl_pad_connect(unsigned id)
{
   sdl_joypad_t *pad          = (sdl_joypad_t*)&sdl_pads[id];
   bool success               = false;
   int32_t product            = 0;
   int32_t vendor             = 0;
   settings_t *settings       = config_get_ptr();
   autoconfig_params_t params = {{0}};

#ifdef HAVE_SDL2
   SDL_JoystickGUID guid;
   uint16_t *guid_ptr;

   if (SDL_IsGameController(id))
   {
      pad->controller = SDL_GameControllerOpen(id);
      pad->joypad     = SDL_GameControllerGetJoystick(pad->controller);

      success = pad->joypad != NULL && pad->controller != NULL;
   }
   else
#endif
   {
      pad->joypad = SDL_JoystickOpen(id);
      success = pad->joypad != NULL;
   }

   if (!success)
   {
      RARCH_ERR("[SDL]: Couldn't open joystick #%u: %s.\n", id, SDL_GetError());

      if (pad->joypad)
         SDL_JoystickClose(pad->joypad);

      pad->joypad = NULL;

      return;
   }

   strlcpy(settings->input.device_names[id], sdl_pad_name(id), sizeof(settings->input.device_names[id]));

#ifdef HAVE_SDL2
   guid       = SDL_JoystickGetGUID(pad->joypad);
   guid_ptr   = (uint16_t*)guid.data;
#ifdef __linux
   vendor     = guid_ptr[2];
   product    = guid_ptr[4];
#elif _WIN32
   vendor     = guid_ptr[0];
   product    = guid_ptr[1];
#endif
#endif
   params.idx = id;
   strlcpy(params.name, sdl_pad_name(id), sizeof(params.name));
   params.vid = vendor;
   params.pid = product;
   strlcpy(params.driver, sdl_joypad.ident, sizeof(params.driver));

   input_config_autoconfigure_joypad(&params);

   RARCH_LOG("[SDL]: Device #%u (%04x:%04x) connected: %s.\n", id, vendor,
             product, sdl_pad_name(id));

#ifdef HAVE_SDL2

   if (pad->controller)
      RARCH_LOG("[SDL]: Device #%u supports game controller api.\n", id);

   pad->haptic = g_has_haptic ? SDL_HapticOpenFromJoystick(pad->joypad) : NULL;

   if (g_has_haptic && !pad->haptic)
      RARCH_WARN("[SDL]: Couldn't open haptic device of the joypad #%u: %s\n",
                 id, SDL_GetError());

   pad->rumble_effect = -1;

   if (pad->haptic)
   {
      SDL_HapticEffect efx;
      efx.type = SDL_HAPTIC_LEFTRIGHT;
      efx.leftright.type = SDL_HAPTIC_LEFTRIGHT;
      efx.leftright.large_magnitude = efx.leftright.small_magnitude = 0x4000;
      efx.leftright.length = 5000;

      if (SDL_HapticEffectSupported(pad->haptic, &efx) == SDL_FALSE)
      {
         pad->rumble_effect = -2;
         RARCH_WARN("[SDL]: Device #%u does not support rumble.\n", id);
      }
   }
#endif

   pad->num_axes    = SDL_JoystickNumAxes(pad->joypad);
   pad->num_buttons = SDL_JoystickNumButtons(pad->joypad);
   pad->num_hats    = SDL_JoystickNumHats(pad->joypad);

#ifdef HAVE_SDL2
   pad->num_balls   = SDL_JoystickNumBalls(pad->joypad);

   RARCH_LOG("[SDL]: Device #%u has: %u axes, %u buttons, %u hats and %u trackballs.\n",
             id, pad->num_axes, pad->num_buttons, pad->num_hats, pad->num_balls);
#else
   RARCH_LOG("[SDL]: Device #%u has: %u axes, %u buttons, %u hats.\n",
             id, pad->num_axes, pad->num_buttons, pad->num_hats);
#endif
}
Example #23
0
static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
{
#ifdef HAVE_XINPUT
    bool is_xinput_pad;
#endif
    LPDIRECTINPUTDEVICE8 *pad = NULL;
    settings_t *settings = config_get_ptr();

    (void)p;

    if (g_joypad_cnt == MAX_USERS)
        return DIENUM_STOP;

    pad = &g_pads[g_joypad_cnt].joypad;

#ifdef __cplusplus
    if (FAILED(IDirectInput8_CreateDevice(
                   g_dinput_ctx, inst->guidInstance, pad, NULL)))
#else
    if (FAILED(IDirectInput8_CreateDevice(
                   g_dinput_ctx, &inst->guidInstance, pad, NULL)))
#endif
        return DIENUM_CONTINUE;

    g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
    g_pads[g_joypad_cnt].joy_friendly_name = strdup(inst->tszInstanceName);

    /* there may be more useful info in the GUID so leave this here for a while */
#if 0
    printf("Guid = {%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n",
           inst->guidProduct.Data1, inst->guidProduct.Data2, inst->guidProduct.Data3,
           inst->guidProduct.Data4[0], inst->guidProduct.Data4[1], inst->guidProduct.Data4[2], inst->guidProduct.Data4[3],
           inst->guidProduct.Data4[4], inst->guidProduct.Data4[5], inst->guidProduct.Data4[6], inst->guidProduct.Data4[7]);
#endif

    g_pads[g_joypad_cnt].vid = inst->guidProduct.Data1 % 0x10000;
    g_pads[g_joypad_cnt].pid = inst->guidProduct.Data1 / 0x10000;

    RARCH_LOG("Device #%u PID: {%04lX} VID:{%04lX}\n", g_joypad_cnt, g_pads[g_joypad_cnt].pid, g_pads[g_joypad_cnt].vid);

#ifdef HAVE_XINPUT
    is_xinput_pad = g_xinput_block_pads
                    && guid_is_xinput_device(&inst->guidProduct);

    if (is_xinput_pad)
    {
        if (g_last_xinput_pad_idx < 4)
            g_xinput_pad_indexes[g_joypad_cnt] = g_last_xinput_pad_idx++;
        goto enum_iteration_done;
    }
#endif

    IDirectInputDevice8_SetDataFormat(*pad, &c_dfDIJoystick2);
    IDirectInputDevice8_SetCooperativeLevel(*pad, (HWND)video_driver_window_get(),
                                            DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

    IDirectInputDevice8_EnumObjects(*pad, enum_axes_cb,
                                    *pad, DIDFT_ABSAXIS);

#ifdef HAVE_XINPUT
    if (!is_xinput_pad)
#endif
    {
        autoconfig_params_t params = {{0}};

        strlcpy(settings->input.device_names[g_joypad_cnt],
                dinput_joypad_name(g_joypad_cnt),
                sizeof(settings->input.device_names[g_joypad_cnt]));

        params.idx = g_joypad_cnt;
        strlcpy(params.name, dinput_joypad_name(g_joypad_cnt), sizeof(params.name));
        strlcpy(params.display_name, dinput_joypad_friendly_name(g_joypad_cnt), sizeof(params.driver));
        strlcpy(params.driver, dinput_joypad.ident, sizeof(params.driver));
        params.vid = dinput_joypad_vid(g_joypad_cnt);
        params.pid = dinput_joypad_pid(g_joypad_cnt);
        input_config_autoconfigure_joypad(&params);
        settings->input.pid[g_joypad_cnt] = params.pid;
        settings->input.vid[g_joypad_cnt] = params.vid;
    }

#ifdef HAVE_XINPUT
enum_iteration_done:
#endif
    g_joypad_cnt++;
    return DIENUM_CONTINUE;
}
Example #24
0
static bool winxinput_joypad_init(void)
{
   unsigned i, autoconf_pad;
   XINPUT_STATE dummy_state;
   const char *version = "1.4";

   g_winxinput_dll = NULL;

   /* Find the correct path to load the DLL from.
    * Usually this will be from the system directory,
    * but occasionally a user may wish to use a third-party
    * wrapper DLL (such as x360ce); support these by checking
    * the working directory first.
    *
    * No need to check for existance as we will be checking LoadLibrary's
    * success anyway.
    */

   /* Using dylib_* complicates building joyconfig. */
   g_winxinput_dll = LoadLibrary("xinput1_4.dll"); 
   if (!g_winxinput_dll)
   {
      g_winxinput_dll = LoadLibrary("xinput1_3.dll");
      version = "1.3";
   }

   if (!g_winxinput_dll)
   {
      RARCH_ERR("Failed to load XInput, ensure DirectX and controller drivers are up to date.\n");
      return false;
   }

   RARCH_LOG("Found XInput v%s.\n", version);

   /* If we get here then an xinput DLL is correctly loaded.
    * First try to load ordinal 100 (XInputGetStateEx).
    */
   g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, (const char*)100);
   g_winxinput_guide_button_supported = true;

   if (!g_XInputGetStateEx)
   {
      /* no ordinal 100. (Presumably a wrapper.) Load the ordinary
       * XInputGetState, at the cost of losing guide button support.
       */
      g_winxinput_guide_button_supported = false;
      g_XInputGetStateEx = (XInputGetStateEx_t) GetProcAddress(g_winxinput_dll, "XInputGetState");

      if (!g_XInputGetStateEx)
      {
         RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
         FreeLibrary(g_winxinput_dll);
         return false; /* DLL was loaded but did not contain the correct function. */
      }
      RARCH_WARN("XInput: No guide button support.\n");
   }

   g_XInputSetState = (XInputSetState_t) GetProcAddress(g_winxinput_dll, "XInputSetState");
   if (!g_XInputSetState)
   {
      RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
      FreeLibrary(g_winxinput_dll);
      return false; /* DLL was loaded but did not contain the correct function. */
   }

   /* Zero out the states. */
   for (i = 0; i < 4; ++i)
      memset(&g_winxinput_states[i], 0, sizeof(winxinput_joypad_state));

   /* Do a dummy poll to check which controllers are connected. */
   for (i = 0; i < 4; ++i)
   {
      g_winxinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED);
      if (g_winxinput_states[i].connected)
         RARCH_LOG("Found XInput controller, user #%u\n", i);
   }

   if ((!g_winxinput_states[0].connected) &&
         (!g_winxinput_states[1].connected) &&
         (!g_winxinput_states[2].connected) &&
         (!g_winxinput_states[3].connected))
      return false;

   g_xinput_block_pads = true;

   /* We're going to have to be buddies with dinput if we want to be able
    * to use XInput and non-XInput controllers together. */
   if (!dinput_joypad.init())
   {
      g_xinput_block_pads = false;
      return false;
   }

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      if (pad_index_to_xuser_index(autoconf_pad) > -1)
      {
         strlcpy(g_settings.input.device_names[autoconf_pad],
               winxinput_joypad_name(autoconf_pad),
               sizeof(g_settings.input.device_names[autoconf_pad]));

         /* TODO - implement VID/PID? */
         input_config_autoconfigure_joypad(autoconf_pad,
               winxinput_joypad_name(autoconf_pad),
               0, 0,
               winxinput_joypad.ident);
      }
   }

   return true;
}
Example #25
0
static bool parport_joypad_init(void *data)
{
   unsigned i, j;
   bool found_enabled_button             = false;
   bool found_disabled_button            = false;
   char buf[PARPORT_NUM_BUTTONS * 3 + 1] = {0};
   char pin[3 + 1]                       = {0};
   settings_t *settings                  = config_get_ptr();
   autoconfig_params_t params            = {{0}};

   (void)data;

   memset(buf, 0, PARPORT_NUM_BUTTONS * 3 + 1);

   for (i = 0; i < MAX_USERS; i++)
   {
      char path[PATH_MAX_LENGTH] = {0};
      struct parport_joypad *pad = &parport_pads[i];

      pad->fd    = -1;
      pad->ident = settings->input.device_names[i];

      snprintf(path, sizeof(path), "/dev/parport%u", i);

      params.idx = i;

      if (parport_joypad_init_pad(path, pad))
      {
         /* If a pin is low on initialization it can either mean
          * a button is pressed or that nothing is connected.
          * Polling non-connected pins can render the menu unusable
          * so assume the user is not holding any button on startup
          * and disable any low pins.
          */
         parport_poll_pad(pad);
         found_enabled_button = false;
         found_disabled_button = false;

         for (j = 0; j < PARPORT_NUM_BUTTONS; j++)
         {
            if (!(BIT64_GET(pad->buttons, j)))
            {
               pad->button_enable[j] = true;
               found_enabled_button = true;
            }
            else
            {
               pad->button_enable[j] = false;
               found_disabled_button = true;
            }
         }

         if (found_enabled_button)
         {
            if (found_disabled_button)
            {
               buf[0] = '\0';
               for (j = 0; j < PARPORT_NUM_BUTTONS; j++)
               {
                  if (!pad->button_enable[j])
                  {
                     snprintf(pin, sizeof(pin), "%d ", j);
                     strlcat(buf, pin, sizeof(buf));
                  }
               }
               RARCH_WARN("[Joypad]: Pin(s) %son %s were low on init, assuming not connected\n", \
                     buf, path);
            }
            strlcpy(params.name, "Generic Parallel Port device", sizeof(params.name));
            strlcpy(params.driver, "parport", sizeof(params.driver));
         }
         else
         {
            RARCH_WARN("[Joypad]: All pins low on %s, assuming nothing connected\n", path);
            parport_free_pad(pad);
         }
      }
      input_config_autoconfigure_joypad(&params);
   }

   return true;
}