f47a0fc2b614e6d26342a6bd4289fef2c898a3f7
[framework/telephony/libslp-tapi.git] / wearable / test_src / menu.c
1 /*
2  * Telephony test application
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #define _GNU_SOURCE
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <glib.h>
27 #include <asm/unistd.h>
28 #include <unistd.h>
29 #include <sys/syscall.h>
30
31 #include "menu.h"
32
33 #define DEFAULT_MENU_MENU       "m"
34 #define DEFAULT_MENU_PREV       "p"
35 #define DEFAULT_MENU_QUIT       "q"
36 #define DEFAULT_MENU_NONE       "-"
37
38
39 struct menu_manager {
40         GQueue *stack;
41         GQueue *title_stack;
42
43         struct menu_data *menu;
44
45         char *buf;
46
47         void *user_data;
48         GMainLoop *mainloop;
49 };
50
51
52 char key_buffer[MENU_DATA_SIZE];
53 int flag_pid_display = 1;
54
55
56 static void _show_prompt (void)
57 {
58         msgn ("(%5d) >> ", get_tid ());
59 }
60
61 static void _show_reserved_menu (void)
62 {
63         msg (ANSI_COLOR_DARKGRAY HR_SINGLE2 ANSI_COLOR_NORMAL);
64         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
65                         " ] " ANSI_COLOR_NORMAL "Previous menu " , DEFAULT_MENU_PREV);
66         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
67                         " ] " ANSI_COLOR_NORMAL "Show Menu " , DEFAULT_MENU_MENU);
68         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
69                         " ] " ANSI_COLOR_NORMAL "Quit " , DEFAULT_MENU_QUIT);
70 }
71
72 static void _show_input_ok (void)
73 {
74         msg ("OK.");
75 }
76
77 static void _show_menu (MManager *m, struct menu_data menu[])
78 {
79         int i = 0;
80         int len = 0;
81         struct menu_data *item;
82         char title_buf[256] = { 0, };
83
84         if (!menu)
85                 return;
86
87         msg ("");
88         msg (HR_DOUBLE);
89
90         len = g_queue_get_length (m->title_stack);
91         msgn (ANSI_COLOR_YELLOW " Main");
92         if (len > 0) {
93                 for (i = 0; i < len; i++) {
94                         msgn (ANSI_COLOR_NORMAL " >> " ANSI_COLOR_YELLOW "%s",
95                                         (char *) g_queue_peek_nth (m->title_stack, i));
96                 }
97         }
98         msg (ANSI_COLOR_NORMAL);
99         msg (HR_SINGLE);
100
101         hide_pid();
102         i = 0;
103
104         while (1) {
105                 item = menu + i;
106                 if (item->key == NULL)
107                         break;
108
109                 if (!g_strcmp0 (item->key, "-")) {
110                         msgn ("       ");
111                 }
112                 else if (!g_strcmp0 (item->key, "_")) {
113                         msg (ANSI_COLOR_DARKGRAY HR_SINGLE2 ANSI_COLOR_NORMAL);
114
115                         if (item->callback)
116                                 item->callback (m, item);
117
118                         i++;
119
120                         continue;
121                 }
122                 else if (!g_strcmp0 (item->key, "*")) {
123                         msg (" %s", item->title);
124                         if (item->callback)
125                                 item->callback (m, item);
126                 }
127                 else {
128                         msgn (ANSI_COLOR_DARKGRAY " [" ANSI_COLOR_NORMAL "%3s"
129                                         ANSI_COLOR_DARKGRAY "] " ANSI_COLOR_NORMAL,     item->key);
130                 }
131
132                 memset (title_buf, 0, 256);
133                 if (item->title) {
134                         snprintf (title_buf, MAX_TITLE, "%s", item->title);
135
136                         if (strlen (item->title) >= MAX_TITLE) {
137                                 title_buf[MAX_TITLE - 2] = '.';
138                                 title_buf[MAX_TITLE - 1] = '.';
139                         }
140                 }
141
142                 if (item->data) {
143                         msg ("%s " ANSI_COLOR_LIGHTBLUE "(%s)" ANSI_COLOR_NORMAL,
144                                         title_buf, item->data);
145                 }
146                 else if (!g_strcmp0 (item->key, "*")) {
147                         /* none */
148                 }
149                 else {
150                         msg ("%s", title_buf);
151                 }
152
153                 if (item->sub_menu) {
154                         msg ("\e[1A\e[%dC >", POS_MORE);
155                 }
156
157                 i++;
158         }
159
160         show_pid();
161
162         _show_reserved_menu();
163
164         msg (HR_DOUBLE);
165
166         _show_prompt();
167 }
168
169 static void _show_item_data_input_msg (struct menu_data *item)
170 {
171         msg ("");
172         msg (HR_DOUBLE);
173         msg (" Input [%s] data ", item->title);
174         msg (HR_SINGLE);
175         msg (" current = [%s]", item->data);
176         msgn (" new >> ");
177 }
178
179 static void _move_menu (MManager *mm, struct menu_data menu[], char *key)
180 {
181         struct menu_data *item;
182         int i = 0;
183
184         if (!mm->menu)
185                 return;
186
187         if (!g_strcmp0 (DEFAULT_MENU_PREV, key)) {
188                 if (g_queue_get_length (mm->stack) > 0) {
189                         mm->menu = g_queue_pop_tail (mm->stack);
190                         g_queue_pop_tail (mm->title_stack);
191                 }
192
193                 _show_menu (mm, mm->menu);
194                 mm->buf = key_buffer;
195
196                 return;
197         }
198         else if (!g_strcmp0 (DEFAULT_MENU_MENU, key)) {
199                 _show_menu (mm, mm->menu);
200                 return;
201         }
202         else if (!g_strcmp0 (DEFAULT_MENU_QUIT, key)) {
203                 g_main_loop_quit (mm->mainloop);
204                 return;
205         }
206         else if (!g_strcmp0 (DEFAULT_MENU_NONE, key)) {
207                 _show_prompt();
208                 return;
209         }
210
211         while (1) {
212                 item = menu + i;
213                 if (item->key == NULL)
214                         break;
215
216                 if (!g_strcmp0 (item->key, key)) {
217                         if (item->sub_menu) {
218                                 g_queue_push_tail (mm->stack, mm->menu);
219                                 g_queue_push_tail (mm->title_stack, item->title);
220
221                                 mm->menu = item->sub_menu;
222                                 _show_menu (mm, mm->menu);
223                                 mm->buf = key_buffer;
224                         }
225
226                         if (item->callback) {
227                                 item->callback (mm, item);
228                                 _show_prompt();
229                         }
230
231                         if (item->data) {
232                                 _show_item_data_input_msg (item);
233                                 mm->buf = item->data;
234                         }
235
236                         return;
237                 }
238
239                 i++;
240         }
241
242         _show_prompt();
243 }
244
245 MManager *menu_manager_new (struct menu_data items[], GMainLoop *mainloop)
246 {
247         MManager *mm;
248
249         mm = calloc (sizeof (struct menu_manager), 1);
250         if (!mm)
251                 return NULL;
252
253         mm->stack = g_queue_new();
254         mm->title_stack = g_queue_new();
255         mm->menu = items;
256         mm->mainloop = mainloop;
257
258         return mm;
259 }
260
261 int menu_manager_run (MManager *mm)
262 {
263         _show_menu (mm, mm->menu);
264
265         mm->buf = key_buffer;
266
267         return 0;
268 }
269
270 int menu_manager_set_user_data (MManager *mm, void *user_data)
271 {
272         if (!mm)
273                 return -1;
274
275         mm->user_data = user_data;
276
277         return 0;
278 }
279
280 void *menu_manager_ref_user_data (MManager *mm)
281 {
282         if (!mm)
283                 return NULL;
284
285         return mm->user_data;
286 }
287
288 gboolean on_menu_manager_keyboard (GIOChannel *src, GIOCondition con,
289                 gpointer data)
290 {
291         MManager *mm = data;
292         char local_buf[MENU_DATA_SIZE + 1] = { 0, };
293
294         if (fgets (local_buf, MENU_DATA_SIZE, stdin) == NULL)
295                 return TRUE;
296
297         if (strlen (local_buf) > 0) {
298                 if (local_buf[strlen (local_buf) - 1] == '\n')
299                         local_buf[strlen (local_buf) - 1] = '\0';
300         }
301
302         if (mm->buf == key_buffer) {
303                 if (strlen (local_buf) < 1) {
304                         _show_prompt();
305                         return TRUE;
306                 }
307
308                 _move_menu (mm, mm->menu, local_buf);
309         }
310         else {
311                 if (mm->buf) {
312                         memset (mm->buf, 0, MENU_DATA_SIZE);
313                         memcpy (mm->buf, local_buf, MENU_DATA_SIZE);
314                         _show_input_ok();
315                 }
316                 mm->buf = key_buffer;
317                 _move_menu (mm, mm->menu, DEFAULT_MENU_MENU);
318         }
319
320         return TRUE;
321 }
322
323 pid_t get_tid ()
324 {
325         return syscall (__NR_gettid);
326 }
327
328 void hide_pid ()
329 {
330         flag_pid_display = 0;
331 }
332
333 void show_pid ()
334 {
335         flag_pid_display = 1;
336 }
337
338 int is_pid_show ()
339 {
340         return flag_pid_display;
341 }