* Copyright 2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Fredrik Modeen
*
*/
#include "JoystickTweaker.h"
#include <new>
#include <stdio.h>
#include <stdlib.h>
#include <Debug.h>
#include <Directory.h>
#include <Joystick.h>
#include <Path.h>
#include <String.h>
#include <UTF8.h>
#define STACK_STRING_BUFFER_SIZE 64
#if DEBUG
inline void
LOG(const char *fmt, ...)
{
char buf[1024];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
fputs(buf, _BJoystickTweaker::sLogFile);
fflush(_BJoystickTweaker::sLogFile);
}
# define LOG_ERR(text...) LOG(text)
FILE *_BJoystickTweaker::sLogFile = NULL;
#else
# define LOG(text...)
# define LOG_ERR(text...) fprintf(stderr, text)
#endif
#define CALLED() LOG("%s\n", __PRETTY_FUNCTION__)
_BJoystickTweaker::_BJoystickTweaker()
{
#if DEBUG
sLogFile = fopen("/var/log/joystick.log", "a");
#endif
CALLED();
}
_BJoystickTweaker::_BJoystickTweaker(BJoystick &stick)
{
#if DEBUG
sLogFile = fopen("/var/log/joystick.log", "a");
#endif
CALLED();
fJoystick = &stick;
}
_BJoystickTweaker::~_BJoystickTweaker()
{
}
status_t
_BJoystickTweaker::save_config(const entry_ref *ref)
{
CALLED();
return B_ERROR;
}
status_t
_BJoystickTweaker::_ScanIncludingDisabled(const char *rootPath, BList *list,
BEntry *rootEntry)
{
BDirectory root;
if (rootEntry != NULL)
root.SetTo(rootEntry);
else if (rootPath != NULL)
root.SetTo(rootPath);
else
return B_ERROR;
BEntry entry;
ASSERT(list != NULL);
while (root.GetNextEntry(&entry) == B_OK) {
if (entry.IsDirectory()) {
status_t result = _ScanIncludingDisabled(rootPath, list, &entry);
if (result != B_OK)
return result;
continue;
}
BPath path;
status_t result = entry.GetPath(&path);
if (result != B_OK)
return result;
BString *deviceName = new(std::nothrow) BString(path.Path());
if (deviceName == NULL)
return B_NO_MEMORY;
deviceName->RemoveFirst(rootPath);
if (!list->AddItem(deviceName)) {
delete deviceName;
return B_ERROR;
}
}
return B_OK;
}
void
_BJoystickTweaker::scan_including_disabled()
{
CALLED();
_EmpyList(fJoystick->fDevices);
_ScanIncludingDisabled(DEVICE_BASE_PATH, fJoystick->fDevices);
}
void
_BJoystickTweaker::_EmpyList(BList *list)
{
for (int32 i = 0; i < list->CountItems(); i++)
delete (BString *)list->ItemAt(i);
list->MakeEmpty();
}
status_t
_BJoystickTweaker::get_info()
{
CALLED();
return B_ERROR;
}
status_t
_BJoystickTweaker::GetInfo(_joystick_info *info, const char *ref)
{
CALLED();
BString configFilePath(JOYSTICK_CONFIG_BASE_PATH);
configFilePath.Append(ref);
FILE *file = fopen(configFilePath.String(), "r");
if (file == NULL)
return B_ERROR;
char line[STACK_STRING_BUFFER_SIZE];
while (fgets(line, sizeof(line), file) != NULL) {
int length = strlen(line);
if (length > 0 && line[length - 1] == '\n')
line[length - 1] = '\0';
_BuildFromJoystickDesc(line, info);
}
fclose(file);
return B_OK;
}
void
_BJoystickTweaker::_BuildFromJoystickDesc(char *string, _joystick_info *info)
{
BString str(string);
str.RemoveAll("\"");
if (str.IFindFirst("module") != -1) {
str.RemoveFirst("module = ");
strlcpy(info->module_info.module_name, str.String(),
STACK_STRING_BUFFER_SIZE);
} else if (str.IFindFirst("gadget") != -1) {
str.RemoveFirst("gadget = ");
strlcpy(info->module_info.device_name, str.String(),
STACK_STRING_BUFFER_SIZE);
} else if (str.IFindFirst("num_axes") != -1) {
str.RemoveFirst("num_axes = ");
info->module_info.num_axes = atoi(str.String());
} else if (str.IFindFirst("num_hats") != -1) {
str.RemoveFirst("num_hats = ");
info->module_info.num_hats = atoi(str.String());
} else if (str.IFindFirst("num_buttons") != -1) {
str.RemoveFirst("num_buttons = ");
info->module_info.num_buttons = atoi(str.String());
} else if (str.IFindFirst("num_sticks") != -1) {
str.RemoveFirst("num_sticks = ");
info->module_info.num_sticks = atoi(str.String());
} else {
LOG("Path = %s\n", str.String());
}
}
status_t
_BJoystickTweaker::SendIOCT(uint32 op)
{
switch (op) {
case B_JOYSTICK_SET_DEVICE_MODULE:
break;
case B_JOYSTICK_GET_DEVICE_MODULE:
break;
case B_JOYSTICK_GET_SPEED_COMPENSATION:
case B_JOYSTICK_SET_SPEED_COMPENSATION:
case B_JOYSTICK_GET_MAX_LATENCY:
case B_JOYSTICK_SET_MAX_LATENCY:
case B_JOYSTICK_SET_RAW_MODE:
default:
break;
}
return B_ERROR;
}