<commit_before>/*
    Copyright (C) 2002 by <NAME>
    Multi-axis support (C) 2005 <NAME> <<EMAIL>>
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "iutil/csinput.h" /* for JS max/mins */
#include "iutil/verbositymanager.h"
#include "ivaria/reporter.h"

#include "csutil/array.h"
#include "csutil/csstring.h"
#include "csutil/event.h"
#include "csutil/eventnames.h"
#include "csutil/eventhandlers.h"

#include "csjoylin.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/joystick.h>

#define CS_LINUX_JOYSTICK_CFG "/config/joystick.cfg"
#define CS_LINUX_JOYSTICK_KEY "Device.Joystick." CS_PLATFORM_NAME "."



CS_PLUGIN_NAMESPACE_BEGIN(JoyLin)
{

SCF_IMPLEMENT_FACTORY (csLinuxJoystick);

csLinuxJoystick::csLinuxJoystick (iBase *parent) :
  scfImplementationType (this, parent),
  object_reg(0),
  joystick(0),
  nJoy(0),
  bHooked(false)
{
}

csLinuxJoystick::~csLinuxJoystick ()
{
  Close ();
}

bool csLinuxJoystick::Initialize (iObjectRegistry *oreg)
{
  object_reg = oreg;
  return Init ();
}

#define CS_MAX_LINUX_JOYSTICK_AXES CS_MAX_JOYSTICK_AXES
bool csLinuxJoystick::HandleEvent (iEvent& ev)
{
  if (ev.Name != Frame)
    return false;

  struct js_event js;

  for (int i = 0; i < nJoy; i++)
  {
    joydata& jd = joystick[i];
    while (read (jd.fd, &js, sizeof(js)) == sizeof(js)) 
    {
      int32 axisread[CS_MAX_LINUX_JOYSTICK_AXES];
      if ((js.type & ~JS_EVENT_INIT) == JS_EVENT_AXIS)
	jd.axis[js.number] = js.value;
      for (int iter=0 ; 
	   iter<MIN(jd.nAxes,CS_MAX_LINUX_JOYSTICK_AXES) ; 
	   iter++)
	axisread[iter] = jd.axis[iter]; /* "int16" to "int" */
      switch (js.type & ~JS_EVENT_INIT) 
      {
      case JS_EVENT_BUTTON:
        jd.button[js.number] = js.value;
        EventOutlet->Joystick (jd.number, js.number, js.value,
			       axisread, jd.nAxes);
        break;
      case JS_EVENT_AXIS:
        EventOutlet->Joystick (jd.number, (uint) -1, 0, 
			       axisread, jd.nAxes);
        break;
      }
    }
  }
  return false;
}

bool csLinuxJoystick::Init ()
{
  bool verbose = false;
  csRef<iVerbosityManager> verbosemgr (
    csQueryRegistry<iVerbosityManager> (object_reg));
  if (verbosemgr) 
    verbose = verbosemgr->Enabled ("joystick");

  config.AddConfig (object_reg, CS_LINUX_JOYSTICK_CFG);
  csRef<iConfigIterator> it (config->Enumerate (CS_LINUX_JOYSTICK_KEY));
  csArray<int> fds;
  csArray<dev_t> devids;

  nJoy=0;
  bHooked = false;
  EventOutlet = 0;

  while (it->Next ())
  {
    int fd = open (it->GetStr (), O_RDONLY);
    if (fd >= 0) 
    {
      Report (CS_REPORTER_SEVERITY_DEBUG,
	      "Opened joystick device %s as fd#%d\n",
	      it->GetStr(), fd);
      struct stat st;
      fstat(fd, &st);

      /* check devids for a dup st.st_dev */
      for (csArray<dev_t>::Iterator i = devids.GetIterator(); i.HasNext(); )
      {
	if (i.Next() == st.st_rdev)
	{
	  close(fd);
	  fd = -1;
	  if (verbose)
	    Report (CS_REPORTER_SEVERITY_WARNING,
		    "Found duplicate joystick device %s\n", it->GetStr());
	  break;
	}
      }
      if (fd != -1)
      {
	nJoy++;
	fds.Push((const int) fd);
	devids.Push(st.st_rdev);
      }
    }
    else if (verbose || errno != ENOENT)
    {
      Report (CS_REPORTER_SEVERITY_WARNING,
              "Failed to open joystick device %s - error: %s\n",
              it->GetStr (),
              strerror (errno));
    }
  }

  if (nJoy)
  {
    delete [] joystick;
    joystick = new joydata[nJoy];
    
    csArray<int>::Iterator i = fds.GetIterator();
    int n = 0;
    while (i.HasNext())
    {
      int const fd = i.Next();
      unsigned char axes = 2;
      unsigned char buttons = 2;
      int version = 0x000800;
      char name[128] = "Unknown";

      ioctl (fd, JSIOCGVERSION, &version);
      ioctl (fd, JSIOCGAXES, &axes);
      ioctl (fd, JSIOCGBUTTONS, &buttons);
      ioctl (fd, JSIOCGNAME(128), name);<commit_msg>Lowered severity of a message which will always show in the linux joystick support. That the joystick device x can't be opened will always happen even more when trying 15 devices in two places and even further when there is no joypad attached.<commit_after>/*
    Copyright (C) 2002 by <NAME>
    Multi-axis support (C) 2005 <NAME> <<EMAIL>>
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "iutil/csinput.h" /* for JS max/mins */
#include "iutil/verbositymanager.h"
#include "ivaria/reporter.h"

#include "csutil/array.h"
#include "csutil/csstring.h"
#include "csutil/event.h"
#include "csutil/eventnames.h"
#include "csutil/eventhandlers.h"

#include "csjoylin.h"

#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/joystick.h>

#define CS_LINUX_JOYSTICK_CFG "/config/joystick.cfg"
#define CS_LINUX_JOYSTICK_KEY "Device.Joystick." CS_PLATFORM_NAME "."



CS_PLUGIN_NAMESPACE_BEGIN(JoyLin)
{

SCF_IMPLEMENT_FACTORY (csLinuxJoystick);

csLinuxJoystick::csLinuxJoystick (iBase *parent) :
  scfImplementationType (this, parent),
  object_reg(0),
  joystick(0),
  nJoy(0),
  bHooked(false)
{
}

csLinuxJoystick::~csLinuxJoystick ()
{
  Close ();
}

bool csLinuxJoystick::Initialize (iObjectRegistry *oreg)
{
  object_reg = oreg;
  return Init ();
}

#define CS_MAX_LINUX_JOYSTICK_AXES CS_MAX_JOYSTICK_AXES
bool csLinuxJoystick::HandleEvent (iEvent& ev)
{
  if (ev.Name != Frame)
    return false;

  struct js_event js;

  for (int i = 0; i < nJoy; i++)
  {
    joydata& jd = joystick[i];
    while (read (jd.fd, &js, sizeof(js)) == sizeof(js)) 
    {
      int32 axisread[CS_MAX_LINUX_JOYSTICK_AXES];
      if ((js.type & ~JS_EVENT_INIT) == JS_EVENT_AXIS)
	jd.axis[js.number] = js.value;
      for (int iter=0 ; 
	   iter<MIN(jd.nAxes,CS_MAX_LINUX_JOYSTICK_AXES) ; 
	   iter++)
	axisread[iter] = jd.axis[iter]; /* "int16" to "int" */
      switch (js.type & ~JS_EVENT_INIT) 
      {
      case JS_EVENT_BUTTON:
        jd.button[js.number] = js.value;
        EventOutlet->Joystick (jd.number, js.number, js.value,
			       axisread, jd.nAxes);
        break;
      case JS_EVENT_AXIS:
        EventOutlet->Joystick (jd.number, (uint) -1, 0, 
			       axisread, jd.nAxes);
        break;
      }
    }
  }
  return false;
}

bool csLinuxJoystick::Init ()
{
  bool verbose = false;
  csRef<iVerbosityManager> verbosemgr (
    csQueryRegistry<iVerbosityManager> (object_reg));
  if (verbosemgr) 
    verbose = verbosemgr->Enabled ("joystick");

  config.AddConfig (object_reg, CS_LINUX_JOYSTICK_CFG);
  csRef<iConfigIterator> it (config->Enumerate (CS_LINUX_JOYSTICK_KEY));
  csArray<int> fds;
  csArray<dev_t> devids;

  nJoy=0;
  bHooked = false;
  EventOutlet = 0;

  while (it->Next ())
  {
    int fd = open (it->GetStr (), O_RDONLY);
    if (fd >= 0) 
    {
      Report (CS_REPORTER_SEVERITY_DEBUG,
	      "Opened joystick device %s as fd#%d\n",
	      it->GetStr(), fd);
      struct stat st;
      fstat(fd, &st);

      /* check devids for a dup st.st_dev */
      for (csArray<dev_t>::Iterator i = devids.GetIterator(); i.HasNext(); )
      {
	if (i.Next() == st.st_rdev)
	{
	  close(fd);
	  fd = -1;
	  if (verbose)
	    Report (CS_REPORTER_SEVERITY_WARNING,
		    "Found duplicate joystick device %s\n", it->GetStr());
	  break;
	}
      }
      if (fd != -1)
      {
	nJoy++;
	fds.Push((const int) fd);
	devids.Push(st.st_rdev);
      }
    }
    else if (verbose || errno != ENOENT)
    {
      Report (CS_REPORTER_SEVERITY_DEBUG,
              "Failed to open joystick device %s - error: %s\n",
              it->GetStr (),
              strerror (errno));
    }
  }

  if (nJoy)
  {
    delete [] joystick;
    joystick = new joydata[nJoy];
    
    csArray<int>::Iterator i = fds.GetIterator();
    int n = 0;
    while (i.HasNext())
    {
      int const fd = i.Next();
      unsigned char axes = 2;
      unsigned char buttons = 2;
      int version = 0x000800;
      char name[128] = "Unknown";

      ioctl (fd, JSIOCGVERSION, &version);
      ioctl (fd, JSIOCGAXES, &axes);
      ioctl (fd, JSIOCGBUTTONS, &buttons);
      ioctl (fd, JSIOCGNAME(128), name);
{'fraction_non_alphanumeric': 0.12507850115135022, 'fraction_numerical': 0.010466820180029307, 'mean_word_length': 3.0265486725663715, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7577984', 'n_tokens_mistral': 3672, 'n_tokens_neox': 3446, 'n_words': 893}