tizen 2.3 release
[framework/telephony/libslp-tapi.git] / test_src / menu.c
1 /*
2  * libslp-tapi
3  *
4  * Copyright (c) 2014 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 struct menu_manager {
39         GQueue *stack;
40         GQueue *title_stack;
41
42         struct menu_data *menu;
43
44         char *buf;
45
46         void *user_data;
47         GMainLoop *mainloop;
48 };
49
50
51 char key_buffer[MENU_DATA_SIZE];
52 int flag_pid_display = 1;
53
54
55 static void _show_prompt (void)
56 {
57         msgn ("(%5d) >> ", get_tid ());
58 }
59
60 static void _show_reserved_menu (void)
61 {
62         msg (ANSI_COLOR_DARKGRAY HR_SINGLE2 ANSI_COLOR_NORMAL);
63         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
64                         " ] " ANSI_COLOR_NORMAL "Previous menu " , DEFAULT_MENU_PREV);
65         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
66                         " ] " ANSI_COLOR_NORMAL "Show Menu " , DEFAULT_MENU_MENU);
67         msg (ANSI_COLOR_DARKGRAY " [ " ANSI_COLOR_NORMAL "%s" ANSI_COLOR_DARKGRAY
68                         " ] " ANSI_COLOR_NORMAL "Quit " , DEFAULT_MENU_QUIT);
69 }
70
71 static void _show_input_ok (void)
72 {
73         msg ("OK.");
74 }
75
76 static void _show_menu (MManager *m, struct menu_data menu[])
77 {
78         int i = 0;
79         int len = 0;
80         struct menu_data *item;
81         char title_buf[256] = { 0, };
82
83         if (!menu)
84                 return;
85
86         msg ("");
87         msg (HR_DOUBLE);
88
89         len = g_queue_get_length (m->title_stack);
90         msgn (ANSI_COLOR_YELLOW " Main");
91         if (len > 0) {
92                 for (i = 0; i < len; i++) {
93                         msgn (ANSI_COLOR_NORMAL " >> " ANSI_COLOR_YELLOW "%s",
94                                         (char *) g_queue_peek_nth (m->title_stack, i));
95                 }
96         }
97         msg (ANSI_COLOR_NORMAL);
98         msg (HR_SINGLE);
99
100         hide_pid();
101         i = 0;
102
103         while (1) {
104                 item = menu + i;
105                 if (item->key == NULL)
106                         break;
107
108                 if (!g_strcmp0 (item->key, "-")) {
109                         msgn ("       ");
110                 }
111                 else if (!g_strcmp0 (item->key, "_")) {
112                         msg (ANSI_COLOR_DARKGRAY HR_SINGLE2 ANSI_COLOR_NORMAL);
113
114                         if (item->callback)
115                                 item->callback (m, item);
116
117                         i++;
118
119                         continue;
120                 }
121                 else if (!g_strcmp0 (item->key, "*")) {
122                         msg (" %s", item->title);
123                         if (item->callback)
124                                 item->callback (m, item);
125                 }
126                 else {
127                         msgn (ANSI_COLOR_DARKGRAY " [" ANSI_COLOR_NORMAL "%3s"
128                                         ANSI_COLOR_DARKGRAY "] " ANSI_COLOR_NORMAL,     item->key);
129                 }
130
131                 memset (title_buf, 0, 256);
132                 if (item->title) {
133                         snprintf (title_buf, MAX_TITLE, "%s", item->title);
134
135                         if (strlen (item->title) >= MAX_TITLE) {
136                                 title_buf[MAX_TITLE - 2] = '.';
137                                 title_buf[MAX_TITLE - 1] = '.';
138                         }
139                 }
140
141                 if (item->data) {
142                         msg ("%s " ANSI_COLOR_LIGHTBLUE "(%s)" ANSI_COLOR_NORMAL,
143                                         title_buf, item->data);
144                 }
145                 else if (!g_strcmp0 (item->key, "*")) {
146                         /* none */
147                 }
148                 else {
149                         msg ("%s", title_buf);
150                 }
151
152                 if (item->sub_menu) {
153                         msg ("\e[1A\e[%dC >", POS_MORE);
154                 }
155
156                 i++;
157         }
158
159         show_pid();
160
161         _show_reserved_menu();
162
163         msg (HR_DOUBLE);
164
165         _show_prompt();
166 }
167
168 static void _show_item_data_input_msg (struct menu_data *item)
169 {
170         msg ("");
171         msg (HR_DOUBLE);
172         msg (" Input [%s] data ", item->title);
173         msg (HR_SINGLE);
174         msg (" current = [%s]", item->data);
175         msgn (" new >> ");
176 }
177
178 static void _move_menu (MManager *mm, struct menu_data menu[], char *key)
179 {
180         struct menu_data *item;
181         int i = 0;
182
183         if (!mm->menu)
184                 return;
185
186         if (!g_strcmp0 (DEFAULT_MENU_PREV, key)) {
187                 if (g_queue_get_length (mm->stack) > 0) {
188                         mm->menu = g_queue_pop_tail (mm->stack);
189                         g_queue_pop_tail (mm->title_stack);
190                 }
191
192                 _show_menu (mm, mm->menu);
193                 mm->buf = key_buffer;
194
195                 return;
196         }
197         else if (!g_strcmp0 (DEFAULT_MENU_MENU, key)) {
198                 _show_menu (mm, mm->menu);
199                 return;
200         }
201         else if (!g_strcmp0 (DEFAULT_MENU_QUIT, key)) {
202                 g_main_loop_quit (mm->mainloop);
203                 return;
204         }
205         else if (!g_strcmp0 (DEFAULT_MENU_NONE, key)) {
206                 _show_prompt();
207                 return;
208         }
209
210         while (1) {
211                 int ret = RET_SUCCESS;
212                 item = menu + i;
213                 if (item->key == NULL)
214                         break;
215
216                 if (!g_strcmp0 (item->key, key)) {
217                         if (item->callback) {
218                                 ret = item->callback (mm, item);
219                                 _show_prompt();
220                         }
221
222                         if(RET_SUCCESS == ret) {
223                                 if (item->sub_menu) {
224                                         g_queue_push_tail (mm->stack, mm->menu);
225                                         g_queue_push_tail (mm->title_stack, (gpointer *)item->title);
226
227                                         mm->menu = item->sub_menu;
228                                         _show_menu (mm, mm->menu);
229                                         mm->buf = key_buffer;
230                                 }
231
232                                 if (item->data) {
233                                         _show_item_data_input_msg (item);
234                                         mm->buf = item->data;
235                                 }
236                         }
237
238                         return;
239                 }
240
241                 i++;
242         }
243
244         _show_prompt();
245 }
246
247 MManager *menu_manager_new (struct menu_data items[], GMainLoop *mainloop)
248 {
249         MManager *mm;
250
251         mm = calloc (sizeof (struct menu_manager), 1);
252         if (!mm)
253                 return NULL;
254
255         mm->stack = g_queue_new();
256         mm->title_stack = g_queue_new();
257         mm->menu = items;
258         mm->mainloop = mainloop;
259
260         return mm;
261 }
262
263 int menu_manager_run (MManager *mm)
264 {
265         _show_menu (mm, mm->menu);
266
267         mm->buf = key_buffer;
268
269         return 0;
270 }
271
272 int menu_manager_set_user_data (MManager *mm, void *user_data)
273 {
274         if (!mm)
275                 return -1;
276
277         mm->user_data = user_data;
278
279         return 0;
280 }
281
282 void *menu_manager_ref_user_data (MManager *mm)
283 {
284         if (!mm)
285                 return NULL;
286
287         return mm->user_data;
288 }
289
290 gboolean on_menu_manager_keyboard (GIOChannel *src, GIOCondition con,
291                 gpointer data)
292 {
293         MManager *mm = data;
294         char local_buf[MENU_DATA_SIZE + 1] = { 0, };
295
296         if (fgets (local_buf, MENU_DATA_SIZE, stdin) == NULL)
297                 return TRUE;
298
299         if (strlen (local_buf) > 0) {
300                 if (local_buf[strlen (local_buf) - 1] == '\n')
301                         local_buf[strlen (local_buf) - 1] = '\0';
302         }
303
304         if (mm->buf == key_buffer) {
305                 if (strlen (local_buf) < 1) {
306                         _show_prompt();
307                         return TRUE;
308                 }
309
310                 _move_menu (mm, mm->menu, local_buf);
311         }
312         else {
313                 if (mm->buf) {
314                         memset (mm->buf, 0, MENU_DATA_SIZE);
315                         memcpy (mm->buf, local_buf, MENU_DATA_SIZE);
316                         _show_input_ok();
317                 }
318                 mm->buf = key_buffer;
319                 _move_menu (mm, mm->menu, (char *)DEFAULT_MENU_MENU);
320         }
321
322         return TRUE;
323 }
324
325 pid_t get_tid ()
326 {
327         return syscall (__NR_gettid);
328 }
329
330 void hide_pid ()
331 {
332         flag_pid_display = 0;
333 }
334
335 void show_pid ()
336 {
337         flag_pid_display = 1;
338 }
339
340 int is_pid_show ()
341 {
342         return flag_pid_display;
343 }
344
345 static void _hex_dump(const char *pad, int size, const void *data)
346 {
347         char buf[255] = {0, };
348         char hex[4] = {0, };
349         int i;
350         unsigned char *p;
351
352         if (size <= 0) {
353                 msg("%sno data", pad);
354                 return;
355         }
356         p = (unsigned char *)data;
357
358         snprintf(buf, 255, "%s%04X: ", pad, 0);
359         for (i = 0; i<size; i++) {
360                 snprintf(hex, 4, "%02X ", p[i]);
361                 strcat(buf, hex);
362
363                 if ((i + 1) % 8 == 0) {
364                         if ((i + 1) % 16 == 0) {
365                                 msg("%s", buf);
366                                 memset(buf, 0, 255);
367                                 snprintf(buf, 255, "%s%04X: ", pad, i + 1);
368                         }
369                         else {
370                                 strcat(buf, "  ");
371                         }
372                 }
373         }
374
375         msg("%s", buf);
376 }
377
378 void menu_print_dump(int data_len, void *data)
379 {
380         if(!data)
381                 return;
382
383         msg("");
384         msg("  \tlen=%d", data_len);
385         _hex_dump("        ", data_len, data);
386
387         msg("");
388 }
389