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
27 inline void
LOG(const char * fmt,...)28 LOG(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)
40 FILE *_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
_BJoystickTweaker()49 _BJoystickTweaker::_BJoystickTweaker()
50 {
51 #if DEBUG
52 sLogFile = fopen("/var/log/joystick.log", "a");
53 #endif
54 CALLED();
55 }
56
57
_BJoystickTweaker(BJoystick & stick)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
~_BJoystickTweaker()69 _BJoystickTweaker::~_BJoystickTweaker()
70 {
71 }
72
73
74 status_t
save_config(const entry_ref * ref)75 _BJoystickTweaker::save_config(const entry_ref *ref)
76 {
77 CALLED();
78 return B_ERROR;
79 }
80
81
82 status_t
_ScanIncludingDisabled(const char * rootPath,BList * list,BEntry * rootEntry)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
127 void
scan_including_disabled()128 _BJoystickTweaker::scan_including_disabled()
129 {
130 CALLED();
131 _EmpyList(fJoystick->fDevices);
132 _ScanIncludingDisabled(DEVICE_BASE_PATH, fJoystick->fDevices);
133 }
134
135
136 void
_EmpyList(BList * list)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
146 status_t
get_info()147 _BJoystickTweaker::get_info()
148 {
149 CALLED();
150 return B_ERROR;
151 }
152
153
154 status_t
GetInfo(_joystick_info * info,const char * ref)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
179 void
_BuildFromJoystickDesc(char * string,_joystick_info * info)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
211 status_t
SendIOCT(uint32 op)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