5c824510668a5ceb2bb49d04593affc578284046
[framework/telephony/tel-plugin-socket_communicator.git] / test / menu.c
1 /*
2  * tel-plugin-socket-communicator
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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <glib-object.h>
26
27 #include "menu.h"
28
29 #define DEFAULT_MENU_MENU       "m"
30 #define DEFAULT_MENU_PREV       "p"
31 #define DEFAULT_MENU_QUIT       "q"
32
33
34 struct menu_manager {
35         GQueue *stack;
36         GQueue *title_stack;
37
38         struct menu_data *menu;
39
40         char *buf;
41
42         void *user_data;
43         GMainLoop *mainloop;
44 };
45
46
47 char key_buffer[MENU_DATA_SIZE];
48
49 static void _show_prompt()
50 {
51         msgn(" >> ");
52 }
53
54 static void _show_reserved_menu()
55 {
56         msg(ANSI_COLOR_DARKGRAY "--------------------------------------------" ANSI_COLOR_NORMAL);
57         msg(" [%3s] Previous menu ", DEFAULT_MENU_PREV);
58         msg(" [%3s] Show Menu ", DEFAULT_MENU_MENU);
59         msg(" [%3s] Quit ", DEFAULT_MENU_QUIT);
60 }
61
62 static void _show_input_ok()
63 {
64         msg("OK.");
65 }
66
67 static void _show_menu(MManager *m, struct menu_data menu[])
68 {
69         int i = 0;
70         int len = 0;
71         struct menu_data *item;
72
73         if (!menu)
74                 return;
75
76         msg("");
77         msg("============================================");
78         len = g_queue_get_length(m->title_stack);
79         msgn(ANSI_COLOR_YELLOW " Main");
80         if (len > 0) {
81                 for (i = 0; i < len; i++) {
82                         msgn(ANSI_COLOR_NORMAL " >> " ANSI_COLOR_YELLOW "%s", (char *)g_queue_peek_nth(m->title_stack, i));
83                 }
84         }
85         msg(ANSI_COLOR_NORMAL);
86         msg("--------------------------------------------");
87
88         i = 0;
89         while (1) {
90                 item = menu + i;
91                 if (item->key == NULL)
92                         break;
93
94                 //msgn(" [%p][%3s] ", item, item->key);
95                 msgn(" [%3s] ", item->key);
96                 if (item->data) {
97                         msg("%s " ANSI_COLOR_LIGHTBLUE "(%s)" ANSI_COLOR_NORMAL, item->title, item->data);
98                 }
99                 else {
100                         msg("%s", item->title);
101                 }
102
103                 i++;
104         }
105
106         _show_reserved_menu();
107
108         msg("============================================");
109
110         _show_prompt();
111 }
112
113 static void _show_item_data_input_msg(struct menu_data *item)
114 {
115         msg("");
116         msg("============================================");
117         msg(" Input [%s] data ", item->title);
118         msg("--------------------------------------------");
119         msg(" current = [%s]", item->data);
120         msgn(" new >> ");
121 }
122
123 static void _move_menu(MManager *mm, struct menu_data menu[], char *key)
124 {
125         struct menu_data *item;
126         int i = 0;
127
128         if (!mm->menu)
129                 return;
130
131         if (!g_strcmp0(DEFAULT_MENU_PREV, key)) {
132                 if (g_queue_get_length(mm->stack) > 0) {
133                         mm->menu = g_queue_pop_tail(mm->stack);
134                         g_queue_pop_tail(mm->title_stack);
135                 }
136                 _show_menu(mm, mm->menu);
137                 mm->buf = key_buffer;
138         }
139         else if (!g_strcmp0(DEFAULT_MENU_MENU, key)) {
140                 _show_menu(mm, mm->menu);
141         }
142         else if (!g_strcmp0(DEFAULT_MENU_QUIT, key)) {
143                 g_main_loop_quit(mm->mainloop);
144         }
145
146         while (1) {
147                 item = menu + i;
148                 if (item->key == NULL)
149                         break;
150
151                 if (!g_strcmp0(item->key, key)) {
152                         if (item->sub_menu) {
153                                 g_queue_push_tail(mm->stack, mm->menu);
154                                 g_queue_push_tail(mm->title_stack, item->title);
155
156                                 mm->menu = item->sub_menu;
157                                 _show_menu(mm, mm->menu);
158                                 mm->buf = key_buffer;
159                         }
160
161                         if (item->callback)
162                                 item->callback(mm, item);
163
164                         if (item->data) {
165                                 _show_item_data_input_msg(item);
166                                 mm->buf = item->data;
167                         }
168                         return;
169                 }
170
171                 i++;
172         }
173
174         _show_prompt();
175 }
176
177 MManager *menu_manager_new(struct menu_data items[], GMainLoop *mainloop)
178 {
179         MManager *mm;
180
181         mm = calloc(sizeof(struct menu_manager), 1);
182         mm->stack = g_queue_new();
183         mm->title_stack = g_queue_new();
184         mm->menu = items;
185         mm->mainloop = mainloop;
186
187         return mm;
188 }
189
190 int menu_manager_run(MManager *mm)
191 {
192         _show_menu(mm, mm->menu);
193
194         mm->buf = key_buffer;
195
196         return 0;
197 }
198
199 int menu_manager_set_user_data(MManager *mm, void *user_data)
200 {
201         if (!mm)
202                 return -1;
203
204         mm->user_data = user_data;
205
206         return 0;
207 }
208
209 void *menu_manager_ref_user_data(MManager *mm)
210 {
211         if (!mm)
212                 return NULL;
213
214         return mm->user_data;
215 }
216
217 gboolean on_menu_manager_keyboard(GIOChannel *src, GIOCondition con, gpointer data)
218 {
219         MManager *mm = data;
220         char local_buf[MENU_DATA_SIZE + 1] = {
221                         0, };
222
223         fgets(local_buf, MENU_DATA_SIZE, stdin);
224
225         if (strlen(local_buf) > 0) {
226                 if (local_buf[strlen(local_buf) - 1] == '\n')
227                         local_buf[strlen(local_buf) - 1] = '\0';
228         }
229
230         if (mm->buf == key_buffer) {
231                 if (strlen(local_buf) < 1) {
232                         _show_prompt();
233                         return TRUE;
234                 }
235
236                 _move_menu(mm, mm->menu, local_buf);
237         }
238         else {
239                 if (mm->buf) {
240                         memset(mm->buf, 0, MENU_DATA_SIZE);
241                         memcpy(mm->buf, local_buf, MENU_DATA_SIZE);
242                         _show_input_ok();
243                 }
244                 mm->buf = key_buffer;
245                 _move_menu(mm, mm->menu, DEFAULT_MENU_MENU);
246         }
247
248         return TRUE;
249 }