2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
25 #include <devman_haptic.h>
29 #include "haptic_private.h"
32 #define LOG_TAG "TIZEN_SYSTEM_HAPTIC"
34 #define NOT_ASSIGNED -1
35 #define VIBE_SILENCE -128
37 #define _MSG_HAPTIC_ERROR_INVALID_PARAMETER "Invalid parameter"
38 #define _MSG_HAPTIC_ERROR_NO_SUCH_FILE "No such file"
39 #define _MSG_HAPTIC_ERROR_NOT_SUPPORTED_FORMAT "Not supported format"
40 #define _MSG_HAPTIC_ERROR_NOT_INITIALIZED "Not initialize"
41 #define _MSG_HAPTIC_ERROR_OPERATION_FAILED "Operation failed"
43 #define RETURN_ERR_MSG(err_code, msg) \
45 LOGE("[%s] "_MSG_##err_code"(0x%08x) : %s", __FUNCTION__, err_code, msg); \
49 #define RETURN_ERR(err_code) \
51 LOGE("[%s] "_MSG_##err_code"(0x%08x)", __FUNCTION__, err_code); \
63 HAPTIC_FEEDBACK_LEVEL_AUTO,
65 HAPTIC_FEEDBACK_LEVEL_1,
66 HAPTIC_FEEDBACK_LEVEL_2,
67 HAPTIC_FEEDBACK_LEVEL_3,
68 HAPTIC_FEEDBACK_LEVEL_4,
69 HAPTIC_FEEDBACK_LEVEL_5,
72 struct _vibe_pattern {
73 haptic_vibration_iter_s *iters;
83 GArray *pattern_table = NULL;
85 static int initialize = 0;
86 static int max_device = 0;
88 static int* haptic_ids = NULL;
90 static void _free_pattern_from_table(int index);
92 static bool invalid_ivt(const char* file_name)
94 if( 0 != access(file_name, R_OK) )
99 char* ext = strrchr(file_name, '.');
100 if (ext == NULL || 0 != strcasecmp(ext, ".ivt")){
107 int haptic_get_count(int* vibrator_number)
110 if(vibrator_number == NULL)
111 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
113 count = device_haptic_get_device_count();
115 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
117 *vibrator_number = count;
119 return HAPTIC_ERROR_NONE;
122 int haptic_initialize()
127 if( haptic_get_count(&max_device) < 0)
128 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
130 haptic_ids = (int*)malloc(sizeof(int)*max_device+1); // max + zero
132 if(haptic_ids == NULL){
133 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
136 for(i=0; i<=max_device; i++){
137 id = device_haptic_open(_DEV[i], 0);
139 for (j=i; i>=0; i--){
140 device_haptic_close(_DEV[i]);
142 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
150 pattern_table = g_array_new(FALSE, TRUE, sizeof(struct _vibe_pattern*));
154 return HAPTIC_ERROR_NONE;
157 int haptic_deinitialize()
162 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
164 for(i=0; i<=max_device; i++){
165 err = device_haptic_close(_DEV[i]);
169 if(haptic_ids != NULL)
172 for(i=0; i< pattern_table->len; i++){
173 _free_pattern_from_table(i);
175 g_array_free(pattern_table, TRUE);
179 return HAPTIC_ERROR_NONE;
183 int haptic_get_file_duration(int device_index, const char *file_name , int* duration)
188 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
190 if(device_index < 0 || device_index > max_device)
191 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
193 device_index = ((device_index < 3) ? _DEV[device_index] : DEV_IDX_ALL); // xxx
195 if(!invalid_ivt(file_name))
196 RETURN_ERR(HAPTIC_ERROR_NOT_SUPPORTED_FORMAT);
198 ret = device_haptic_get_file_duration(haptic_ids[device_index], file_name, duration);
202 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
204 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
207 return HAPTIC_ERROR_NONE;
210 int haptic_vibrate_file(int device_index, const char *file_name , int count , haptic_level_e level)
214 if(device_index < 0 || device_index > max_device)
215 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
217 device_index = ((device_index < 3) ? _DEV[device_index] : DEV_IDX_ALL); // xxx
220 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
222 if(level == VIBE_SILENCE)
223 return HAPTIC_ERROR_NONE;
225 if(level > HAPTIC_LEVEL_5 || level < 0)
226 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
228 if(count < 0 || count >= HAPTIC_INFINITE_ITERATION)
229 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
232 count = HAPTIC_INFINITE_ITERATION;
234 if(!invalid_ivt(file_name))
235 RETURN_ERR(HAPTIC_ERROR_NOT_SUPPORTED_FORMAT);
237 ret = device_haptic_play_file(haptic_ids[device_index], file_name, count, _LEVEL[level]);
241 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
243 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
246 return HAPTIC_ERROR_NONE;
249 int haptic_vibrate_monotone(int device_index , int duration)
253 if(device_index < 0 || device_index > max_device)
254 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
256 device_index = ((device_index < 3) ? _DEV[device_index] : DEV_IDX_ALL); // xxx
259 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
261 ret = device_haptic_play_monotone(haptic_ids[device_index], duration);
265 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
267 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
270 return HAPTIC_ERROR_NONE;
273 int haptic_stop_device(int device_index)
277 if(device_index < 0 || device_index > max_device)
278 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
280 device_index = ((device_index < 3) ? _DEV[device_index] : DEV_IDX_ALL); // xxx
283 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
285 ret = device_haptic_stop_play(haptic_ids[device_index]);
289 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
291 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
294 return HAPTIC_ERROR_NONE;
297 static void _free_pattern_from_table(int index)
299 struct _vibe_pattern* p = g_array_index(pattern_table, struct _vibe_pattern *, index);
304 g_array_index(pattern_table, struct _vibe_pattern *, index) = NULL;
307 static gboolean _haptic_play_iter(gpointer data)
310 struct _vibe_pattern* pattern = (struct _vibe_pattern*)data;
313 _free_pattern_from_table(pattern->pattern_index);
316 int current = pattern->current;
318 int device = pattern->iters[current].vibrator_index;
319 int level = pattern->iters[current].level;
320 long time = pattern->iters[current].time;
321 int level_change = pattern->level_change;
322 int iter_count = pattern->iter_count;
324 // set default device, if can't find given device.
325 if(device >= max_device || device < 0)
328 if(level + level_change < HAPTIC_LEVEL_0)
329 level = HAPTIC_LEVEL_0;
330 if(level + level_change > HAPTIC_LEVEL_5)
331 level = HAPTIC_LEVEL_5;
333 if(level != HAPTIC_LEVEL_0 || time != 0){
334 // err = _haptic_play_monotone(device, time, level);
335 err = haptic_vibrate_monotone(device, time);
337 pattern->error = err;
344 // pattern play finish
345 if(pattern->current >= pattern->size){
347 _free_pattern_from_table(pattern->pattern_index);
350 pattern->current = 0;
351 pattern->iter_count--;
356 g_timeout_add(time, _haptic_play_iter, data);
361 int haptic_play_pattern(haptic_vibration_iter_s* pattern, int pattern_size, int count, int level_change, int* id)
366 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
369 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
372 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
374 haptic_vibration_iter_s* tmp_ptn = (haptic_vibration_iter_s*)
375 malloc(sizeof(haptic_vibration_iter_s) * pattern_size);
377 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
379 memcpy(tmp_ptn, pattern, sizeof(haptic_vibration_iter_s) * pattern_size);
381 struct _vibe_pattern* vibe_p = (struct _vibe_pattern*)malloc(sizeof(struct _vibe_pattern));
384 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
386 vibe_p->iters = tmp_ptn;
387 vibe_p->size = pattern_size;
388 vibe_p->level_change = level_change;
389 vibe_p->iter_count = count;
394 for(i=0; i< pattern_table->len; i++){
395 if(g_array_index(pattern_table, struct _vibe_pattern *, i) == NULL){
401 g_array_append_val(pattern_table, vibe_p);
402 key = pattern_table->len -1;
404 g_array_index(pattern_table, struct _vibe_pattern *, key) = vibe_p;
407 vibe_p->pattern_index = key;
409 _haptic_play_iter((gpointer)vibe_p);
411 if(vibe_p->error < 0){
412 _free_pattern_from_table(key);
413 if(vibe_p->error == -2)
414 RETURN_ERR(HAPTIC_ERROR_OPERATION_FAILED);
416 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
421 return HAPTIC_ERROR_NONE;
424 int haptic_stop_pattern(int id)
427 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
429 if(!initialize || pattern_table == NULL)
430 RETURN_ERR(HAPTIC_ERROR_NOT_INITIALIZED);
432 if(id >= pattern_table->len)
433 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
435 struct _vibe_pattern* pattern = g_array_index(pattern_table, struct _vibe_pattern *, id);
439 RETURN_ERR(HAPTIC_ERROR_INVALID_PARAMETER);
441 return HAPTIC_ERROR_NONE;