1/*
2 * Copyright 2008, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Fredrik Modeen
7 *
8 */
9#include "JoystickTweaker.h"
10
11#include <new>
12#include <stdio.h>
13#include <stdlib.h>
14
15#include <Debug.h>
16#include <Directory.h>
17#include <Joystick.h>
18#include <Path.h>
19#include <String.h>
20#include <UTF8.h>
21
22
23#define STACK_STRING_BUFFER_SIZE	64
24
25
26#if DEBUG
27inline void
28LOG(const char *fmt, ...)
29{
30	char buf[1024];
31	va_list ap;
32	va_start(ap, fmt);
33	vsprintf(buf, fmt, ap);
34	va_end(ap);
35
36	fputs(buf, _BJoystickTweaker::sLogFile);
37	fflush(_BJoystickTweaker::sLogFile);
38}
39#	define LOG_ERR(text...) LOG(text)
40FILE *_BJoystickTweaker::sLogFile = NULL;
41#else
42#	define LOG(text...)
43#	define LOG_ERR(text...) fprintf(stderr, text)
44#endif
45
46#define CALLED() LOG("%s\n", __PRETTY_FUNCTION__)
47
48
49_BJoystickTweaker::_BJoystickTweaker()
50{
51#if DEBUG
52	sLogFile = fopen("/var/log/joystick.log", "a");
53#endif
54	CALLED();
55}
56
57
58_BJoystickTweaker::_BJoystickTweaker(BJoystick &stick)
59{
60#if DEBUG
61	sLogFile = fopen("/var/log/joystick.log", "a");
62#endif
63	CALLED();
64
65	fJoystick = &stick;
66}
67
68
69_BJoystickTweaker::~_BJoystickTweaker()
70{
71}
72
73
74status_t
75_BJoystickTweaker::save_config(const entry_ref *ref)
76{
77	CALLED();
78	return B_ERROR;
79}
80
81
82status_t
83_BJoystickTweaker::_ScanIncludingDisabled(const char *rootPath, BList *list,
84	BEntry *rootEntry)
85{
86	BDirectory root;
87
88	if (rootEntry != NULL)
89		root.SetTo(rootEntry);
90	else if (rootPath != NULL)
91		root.SetTo(rootPath);
92	else
93		return B_ERROR;
94
95	BEntry entry;
96
97	ASSERT(list != NULL);
98	while (root.GetNextEntry(&entry) == B_OK) {
99		if (entry.IsDirectory()) {
100			status_t result = _ScanIncludingDisabled(rootPath, list, &entry);
101			if (result != B_OK)
102				return result;
103
104			continue;
105		}
106
107		BPath path;
108		status_t result = entry.GetPath(&path);
109		if (result != B_OK)
110			return result;
111
112		BString *deviceName = new(std::nothrow) BString(path.Path());
113		if (deviceName == NULL)
114			return B_NO_MEMORY;
115
116		deviceName->RemoveFirst(rootPath);
117		if (!list->AddItem(deviceName)) {
118			delete deviceName;
119			return B_ERROR;
120		}
121	}
122
123	return B_OK;
124}
125
126
127void
128_BJoystickTweaker::scan_including_disabled()
129{
130	CALLED();
131	_EmpyList(fJoystick->fDevices);
132	_ScanIncludingDisabled(DEVICE_BASE_PATH, fJoystick->fDevices);
133}
134
135
136void
137_BJoystickTweaker::_EmpyList(BList *list)
138{
139	for (int32 i = 0; i < list->CountItems(); i++)
140		delete (BString *)list->ItemAt(i);
141
142	list->MakeEmpty();
143}
144
145
146status_t
147_BJoystickTweaker::get_info()
148{
149	CALLED();
150	return B_ERROR;
151}
152
153
154status_t
155_BJoystickTweaker::GetInfo(_joystick_info *info, const char *ref)
156{
157	CALLED();
158	BString configFilePath(JOYSTICK_CONFIG_BASE_PATH);
159	configFilePath.Append(ref);
160
161	FILE *file = fopen(configFilePath.String(), "r");
162	if (file == NULL)
163		return B_ERROR;
164
165	char line[STACK_STRING_BUFFER_SIZE];
166	while (fgets(line, sizeof(line), file) != NULL) {
167		int length = strlen(line);
168		if (length > 0 && line[length - 1] == '\n')
169			line[length - 1] = '\0';
170
171		_BuildFromJoystickDesc(line, info);
172	}
173
174	fclose(file);
175	return B_OK;
176}
177
178
179void
180_BJoystickTweaker::_BuildFromJoystickDesc(char *string, _joystick_info *info)
181{
182	BString str(string);
183	str.RemoveAll("\"");
184
185	if (str.IFindFirst("module") != -1) {
186		str.RemoveFirst("module = ");
187		strlcpy(info->module_info.module_name, str.String(),
188			STACK_STRING_BUFFER_SIZE);
189	} else if (str.IFindFirst("gadget") != -1) {
190		str.RemoveFirst("gadget = ");
191		strlcpy(info->module_info.device_name, str.String(),
192			STACK_STRING_BUFFER_SIZE);
193	} else if (str.IFindFirst("num_axes") != -1) {
194		str.RemoveFirst("num_axes = ");
195		info->module_info.num_axes = atoi(str.String());
196	} else if (str.IFindFirst("num_hats") != -1) {
197		str.RemoveFirst("num_hats = ");
198		info->module_info.num_hats = atoi(str.String());
199	} else if (str.IFindFirst("num_buttons") != -1) {
200		str.RemoveFirst("num_buttons = ");
201		info->module_info.num_buttons = atoi(str.String());
202	} else if (str.IFindFirst("num_sticks") != -1) {
203		str.RemoveFirst("num_sticks = ");
204		info->module_info.num_sticks = atoi(str.String());
205	} else {
206		LOG("Path = %s\n", str.String());
207	}
208}
209
210
211status_t
212_BJoystickTweaker::SendIOCT(uint32 op)
213{
214	switch (op) {
215		case B_JOYSTICK_SET_DEVICE_MODULE:
216				break;
217
218		case B_JOYSTICK_GET_DEVICE_MODULE:
219				break;
220
221		case B_JOYSTICK_GET_SPEED_COMPENSATION:
222		case B_JOYSTICK_SET_SPEED_COMPENSATION:
223		case B_JOYSTICK_GET_MAX_LATENCY:
224		case B_JOYSTICK_SET_MAX_LATENCY:
225		case B_JOYSTICK_SET_RAW_MODE:
226		default:
227				break;
228	}
229
230	return B_ERROR;
231}
232