/*---------------------------------------------------------------------------- ChucK Concurrent, On-the-fly Audio Programming Language Compiler and Virtual Machine Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved. http://chuck.stanford.edu/ http://chuck.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: hidio_sdl.cpp// desc: HID io over SDL header//// author: Spencer Salazar (ssalazar@cs.princeton.edu)// Ge Wang (gewang@cs.princeton.edu)// Ananya Misra (amisra@cs.princeton.edu)// Perry R. Cook (prc@cs.princeton.edu)// date: Summer 2005//-----------------------------------------------------------------------------#include "hidio_sdl.h"#include "util_hid.h"#include "chuck_errmsg.h"#include "chuck_vm.h" #ifndef __PLATFORM_WIN32__#include <unistd.h>#else#include "chuck_def.h"#endif #include <limits.h>#include <vector>#include <map>using namespace std; Chuck_Hid_Driver * default_drivers = NULL; struct PhyHidDevIn{public: PhyHidDevIn(); ~PhyHidDevIn(); t_CKBOOL open( Chuck_VM * vm, t_CKINT type, t_CKUINT number ); t_CKBOOL add_vm( Chuck_VM * vm ); t_CKBOOL read( t_CKINT element_type, t_CKINT element_num, HidMsg * msg ); t_CKBOOL send( const HidMsg * msg ); // close for a specific vm only t_CKBOOL remove_vm( Chuck_VM * vm ); // close for all vms t_CKBOOL close(); std::string name(); t_CKBOOL query_element( HidMsg * query ); t_CKBOOL register_client( HidIn * client ); t_CKBOOL unregister_client( HidIn * client ); public: std::map< Chuck_VM *, CBufferAdvance * > cbufs; protected: t_CKINT device_type; t_CKUINT device_num; std::vector< HidIn * > clients;}; struct PhyHidDevOut{ // lies}; //-----------------------------------------------------------------------------// global variables//-----------------------------------------------------------------------------// per-physical device buffer size#define BUFFER_SIZE 1024 std::vector< std::vector<PhyHidDevIn *> > HidInManager::the_matrix;XThread * HidInManager::the_thread = NULL;t_CKBOOL HidInManager::thread_going = FALSE;t_CKBOOL HidInManager::has_init = FALSE;CBufferSimple * HidInManager::msg_buffer = NULL;std::vector<PhyHidDevOut *> HidOutManager::the_phouts;std::map< Chuck_VM *, CBufferSimple * > HidInManager::m_event_buffers; //-----------------------------------------------------------------------------// name: PhyHidDevIn()// desc: constructor//-----------------------------------------------------------------------------PhyHidDevIn::PhyHidDevIn(){ device_type = CK_HID_DEV_NONE; device_num = 0;} //-----------------------------------------------------------------------------// name: ~PhyHidDevIn()// desc: destructor//-----------------------------------------------------------------------------PhyHidDevIn::~PhyHidDevIn(){ // check if( device_type != CK_HID_DEV_NONE ) this->close();} //-----------------------------------------------------------------------------// name: open()// desc: opens the device of specified type and id//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::open( Chuck_VM * vm, t_CKINT type, t_CKUINT number ){ // check if( device_type != CK_HID_DEV_NONE ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> already open!" ); return FALSE; } if( type <= CK_HID_DEV_NONE || type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> invalid device type %d", type ); return FALSE; } if( !default_drivers[type].open ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> %s does not support open", default_drivers[type].driver_name ); return FALSE; } if( default_drivers[type].open( ( int ) number ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> invalid %s number %d", default_drivers[type].driver_name, number ); return FALSE; } // allocate the buffer if( !add_vm( vm ) ) { // error messages already printed in add_vm return FALSE; } device_type = type; device_num = number; return TRUE;} //-----------------------------------------------------------------------------// name: add_vm()// desc: adds a buffer specifically for this vm//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::add_vm( Chuck_VM * vm ){ // allocate the buffer if( cbufs.count( vm ) != 0 ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: add_vm() unnecessary -> add_vm() already called for this VM" ); return FALSE; } cbufs[vm] = new CBufferAdvance; if( !cbufs[vm]->initialize( BUFFER_SIZE, sizeof(HidMsg), HidInManager::m_event_buffers[vm] ) ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: add_vm() operation failed: cannot initialize buffer" ); // REFACTOR-2017: changed from close-all-hard to just-close-for-this-vm this->remove_vm( vm ); return FALSE; } return TRUE;} //-----------------------------------------------------------------------------// name: read()// desc: query specific elements of the hid device//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::read( t_CKINT element_type, t_CKINT element_num, HidMsg * msg ){ if( !default_drivers[device_type].read ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: read() failed -> %s does not support read", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].read( (int) device_num, (int) element_type, (int) element_num, msg ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: read() failed for %s %i, element type %i, element number %i", default_drivers[device_type].driver_name, device_num, element_type, element_num ); return FALSE; } return TRUE;} //-----------------------------------------------------------------------------// name: send()// desc: send message to a HID device//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::send( const HidMsg * msg ){ if( !default_drivers[device_type].send ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: send() failed -> %s does not support send", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].send( (int) device_num, msg ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: send() failed for %s %i", default_drivers[device_type].driver_name, device_num ); return FALSE; } return TRUE;} //-----------------------------------------------------------------------------// name: remove_vm()// desc: removes a buffer specifically for this vm//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::remove_vm( Chuck_VM * vm ){ // check if it exists if( cbufs.count( vm ) == 0 ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: remove_vm() unnecessary -> add_vm() never called for this VM" ); return FALSE; } // delete cbufs[vm] and remove from map SAFE_DELETE( cbufs[vm] ); cbufs.erase( vm ); return TRUE;} //-----------------------------------------------------------------------------// name: close()// desc: closes the device, deallocates all associated data//-----------------------------------------------------------------------------t_CKBOOL PhyHidDevIn::close(){ // close all cbufs: this is a totally-clear-up-everything operation for( std::map< Chuck_VM *, CBufferAdvance * >::iterator it = cbufs.begin(); it != cbufs.end(); it++ ) { CBufferAdvance * cbuf = it->second; if( cbuf != NULL ) { // delete SAFE_DELETE( cbuf ); // REFACTOR-2017: copied over this TODO from previous edition: // TODO: release references from cbuf } } cbufs.clear(); if( device_type <= CK_HID_DEV_NONE || device_type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> invalid device type %d", device_type ); return FALSE; } if( !default_drivers[device_type].close ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> %s does not support close", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].close( ( int ) device_num ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> invalid %s number %d", default_drivers[device_type].driver_name, device_num ); return FALSE; } device_type = CK_HID_DEV_NONE; device_num = 0; return TRUE;} //-----------------------------------------------------------------------------// name: name()// desc: retrieve device name//-----------------------------------------------------------------------------string PhyHidDevIn::name(){ if( device_type == CK_HID_DEV_NONE ) return " "; if( device_type <= CK_HID_DEV_NONE || device_type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: name() failed -> invalid device type %d", device_type ); return " "; } if( !default_drivers[device_type].name ) return default_drivers[device_type].driver_name; const char * _name; if( !( _name = default_drivers[device_type].name( ( int ) device_num ) ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: name() failed -> invalid %s number %d", default_drivers[device_type].driver_name, device_num ); return " "; } return _name;} //-----------------------------------------------------------------------------// name: HidOut()// desc: constructor//-----------------------------------------------------------------------------HidOut::HidOut(){ // phout = new PhyHidDevOut; m_device_num = 0; m_valid = FALSE; m_suppress_output = FALSE;} //-----------------------------------------------------------------------------// name: ~HidOut()// desc: destructor//-----------------------------------------------------------------------------HidOut::~HidOut(){ if( phout ) this->close(); SAFE_DELETE( phout );} //-----------------------------------------------------------------------------// name: send()// desc: send//-----------------------------------------------------------------------------t_CKUINT HidOut::send( const HidMsg * msg ){ if( !m_valid ) return 0; return 0;} //-----------------------------------------------------------------------------// name: open// desc: open HID output//-----------------------------------------------------------------------------t_CKBOOL HidOut::open( t_CKUINT device_num ){ // close if already opened if( m_valid ) this->close(); return m_valid = HidOutManager::open( this, (t_CKINT)device_num );} //-----------------------------------------------------------------------------// name: close( )// desc: close HID output//-----------------------------------------------------------------------------t_CKBOOL HidOut::close( ){ if( !m_valid ) return FALSE; // close // HidOutManager::close( this ); m_valid = FALSE; return TRUE;} //-----------------------------------------------------------------------------// name: HidIn()// desc: constructor//-----------------------------------------------------------------------------HidIn::HidIn(){ phin = NULL; m_device_num = 0; m_valid = FALSE; m_read_index = UINT_MAX; m_buffer = NULL; m_suppress_output = FALSE; SELF = NULL;} //-----------------------------------------------------------------------------// name: ~HidIn()// desc: destructor//-----------------------------------------------------------------------------HidIn::~HidIn( ){ this->close(); // SAFE_DELETE( min );} //-----------------------------------------------------------------------------// name: open()// desc: open//-----------------------------------------------------------------------------t_CKBOOL HidIn::open( Chuck_VM * vm, t_CKINT device_type, t_CKINT device_num ){ // close if already opened if( m_valid ) this->close(); // open return m_valid = HidInManager::open( this, vm, device_type, device_num );} //-----------------------------------------------------------------------------// name: open()// desc: open//-----------------------------------------------------------------------------t_CKBOOL HidIn::open( Chuck_VM * vm, std::string & name, t_CKUINT device_type )Lines 1–500 of 1110. Load more
/*---------------------------------------------------------------------------- ChucK Concurrent, On-the-fly Audio Programming Language Compiler and Virtual Machine Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved. http://chuck.stanford.edu/ http://chuck.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A. -----------------------------------------------------------------------------*/ //----------------------------------------------------------------------------- // file: hidio_sdl.cpp // desc: HID io over SDL header // // author: Spencer Salazar (ssalazar@cs.princeton.edu) // Ge Wang (gewang@cs.princeton.edu) // Ananya Misra (amisra@cs.princeton.edu) // Perry R. Cook (prc@cs.princeton.edu) // date: Summer 2005 //----------------------------------------------------------------------------- #include "hidio_sdl.h" #include "util_hid.h" #include "chuck_errmsg.h" #include "chuck_vm.h" #ifndef __PLATFORM_WIN32__ #include <unistd.h> #else #include "chuck_def.h" #endif #include <limits.h> #include <vector> #include <map> using namespace std; Chuck_Hid_Driver * default_drivers = NULL; struct PhyHidDevIn { public: PhyHidDevIn(); ~PhyHidDevIn(); t_CKBOOL open( Chuck_VM * vm, t_CKINT type, t_CKUINT number ); t_CKBOOL add_vm( Chuck_VM * vm ); t_CKBOOL read( t_CKINT element_type, t_CKINT element_num, HidMsg * msg ); t_CKBOOL send( const HidMsg * msg ); // close for a specific vm only t_CKBOOL remove_vm( Chuck_VM * vm ); // close for all vms t_CKBOOL close(); std::string name(); t_CKBOOL query_element( HidMsg * query ); t_CKBOOL register_client( HidIn * client ); t_CKBOOL unregister_client( HidIn * client ); public: std::map< Chuck_VM *, CBufferAdvance * > cbufs; protected: t_CKINT device_type; t_CKUINT device_num; std::vector< HidIn * > clients; }; struct PhyHidDevOut { // lies }; //----------------------------------------------------------------------------- // global variables //----------------------------------------------------------------------------- // per-physical device buffer size #define BUFFER_SIZE 1024 std::vector< std::vector<PhyHidDevIn *> > HidInManager::the_matrix; XThread * HidInManager::the_thread = NULL; t_CKBOOL HidInManager::thread_going = FALSE; t_CKBOOL HidInManager::has_init = FALSE; CBufferSimple * HidInManager::msg_buffer = NULL; std::vector<PhyHidDevOut *> HidOutManager::the_phouts; std::map< Chuck_VM *, CBufferSimple * > HidInManager::m_event_buffers; //----------------------------------------------------------------------------- // name: PhyHidDevIn() // desc: constructor //----------------------------------------------------------------------------- PhyHidDevIn::PhyHidDevIn() { device_type = CK_HID_DEV_NONE; device_num = 0; } //----------------------------------------------------------------------------- // name: ~PhyHidDevIn() // desc: destructor //----------------------------------------------------------------------------- PhyHidDevIn::~PhyHidDevIn() { // check if( device_type != CK_HID_DEV_NONE ) this->close(); } //----------------------------------------------------------------------------- // name: open() // desc: opens the device of specified type and id //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::open( Chuck_VM * vm, t_CKINT type, t_CKUINT number ) { // check if( device_type != CK_HID_DEV_NONE ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> already open!" ); return FALSE; } if( type <= CK_HID_DEV_NONE || type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> invalid device type %d", type ); return FALSE; } if( !default_drivers[type].open ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> %s does not support open", default_drivers[type].driver_name ); return FALSE; } if( default_drivers[type].open( ( int ) number ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: open() failed -> invalid %s number %d", default_drivers[type].driver_name, number ); return FALSE; } // allocate the buffer if( !add_vm( vm ) ) { // error messages already printed in add_vm return FALSE; } device_type = type; device_num = number; return TRUE; } //----------------------------------------------------------------------------- // name: add_vm() // desc: adds a buffer specifically for this vm //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::add_vm( Chuck_VM * vm ) { // allocate the buffer if( cbufs.count( vm ) != 0 ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: add_vm() unnecessary -> add_vm() already called for this VM" ); return FALSE; } cbufs[vm] = new CBufferAdvance; if( !cbufs[vm]->initialize( BUFFER_SIZE, sizeof(HidMsg), HidInManager::m_event_buffers[vm] ) ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: add_vm() operation failed: cannot initialize buffer" ); // REFACTOR-2017: changed from close-all-hard to just-close-for-this-vm this->remove_vm( vm ); return FALSE; } return TRUE; } //----------------------------------------------------------------------------- // name: read() // desc: query specific elements of the hid device //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::read( t_CKINT element_type, t_CKINT element_num, HidMsg * msg ) { if( !default_drivers[device_type].read ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: read() failed -> %s does not support read", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].read( (int) device_num, (int) element_type, (int) element_num, msg ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: read() failed for %s %i, element type %i, element number %i", default_drivers[device_type].driver_name, device_num, element_type, element_num ); return FALSE; } return TRUE; } //----------------------------------------------------------------------------- // name: send() // desc: send message to a HID device //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::send( const HidMsg * msg ) { if( !default_drivers[device_type].send ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: send() failed -> %s does not support send", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].send( (int) device_num, msg ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: send() failed for %s %i", default_drivers[device_type].driver_name, device_num ); return FALSE; } return TRUE; } //----------------------------------------------------------------------------- // name: remove_vm() // desc: removes a buffer specifically for this vm //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::remove_vm( Chuck_VM * vm ) { // check if it exists if( cbufs.count( vm ) == 0 ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: remove_vm() unnecessary -> add_vm() never called for this VM" ); return FALSE; } // delete cbufs[vm] and remove from map SAFE_DELETE( cbufs[vm] ); cbufs.erase( vm ); return TRUE; } //----------------------------------------------------------------------------- // name: close() // desc: closes the device, deallocates all associated data //----------------------------------------------------------------------------- t_CKBOOL PhyHidDevIn::close() { // close all cbufs: this is a totally-clear-up-everything operation for( std::map< Chuck_VM *, CBufferAdvance * >::iterator it = cbufs.begin(); it != cbufs.end(); it++ ) { CBufferAdvance * cbuf = it->second; if( cbuf != NULL ) { // delete SAFE_DELETE( cbuf ); // REFACTOR-2017: copied over this TODO from previous edition: // TODO: release references from cbuf } } cbufs.clear(); if( device_type <= CK_HID_DEV_NONE || device_type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> invalid device type %d", device_type ); return FALSE; } if( !default_drivers[device_type].close ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> %s does not support close", default_drivers[device_type].driver_name ); return FALSE; } if( default_drivers[device_type].close( ( int ) device_num ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: close() failed -> invalid %s number %d", default_drivers[device_type].driver_name, device_num ); return FALSE; } device_type = CK_HID_DEV_NONE; device_num = 0; return TRUE; } //----------------------------------------------------------------------------- // name: name() // desc: retrieve device name //----------------------------------------------------------------------------- string PhyHidDevIn::name() { if( device_type == CK_HID_DEV_NONE ) return " "; if( device_type <= CK_HID_DEV_NONE || device_type >= CK_HID_DEV_COUNT ) { // log EM_log( CK_LOG_WARNING, "PhyHidDevIn: name() failed -> invalid device type %d", device_type ); return " "; } if( !default_drivers[device_type].name ) return default_drivers[device_type].driver_name; const char * _name; if( !( _name = default_drivers[device_type].name( ( int ) device_num ) ) ) { EM_log( CK_LOG_WARNING, "PhyHidDevIn: name() failed -> invalid %s number %d", default_drivers[device_type].driver_name, device_num ); return " "; } return _name; } //----------------------------------------------------------------------------- // name: HidOut() // desc: constructor //----------------------------------------------------------------------------- HidOut::HidOut() { // phout = new PhyHidDevOut; m_device_num = 0; m_valid = FALSE; m_suppress_output = FALSE; } //----------------------------------------------------------------------------- // name: ~HidOut() // desc: destructor //----------------------------------------------------------------------------- HidOut::~HidOut() { if( phout ) this->close(); SAFE_DELETE( phout ); } //----------------------------------------------------------------------------- // name: send() // desc: send //----------------------------------------------------------------------------- t_CKUINT HidOut::send( const HidMsg * msg ) { if( !m_valid ) return 0; return 0; } //----------------------------------------------------------------------------- // name: open // desc: open HID output //----------------------------------------------------------------------------- t_CKBOOL HidOut::open( t_CKUINT device_num ) { // close if already opened if( m_valid ) this->close(); return m_valid = HidOutManager::open( this, (t_CKINT)device_num ); } //----------------------------------------------------------------------------- // name: close( ) // desc: close HID output //----------------------------------------------------------------------------- t_CKBOOL HidOut::close( ) { if( !m_valid ) return FALSE; // close // HidOutManager::close( this ); m_valid = FALSE; return TRUE; } //----------------------------------------------------------------------------- // name: HidIn() // desc: constructor //----------------------------------------------------------------------------- HidIn::HidIn() { phin = NULL; m_device_num = 0; m_valid = FALSE; m_read_index = UINT_MAX; m_buffer = NULL; m_suppress_output = FALSE; SELF = NULL; } //----------------------------------------------------------------------------- // name: ~HidIn() // desc: destructor //----------------------------------------------------------------------------- HidIn::~HidIn( ) { this->close(); // SAFE_DELETE( min ); } //----------------------------------------------------------------------------- // name: open() // desc: open //----------------------------------------------------------------------------- t_CKBOOL HidIn::open( Chuck_VM * vm, t_CKINT device_type, t_CKINT device_num ) { // close if already opened if( m_valid ) this->close(); // open return m_valid = HidInManager::open( this, vm, device_type, device_num ); } //----------------------------------------------------------------------------- // name: open() // desc: open //----------------------------------------------------------------------------- t_CKBOOL HidIn::open( Chuck_VM * vm, std::string & name, t_CKUINT device_type )