diff options
author | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:55:26 +0900 |
---|---|---|
committer | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:55:26 +0900 |
commit | e46d71b5b50b75a254e2c6ef85f197eadb01e882 (patch) | |
tree | af10da61a91a8311c64bd4ddd759280f18a7036e | |
parent | 7d2b59047987c175e355aec8f270da77012e0d0f (diff) | |
download | haptic-module-tizen-e46d71b5b50b75a254e2c6ef85f197eadb01e882.tar.gz haptic-module-tizen-e46d71b5b50b75a254e2c6ef85f197eadb01e882.tar.bz2 haptic-module-tizen-e46d71b5b50b75a254e2c6ef85f197eadb01e882.zip |
-rw-r--r-- | AUTHORS | 2 | ||||
-rwxr-xr-x | CMakeLists.txt | 26 | ||||
-rw-r--r-- | LICENSE.APLv2 | 202 | ||||
-rw-r--r-- | NOTICE | 7 | ||||
-rw-r--r-- | include/haptic_file.h | 75 | ||||
-rwxr-xr-x | include/haptic_module_log.h | 34 | ||||
-rw-r--r-- | packaging/haptic-module-tizen.spec | 43 | ||||
-rw-r--r-- | tizen/DEVICE/CMakeLists.txt | 28 | ||||
-rw-r--r-- | tizen/DEVICE/src/haptic_module_file.c | 351 | ||||
-rw-r--r-- | tizen/DEVICE/src/haptic_module_internal.c | 577 | ||||
-rw-r--r-- | tizen/SIMULATOR/CMakeLists.txt | 27 | ||||
-rw-r--r-- | tizen/SIMULATOR/src/haptic_module_internal.c | 312 |
12 files changed, 1684 insertions, 0 deletions
@@ -0,0 +1,2 @@ +Jiyoung Yun <jy910.yun at samsung dot com> +Jae-young Hwang <j-zero.hwang at samsung dot com> diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..8a62cf9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(haptic-module C) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +FIND_PROGRAM(UNAME NAMES uname) +EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH") + +MESSAGE ("architecture name : ${ARCH}") +MESSAGE ("SIMULATOR: ${SIMULATOR}") +IF("${SIMULATOR}" MATCHES "yes") + SET(TIZEN_TARGET "SIMULATOR") +ELSEIF("${ARCH}" MATCHES "^arm.*") + SET(TIZEN_TARGET "DEVICE") +ELSEIF("${ARCH}" MATCHES ".*86.*") + SET(TIZEN_TARGET "DEVICE") +ELSE("${SIMULATOR}" MATCHES "yes") + MESSAGE(SEND_ERROR "Unknown architecture: ${ARCH}") +ENDIF("${SIMULATOR}" MATCHES "yes") + +ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/tizen/${TIZEN_TARGET}) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..c7f3cb1 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + License APLv2 + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + @@ -0,0 +1,7 @@ +Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License, Version 2 terms and conditions. + +IP Rights Notice: The feature implemented by this module may be intellectual property(ies) of +other entities. Tizen device manufacturers may be required to pay royalty to such entities to +enable the features on their devices diff --git a/include/haptic_file.h b/include/haptic_file.h new file mode 100644 index 0000000..4835946 --- /dev/null +++ b/include/haptic_file.h @@ -0,0 +1,75 @@ +/* + * haptic-module-tizen + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __HAPTIC_FILE_H__ +#define __HAPTIC_FILE_H__ + +#define GCC_PACK __attribute__((packed)) + +/* little-endian form */ +#define mmioHeaderID(ch0,ch1,ch2,ch3) \ + ((unsigned int)(unsigned char)(ch0) | ((unsigned int)(unsigned char)(ch1) << 8) | \ + ((unsigned int)(unsigned char)(ch2) << 16) | ((unsigned int)(unsigned char)(ch3) << 24)) + +#define HEADER_ID mmioHeaderID('T','H','F','M') // 0x4D464854 +#define FMT_ID mmioHeaderID('f','m','t',' ') // 0x20746D66 +#define DATA_ID mmioHeaderID('d','a','t','a') // 0x61746164 + +typedef unsigned int ID; /* a four character code */ + +typedef struct _FormatChunk { + ID chunkID; /* chunk ID */ + int chunkSize; /* chunk Size */ + unsigned short wChannels; /* number of channels (Mono = 1, Stereo = 2, etc.) */ + unsigned short wBlockAlign; /* block size of data (wChannels*1byte) */ + unsigned int dwMagnitude; /* max magnitude */ + unsigned int dwDuration; /* duration */ +} GCC_PACK FormatChunk; + +typedef struct _DataChunk { + ID chunkID; + int chunkSize; + unsigned char pData[]; +} GCC_PACK DataChunk; + +typedef struct _HapticFile { + ID chunkID; /* chunk ID */ + int chunkSize; /* chunk Size */ + FormatChunk fmt; /* Format chunk */ + DataChunk data; /* Data chunk */ +} GCC_PACK HapticFile; + +typedef struct _HapticElement { + int stime; + int duration; +} HapticElement; + +int GetHapticLevelMax(int *max); +int SetHapticEnable(int value); +int SetHapticLevel(int value); +int SetHapticOneshot(int value); + +int InitializeHapticBuffer(unsigned char *vibe_buffer, int max_bufsize); +int InsertHapticElement(unsigned char *vibe_buffer, int max_bufsize, HapticElement *element); +int GetHapticBufferSize(const unsigned char *vibe_buffer, int *size); +int GetHapticBufferDuration(const unsigned char *vibe_buffer, int *duration); +int PlayHapticBuffer(const unsigned char *vibe_buffer, int iteration, int *effect_handle); +int OpenHapticDevice(void); +int CloseHapticDevice(void); + +#endif // __HAPTIC_FIEL_H__ diff --git a/include/haptic_module_log.h b/include/haptic_module_log.h new file mode 100755 index 0000000..87b27e5 --- /dev/null +++ b/include/haptic_module_log.h @@ -0,0 +1,34 @@ +/* + * haptic-module-tizen + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __HAPTIC_MODULE_LOG_H__ +#define __HAPTIC_MODULE_LOG_H__ + +#define FEATURE_HAPTIC_MODULE_DLOG + +#ifdef FEATURE_HAPTIC_MODULE_DLOG + #define LOG_TAG "HAPTIC_MODULE" + #include <dlog.h> + #define MODULE_LOG(fmt, args...) SLOGD(fmt, ##args) + #define MODULE_ERROR(fmt, args...) SLOGE(fmt, ##args) +#else + #define MODULE_LOG(x, ...) + #define MODULE_ERROR(x, ...) +#endif + +#endif //__HAPTIC_MODULE_LOG_H__ diff --git a/packaging/haptic-module-tizen.spec b/packaging/haptic-module-tizen.spec new file mode 100644 index 0000000..0d7437e --- /dev/null +++ b/packaging/haptic-module-tizen.spec @@ -0,0 +1,43 @@ +#sbs-git:slp/pkgs/d/devman devman 0.1.6 5bf2e95e0bb15c43ff928f7375e1978b0accb0f8 +Name: haptic-module-tizen +Summary: Haptic Module library +Version: 0.1.0 +Release: 4 +Group: System/Libraries +License: APLv2 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(haptic-plugin) +BuildRequires: pkgconfig(devman) + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description + +%prep +%setup -q + +%build +%if 0%{?simulator} +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMULATOR=yes +%else +%ifarch %{ix86} +CFLAGS=`echo %{optflags} |sed 's/\-fexceptions//g'` +%endif +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMULATOR=no +%endif +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%{_libdir}/libhaptic-module.so diff --git a/tizen/DEVICE/CMakeLists.txt b/tizen/DEVICE/CMakeLists.txt new file mode 100644 index 0000000..f3fa6d6 --- /dev/null +++ b/tizen/DEVICE/CMakeLists.txt @@ -0,0 +1,28 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(DEPENDENTS "dlog vconf haptic-plugin devman") + +SET(SRCS + src/haptic_module_file.c + src/haptic_module_internal.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(rpkgs REQUIRED ${DEPENDENTS}) + +FOREACH(flag ${rpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--no-as-needed") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS}) + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DENABLE_DLOG_OUT -DSLP_DEBUG") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) diff --git a/tizen/DEVICE/src/haptic_module_file.c b/tizen/DEVICE/src/haptic_module_file.c new file mode 100644 index 0000000..7f9f010 --- /dev/null +++ b/tizen/DEVICE/src/haptic_module_file.c @@ -0,0 +1,351 @@ +/* + * haptic-module-tizen + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <pthread.h> +#include <devman.h> + +#include "haptic_module_log.h" +#include "haptic_file.h" + +#define BITPERMS 50 +#define DEFAULT_EFFECT_HANDLE 0x02 + +typedef struct { + unsigned char **ppbuffer; + int channels; + int length; + int iteration; +} BUFFER; + +static pthread_t tid; +static BUFFER gbuffer; + +static int _check_valid_haptic_format(HapticFile *file) +{ + if (file->chunkID != HEADER_ID) + return -1; + + if (file->fmt.chunkID != FMT_ID) + return -1; + + if (file->data.chunkID != DATA_ID) + return -1; + + return 0; +} + +static int _create_thread(void* data, void*(*func)(void*)) +{ + if (tid) { + MODULE_ERROR("pthread already created"); + return -1; + } + + if (pthread_create(&tid, NULL, func, data) != 0) { + MODULE_ERROR("pthread_create is failed : %s", strerror(errno)); + return -1; + } + + return 0; +} + +static int _cancel_thread(void) +{ + int *ptr = NULL; + int ret = -1; + + if (!tid) { + MODULE_LOG("pthread not initialized"); + return 0; + } + + if ((ret = pthread_cancel(tid)) < 0) { + MODULE_ERROR("pthread_cancel is failed : %s, ret(%d)", strerror(errno), ret); + return -1; + } + + if (pthread_join(tid, (void**)&ptr) < 0) { + tid = 0; + MODULE_ERROR("pthread_join is failed : %s", strerror(errno)); + return -1; + } + + tid = 0; + if (ptr == PTHREAD_CANCELED) { + MODULE_LOG("pthread canceled"); + } else { + MODULE_LOG("pthread already finished"); + } + + return 0; +} + +static void __clean_up(void *arg) +{ + BUFFER *pbuffer = (BUFFER*)arg; + int i = 0; + + MODULE_LOG("clean up handler!!! : %d", tid); + SetHapticEnable(0); + + for (i = 0; i < pbuffer->channels; ++i) { + free(pbuffer->ppbuffer[i]); + pbuffer->ppbuffer[i] = NULL; + } + + free(pbuffer->ppbuffer); + pbuffer->ppbuffer = NULL; + + pbuffer->channels = 0; + pbuffer->length = 0; +} + +static void* __play_cb(void *arg) +{ + BUFFER *pbuffer = (BUFFER*)arg; + int i = -1, j = -1, k = -1, value = -1; + + MODULE_LOG("Start thread"); + + pthread_cleanup_push(__clean_up, arg); + + /* Copy buffer from source buffer */ + for (i = 0; i < pbuffer->iteration; i++) { + for (j = 0; j < pbuffer->length; ++j) { + for (k = 0; k < pbuffer->channels; ++k) { + value = (pbuffer->ppbuffer[k][j] > 0) ? 1 : 0; + if (SetHapticEnable(value) < 0) { + MODULE_ERROR("SetHapticEnable fail"); + pthread_exit((void *)-1); + } + + usleep(BITPERMS * 1000); + } + } + } + + pthread_cleanup_pop(1); + pthread_exit((void *)0); +} + +int GetHapticLevelMax(int *max) +{ + int status = -1; + status = device_get_property(DEVTYPE_HAPTIC, HAPTIC_PROP_LEVEL_MAX, max); + if (status < 0) { + MODULE_ERROR("device_get_property fail : %d", status); + return -1; + } + return 0; +} + +int SetHapticEnable(int value) +{ + int status = -1; + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_ENABLE, value); + if (status < 0) { + MODULE_ERROR("device_set_property fail : %d", status); + return -1; + } + return 0; +} + +int SetHapticLevel(int value) +{ + int status = -1; + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_LEVEL, value); + if (status < 0) { + MODULE_ERROR("device_set_property fail : %d", status); + return -1; + } + return 0; +} + +int SetHapticOneshot(int value) +{ + int status = -1; + status = device_set_property(DEVTYPE_HAPTIC, HAPTIC_PROP_ONESHOT, value); + if (status < 0) { + MODULE_ERROR("device_set_property fail : %d", status); + return -1; + } + return 0; +} + +int InitializeHapticBuffer(unsigned char *vibe_buffer, int max_bufsize) +{ + HapticFile *pfile = NULL; + + if (max_bufsize < sizeof(HapticFile)) { + MODULE_ERROR("buffer lacks a memory : size(%d) minimum size(%d)", max_bufsize, sizeof(HapticFile)); + return -1; + } + + MODULE_LOG("FormatChunk : %d, DataChunk : %d, HapticFile : %d", sizeof(FormatChunk), sizeof(DataChunk), sizeof(HapticFile)); + MODULE_LOG("Bufsize : %d", max_bufsize); + + memset(vibe_buffer, 0, sizeof(char)*max_bufsize); + + pfile = (HapticFile*)vibe_buffer; + + pfile->chunkID = HEADER_ID; + pfile->chunkSize = sizeof(HapticFile); + pfile->fmt.chunkID = FMT_ID; + pfile->fmt.chunkSize = sizeof(FormatChunk); + pfile->fmt.wChannels = 1; + pfile->fmt.wBlockAlign = 1; // wChannels*1byte + pfile->fmt.dwMagnitude = 99; + pfile->fmt.dwDuration = 0; + pfile->data.chunkID = DATA_ID; + pfile->data.chunkSize = sizeof(DataChunk); + return 0; +} + +int InsertHapticElement(unsigned char *vibe_buffer, int max_bufsize, HapticElement *element) +{ + HapticFile *pfile = NULL; + int databuf = -1; + int needbuf = -1; + int stime, duration; + int i = -1, j = -1; + + pfile = (HapticFile*)vibe_buffer; + if (_check_valid_haptic_format(pfile) < 0) { + MODULE_ERROR("this buffer is not HapticFormat"); + return -1; + } + + stime = element->stime/BITPERMS; + duration = element->duration/BITPERMS; + + databuf = max_bufsize-sizeof(HapticFile); + needbuf = (stime+duration)*pfile->fmt.wBlockAlign; + MODULE_LOG("Data buffer size : %d, Need buffer size : %d", databuf, needbuf); + + if (databuf < needbuf) { + MODULE_ERROR("buffer lacks a memory : data buf(%d), need buf(%d)", databuf, needbuf); + return -1; + } + + for (i = 0, j = stime; i < duration; ++i, j+=pfile->fmt.wBlockAlign) { + pfile->data.pData[j] = 0xFF; + } + + pfile->chunkSize = sizeof(HapticFile)+needbuf; + pfile->fmt.dwDuration = element->stime+element->duration; + pfile->data.chunkSize = sizeof(DataChunk)+needbuf; + return 0; +} + +int GetHapticBufferSize(const unsigned char *vibe_buffer, int *size) +{ + HapticFile *pfile = NULL; + + pfile = (HapticFile*)vibe_buffer; + if (_check_valid_haptic_format(pfile) < 0) { + MODULE_ERROR("this buffer is not HapticFormat"); + return -1; + } + + *size = pfile->chunkSize; + return 0; +} + +int GetHapticBufferDuration(const unsigned char *vibe_buffer, int *duration) +{ + HapticFile *pfile = NULL; + + pfile = (HapticFile*)vibe_buffer; + if (_check_valid_haptic_format(pfile) < 0) { + MODULE_ERROR("this buffer is not HapticFormat"); + return -1; + } + + *duration = pfile->fmt.dwDuration; + return 0; +} + +int PlayHapticBuffer(const unsigned char *vibe_buffer, int iteration, int *effect_handle) +{ + HapticFile *pfile = NULL; + unsigned char **ppbuffer = NULL; + unsigned int channels, length, align, magnitude; + int i = -1, j = -1; + + pfile = (HapticFile*)vibe_buffer; + if (_check_valid_haptic_format(pfile) < 0) { + MODULE_ERROR("this buffer is not HapticFormat"); + return -1; + } + + /* Temporary code + This code does not support handle and multi channel concept. + Only this code adds to test for playing file. */ + + if (_cancel_thread() < 0) { + MODULE_ERROR("_cancel_thread fail"); + return -1; + } + + channels = pfile->fmt.wChannels; + align = pfile->fmt.wBlockAlign; + length = (pfile->data.chunkSize-8)/align; + magnitude = pfile->fmt.dwMagnitude; + MODULE_LOG("channels : %d, length : %d, align : %d, magnitude : %d", channels, length, align, magnitude); + + /* Create buffer */ + ppbuffer = (unsigned char**)malloc(sizeof(unsigned char*)*channels); + for (i = 0; i < channels; ++i) { + ppbuffer[i] = (unsigned char*)malloc(sizeof(unsigned char)*length); + memset(ppbuffer[i], 0, sizeof(unsigned char)*length); + } + + /* Copy buffer from source buffer */ + for (i = 0; i < length; ++i) { + for (j = 0; j < channels; ++j) { + ppbuffer[j][i] = (unsigned char)(pfile->data.pData[i*align+j]); + } + } + + gbuffer.ppbuffer = ppbuffer; + gbuffer.channels = channels; + gbuffer.length = length; + gbuffer.iteration = iteration; + + /* Start thread */ + if (_create_thread(&gbuffer, __play_cb) < 0) { + MODULE_ERROR("_create_thread fail"); + return -1; + } + + *effect_handle = DEFAULT_EFFECT_HANDLE; + return 0; +} + +int CloseHapticDevice(void) +{ + if (_cancel_thread() < 0) { + MODULE_ERROR("_cancel_thread fail"); + return -1; + } + return 0; +} diff --git a/tizen/DEVICE/src/haptic_module_internal.c b/tizen/DEVICE/src/haptic_module_internal.c new file mode 100644 index 0000000..16c15eb --- /dev/null +++ b/tizen/DEVICE/src/haptic_module_internal.c @@ -0,0 +1,577 @@ +/* + * haptic-module-tizen + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <assert.h> + +#include <haptic_plugin_intf.h> +#include "haptic_module_log.h" +#include "haptic_file.h" + +#ifndef EXTAPI +#define EXTAPI __attribute__ ((visibility("default"))) +#endif + +#define DEFAULT_MOTOR_COUNT 1 +#define DEFAULT_DEVICE_HANDLE 0x01 +#define DEFAULT_EFFECT_HANDLE 0x02 + +#define HAPTIC_PLAY_FILE_EXT ".tht" + +/* START of Static Function Section */ +static int __feedback_to_tizen_type(int feedback) +{ + static int max = -1; + int status = -1; + + if (max < 0) { + status = GetHapticLevelMax(&max); + if (status < 0) { + MODULE_ERROR("GetHapticLevelMax fail : %d", status); + return -1; + } + } + + MODULE_LOG("feedback value is changed : %d -> %d", feedback, (int)(feedback*max/HAPTIC_MODULE_FEEDBACK_MAX)); + return (int)(feedback*max/HAPTIC_MODULE_FEEDBACK_MAX); +} + +static char* __check_file (const char *name) +{ + char *file_full_name = NULL; + int name_length = -1; + char match_ext[4]; + char *file_ext = NULL; + + assert(name); + assert(*name); + + file_full_name = strdup(name); + if (!file_full_name) { + MODULE_ERROR("strdup failed"); + return NULL; + } + + name_length = strlen(file_full_name) - 1; + while (file_full_name[name_length] == ' ') + name_length--; + file_full_name[name_length + 1] = '\0'; + + file_ext = strrchr(file_full_name, '.'); + if (!(file_ext && !strcmp(file_ext, HAPTIC_PLAY_FILE_EXT))) { + free(file_full_name); + MODULE_ERROR("Not supported file"); + return NULL; + } + + return file_full_name; +} + +static unsigned char* __convert_file_to_vibe_buffer(const char *file_name) +{ + char *file_full_name; + FILE *pf; + long file_size; + unsigned char* pIVTData; + + if (!file_name) { + MODULE_ERROR("Wrowng file name"); + return NULL; + } + + file_full_name = __check_file(file_name); + if(!file_full_name) { + MODULE_ERROR("__check_file_faild"); + return NULL; + } + + /* Get File Stream Pointer */ + pf = fopen(file_full_name, "rb"); + free(file_full_name); + if (!pf) { + MODULE_ERROR("file open failed"); + return NULL; + } + + if (fseek(pf, 0, SEEK_END)) { + MODULE_ERROR("fseek failed"); + fclose(pf); + return NULL; + } + + file_size = ftell(pf); + if (file_size < 0) { + MODULE_ERROR("ftell failed"); + fclose(pf); + return NULL; + } + + if (fseek(pf, 0, SEEK_SET)) { + MODULE_ERROR("fseek failed"); + fclose(pf); + return NULL; + } + + pIVTData = (unsigned char*)malloc(file_size); + if (!pIVTData) { + fclose(pf); + return NULL; + } + + if (fread(pIVTData, 1, file_size, pf) != file_size) { + fclose(pf); + free(pIVTData); + MODULE_ERROR("fread failed"); + return NULL; + } + + fclose(pf); + return pIVTData; +} +/* END of Static Function Section */ + +int haptic_internal_get_device_count(int *count) +{ + if (count == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + *count = DEFAULT_MOTOR_COUNT; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_open_device(int device_index, int *device_handle) +{ + if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (device_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + *device_handle = DEFAULT_DEVICE_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_close_device(int device_handle) +{ + int status = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = CloseHapticDevice(); + if (status < 0) { + MODULE_ERROR("CloseHapticDevice fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + status = SetHapticEnable(0); + if (status < 0) { + MODULE_ERROR("SetHapticEnable fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) +{ + int status = -1; + int input_feedback = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (duration < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + input_feedback = __feedback_to_tizen_type(feedback); + if (input_feedback < 0) + return HAPTIC_MODULE_OPERATION_FAILED; + + status = SetHapticLevel(input_feedback); + if (status < 0) { + MODULE_ERROR("SetHapticLevel fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + status = SetHapticOneshot(duration); + if (status < 0) { + MODULE_ERROR("SetHapticOneshot fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + *effect_handle = DEFAULT_EFFECT_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle) +{ + int status = -1; + unsigned char *vibe_buffer = NULL; + int input_feedback = -1; + int handle = -1; + int i = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + input_feedback = __feedback_to_tizen_type(feedback); + if (input_feedback < 0) + return HAPTIC_MODULE_OPERATION_FAILED; + + status = SetHapticLevel(input_feedback); + if (status < 0) { + MODULE_ERROR("SetHapticLevel fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + vibe_buffer = __convert_file_to_vibe_buffer(file_path); + if (!vibe_buffer) { + MODULE_ERROR("File load filed"); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + status = PlayHapticBuffer(vibe_buffer, iteration, &handle); + if (status < 0) { + MODULE_ERROR("PlayHapticBuffer fail: %d", status); + free(vibe_buffer); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + *effect_handle = handle; + free(vibe_buffer); + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) +{ + int status = -1; + int input_feedback = -1; + int handle = -1; + int i = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + input_feedback = __feedback_to_tizen_type(feedback); + if (input_feedback < 0) + return HAPTIC_MODULE_OPERATION_FAILED; + + status = SetHapticLevel(input_feedback); + if (status < 0) { + MODULE_ERROR("SetHapticLevel fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + status = PlayHapticBuffer(vibe_buffer, iteration, &handle); + if (status < 0) { + MODULE_ERROR("PlayHapticBuffer fail: %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + *effect_handle = handle; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_stop_effect(int device_handle, int effect_handle) +{ + int status = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = SetHapticEnable(0); + if (status < 0) { + MODULE_ERROR("SetHapticEnable fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_stop_all_effects(int device_handle) +{ + int status = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = SetHapticEnable(0); + if (status < 0) { + MODULE_ERROR("SetHapticEnable fail : %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_pause_effect(int device_handle, int effect_handle) +{ + MODULE_ERROR("This device is not supported this function(%s)", __func__); + return HAPTIC_MODULE_NOT_SUPPORTED; +} + +int haptic_internal_resume_effect(int device_handle, int effect_handle) +{ + MODULE_ERROR("This device is not supported this function(%s)", __func__); + return HAPTIC_MODULE_NOT_SUPPORTED; +} + +int haptic_internal_get_effect_state(int device_handle, int effect_handle, int *state) +{ + MODULE_ERROR("This device is not supported this function(%s)", __func__); + return HAPTIC_MODULE_NOT_SUPPORTED; +} + +int haptic_internal_create_effect(unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_element) +{ + int status = -1; + HapticElement elem; + int i = -1; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_bufsize < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (elem_arr == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_element < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = InitializeHapticBuffer(vibe_buffer, max_bufsize); + if (status < 0) { + MODULE_ERROR("InitializeHapticBuffer fail: %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + MODULE_LOG("effect count : %d", max_element); + for (i = 0; i < max_element; ++i) { + elem.stime = elem_arr[i].haptic_stime; + elem.duration = elem_arr[i].haptic_duration; + MODULE_LOG("%d) time : %d, duration : %d", i, elem_arr[i].haptic_stime, elem_arr[i].haptic_duration); + + status = InsertHapticElement(vibe_buffer, max_bufsize, &elem); + if (status < 0) { + MODULE_ERROR("InsertHapticElement fail: %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + } + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path) +{ + int status = -1; + FILE *file = NULL; + int fd = -1; + int size = -1; + int ret; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_bufsize < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = GetHapticBufferSize(vibe_buffer, &size); + if (status < 0) { + MODULE_ERROR("GetHapticBufferSize fail: %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + file = fopen(file_path, "wb"); + if (file == NULL) { + MODULE_ERROR("To open file is failed"); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + ret = fwrite(vibe_buffer, 1, size, file); + if (ret != size) { + MODULE_ERROR("To write file is failed"); + fclose(file); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + fd = fileno(file); + if (fd < 0) { + MODULE_ERROR("To get file descriptor is failed"); + fclose(file); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + if (fsync(fd) < 0) { + MODULE_ERROR("To be synchronized with the disk is failed"); + fclose(file); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + fclose(file); + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_get_file_duration(int device_handle, const char *file_path, int *file_duration) +{ + int status = -1; + unsigned char *vibe_buffer = NULL; + int duration = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_duration == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + vibe_buffer = __convert_file_to_vibe_buffer(file_path); + if (!vibe_buffer) { + MODULE_ERROR("File load filed"); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + status = GetHapticBufferDuration(vibe_buffer, &duration); + if (status < 0) { + MODULE_ERROR("GetHapticBufferDuration fail: %d", status); + free(vibe_buffer); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + *file_duration = duration; + free(vibe_buffer); + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration) +{ + int status = -1; + int duration = -1; + + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (buffer_duration == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + status = GetHapticBufferDuration(vibe_buffer, &duration); + if (status < 0) { + MODULE_ERROR("GetHapticBufferDuration fail: %d", status); + return HAPTIC_MODULE_OPERATION_FAILED; + } + + *buffer_duration = duration; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_convert_binary (void) +{ + MODULE_ERROR("This device is not supported this function(%s)", __func__); + return HAPTIC_MODULE_NOT_SUPPORTED; +} + +static haptic_plugin_interface haptic_plugin_tizen; + +EXTAPI +const haptic_plugin_interface *get_haptic_plugin_interface() +{ + haptic_plugin_tizen.haptic_internal_get_device_count= &haptic_internal_get_device_count; + haptic_plugin_tizen.haptic_internal_open_device = &haptic_internal_open_device; + haptic_plugin_tizen.haptic_internal_close_device = &haptic_internal_close_device; + haptic_plugin_tizen.haptic_internal_vibrate_monotone= &haptic_internal_vibrate_monotone; + haptic_plugin_tizen.haptic_internal_vibrate_file = &haptic_internal_vibrate_file; + haptic_plugin_tizen.haptic_internal_vibrate_buffer = &haptic_internal_vibrate_buffer; + haptic_plugin_tizen.haptic_internal_stop_effect = &haptic_internal_stop_effect; + haptic_plugin_tizen.haptic_internal_stop_all_effects= &haptic_internal_stop_all_effects; + haptic_plugin_tizen.haptic_internal_pause_effect = &haptic_internal_pause_effect; + haptic_plugin_tizen.haptic_internal_resume_effect = &haptic_internal_resume_effect; + haptic_plugin_tizen.haptic_internal_get_effect_state= &haptic_internal_get_effect_state; + haptic_plugin_tizen.haptic_internal_create_effect = &haptic_internal_create_effect; + haptic_plugin_tizen.haptic_internal_save_effect = &haptic_internal_save_effect; + haptic_plugin_tizen.haptic_internal_get_file_duration = &haptic_internal_get_file_duration; + haptic_plugin_tizen.haptic_internal_get_buffer_duration = &haptic_internal_get_buffer_duration; + haptic_plugin_tizen.haptic_internal_convert_binary = &haptic_internal_convert_binary; + + return &haptic_plugin_tizen; +} diff --git a/tizen/SIMULATOR/CMakeLists.txt b/tizen/SIMULATOR/CMakeLists.txt new file mode 100644 index 0000000..41d821a --- /dev/null +++ b/tizen/SIMULATOR/CMakeLists.txt @@ -0,0 +1,27 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(DEPENDENTS "dlog vconf haptic-plugin devman") + +SET(SRCS + src/haptic_module_internal.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(rpkgs REQUIRED ${DEPENDENTS}) + +FOREACH(flag ${rpkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,--no-as-needed") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${rpkgs_LDFLAGS}) + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DENABLE_DLOG_OUT -DSLP_DEBUG") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) diff --git a/tizen/SIMULATOR/src/haptic_module_internal.c b/tizen/SIMULATOR/src/haptic_module_internal.c new file mode 100644 index 0000000..732ba07 --- /dev/null +++ b/tizen/SIMULATOR/src/haptic_module_internal.c @@ -0,0 +1,312 @@ +/* + * haptic-module-tizen + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <haptic_plugin_intf.h> +#include "haptic_module_log.h" + +#ifndef EXTAPI +#define EXTAPI __attribute__ ((visibility("default"))) +#endif + +#define DEFAULT_MOTOR_COUNT 1 +#define DEFAULT_DEVICE_HANDLE 0x01 +#define DEFAULT_EFFECT_HANDLE 0x02 + +int haptic_internal_get_device_count(int *count) +{ + if (count == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + *count = DEFAULT_MOTOR_COUNT; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_open_device(int device_index, int *device_handle) +{ + if (device_index < HAPTIC_MODULE_DEVICE_0 || device_index > HAPTIC_MODULE_DEVICE_ALL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (device_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + *device_handle = DEFAULT_DEVICE_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_close_device(int device_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_monotone(int device_handle, int duration, int feedback, int priority, int *effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (duration < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + MODULE_LOG("call %s function", __func__); + + *effect_handle = DEFAULT_EFFECT_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_file(int device_handle, const char *file_path, int iteration, int feedback, int priority, int *effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + MODULE_LOG("call %s function", __func__); + + *effect_handle = DEFAULT_EFFECT_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_vibrate_buffer(int device_handle, const unsigned char *vibe_buffer, int iteration, int feedback, int priority, int *effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (iteration < HAPTIC_MODULE_ITERATION_ONCE || iteration > HAPTIC_MODULE_ITERATION_INFINITE) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback < HAPTIC_MODULE_FEEDBACK_MIN || feedback > HAPTIC_MODULE_FEEDBACK_MAX) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (priority < HAPTIC_MODULE_PRIORITY_MIN || priority > HAPTIC_MODULE_PRIORITY_HIGH) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (feedback == HAPTIC_MODULE_FEEDBACK_MIN) + return HAPTIC_MODULE_ERROR_NONE; + + MODULE_LOG("call %s function", __func__); + + *effect_handle = DEFAULT_EFFECT_HANDLE; + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_stop_effect(int device_handle, int effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_stop_all_effects(int device_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_pause_effect(int device_handle, int effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_resume_effect(int device_handle, int effect_handle) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_get_effect_state(int device_handle, int effect_handle, int *effect_state) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (effect_state == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_create_effect(const unsigned char *vibe_buffer, int max_bufsize, haptic_module_effect_element *elem_arr, int max_elemcnt) +{ + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_bufsize < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (elem_arr == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_elemcnt < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_save_effect(const unsigned char *vibe_buffer, int max_bufsize, const char *file_path) +{ + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (max_bufsize < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_get_file_duration(int device_handle, const char *file_path, int *file_duration) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_path == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (file_duration == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_get_buffer_duration(int device_handle, const unsigned char *vibe_buffer, int *buffer_duration) +{ + if (device_handle < 0) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (vibe_buffer == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + if (buffer_duration == NULL) + return HAPTIC_MODULE_INVALID_ARGUMENT; + + MODULE_LOG("call %s function", __func__); + + return HAPTIC_MODULE_ERROR_NONE; +} + +int haptic_internal_convert_binary (void) +{ + MODULE_ERROR("This device is not supported this function(%s)", __func__); + return HAPTIC_MODULE_NOT_SUPPORTED; +} + +static haptic_plugin_interface haptic_plugin_emul; + +EXTAPI +const haptic_plugin_interface *get_haptic_plugin_interface() +{ + haptic_plugin_emul.haptic_internal_get_device_count = &haptic_internal_get_device_count; + haptic_plugin_emul.haptic_internal_open_device = &haptic_internal_open_device; + haptic_plugin_emul.haptic_internal_close_device = &haptic_internal_close_device; + haptic_plugin_emul.haptic_internal_vibrate_monotone = &haptic_internal_vibrate_monotone; + haptic_plugin_emul.haptic_internal_vibrate_file = &haptic_internal_vibrate_file; + haptic_plugin_emul.haptic_internal_vibrate_buffer = &haptic_internal_vibrate_buffer; + haptic_plugin_emul.haptic_internal_stop_effect = &haptic_internal_stop_effect; + haptic_plugin_emul.haptic_internal_stop_all_effects = &haptic_internal_stop_all_effects; + haptic_plugin_emul.haptic_internal_pause_effect = &haptic_internal_pause_effect; + haptic_plugin_emul.haptic_internal_resume_effect = &haptic_internal_resume_effect; + haptic_plugin_emul.haptic_internal_get_effect_state = &haptic_internal_get_effect_state; + haptic_plugin_emul.haptic_internal_create_effect = &haptic_internal_create_effect; + haptic_plugin_emul.haptic_internal_save_effect = &haptic_internal_save_effect; + haptic_plugin_emul.haptic_internal_get_file_duration = &haptic_internal_get_file_duration; + haptic_plugin_emul.haptic_internal_get_buffer_duration = &haptic_internal_get_buffer_duration; + haptic_plugin_emul.haptic_internal_convert_binary = &haptic_internal_convert_binary; + + return &haptic_plugin_emul; +} |