IBusFactory: Fix syntax of gtk-doc comment
[platform/upstream/ibus.git] / test / test_client.py
1 #! /usr/bin/python
2 # Test program for client APIs.
3
4 import os
5 import sys
6 import glib
7 import termios
8 import tty
9 import locale
10 import curses
11 import ibus
12 from ibus import keysyms
13 from ibus import modifier
14
15 class DemoTerm:
16     def __init__(self):
17         self.__init_curses()
18         self.__bus = ibus.Bus()
19         self.__ic_path = self.__bus.create_input_context("DemoTerm")
20         self.__ic = ibus.InputContext(self.__bus, self.__ic_path, True)
21         self.__ic.set_capabilities(7)
22         self.__ic.connect("commit-text", self.__commit_text_cb)
23
24         self.__ic.connect("update-preedit-text", self.__update_preedit_text_cb)
25         self.__ic.connect("show-preedit-text", self.__show_preedit_text_cb)
26         self.__ic.connect("hide-preedit-text", self.__hide_preedit_text_cb)
27
28         self.__ic.connect("update-auxiliary-text", self.__update_aux_text_cb)
29         self.__ic.connect("show-auxiliary-text", self.__show_aux_text_cb)
30         self.__ic.connect("hide-auxiliary-text", self.__hide_aux_text_cb)
31
32         self.__ic.connect("update-lookup-table", self.__update_lookup_table_cb)
33         self.__ic.connect("show-lookup-table", self.__show_lookup_table_cb)
34         self.__ic.connect("hide-lookup-table", self.__hide_lookup_table_cb)
35         glib.io_add_watch(0, glib.IO_IN, self.__stdin_cb)
36         # glib.timeout_add(500, self.__timeout_cb)
37
38         # self.__master_fd, self.__slave_fd = os.openpty()
39         # self.__run_shell()
40
41         self.__is_invalidate = False
42         self.__preedit = None
43         self.__preedit_visible = False
44         self.__aux_string = None
45         self.__aux_string_visible = False
46         self.__lookup_table = None
47         self.__lookup_table_visible = False
48
49         # self.__old_sigwinch_cb = signal.signal(signal.SIGWINCH, self.__sigwinch_cb)
50
51     def __timeout_cb(self):
52         self.__stdin_cb(0, 0)
53         return True
54
55     def __sigwinch_cb(self, a, b):
56         self.__old_sigwinch_cb(a, b)
57         self.__invalidate()
58
59     def __init_curses(self):
60         self.__screen = curses.initscr()
61         curses.noecho()
62         curses.raw()
63         self.__screen.keypad(1)
64         self.__screen.refresh()
65         self.__screen.nodelay(1)
66         self.__max_y, self.__max_x = self.__screen.getmaxyx()
67         self.__state_pad = curses.newpad(2, self.__max_x)
68         self.__state_pad.bkgd(' ', curses.A_REVERSE)
69         self.__state_pad.addstr(0, 0, "Press Ctrl + v to enable or disable input method")
70         self.__state_pad.refresh(0, 0, self.__max_y - 2, 0, self.__max_y, self.__max_x)
71
72     def __fini_curses(self):
73         curses.noraw()
74         curses.echo()
75         curses.endwin()
76
77     def __stdin_cb(self, fd, condition):
78         while self.__process_input():
79             pass
80         return True
81
82     def __process_input(self):
83         c = self.__screen.getch()
84         if c < 0:
85             return False
86
87         if c == 3:
88             self.__loop.quit()
89         try:
90             if c == 22: # Ctrl + V => Ctrl + space
91                 retval = self.__ic.process_key_event(keysyms.space, 0, modifier.CONTROL_MASK)
92             elif c == curses.KEY_BACKSPACE: # BackSpace
93                 self.__ic.process_key_event(keysyms.BackSpace, 0, 0)
94                 retval = True
95             elif c == curses.KEY_ENTER:
96                 self.__ic.process_key_event(keysyms.Enter, 0, 0)
97             elif c == curses.KEY_RESIZE:
98                 self.__invalidate()
99                 retval = True
100             else:
101                 retval = self.__ic.process_key_event(c, 0, 0)
102         except:
103             import backtrace
104             backtrace.print_exc()
105             retval = False
106             raise
107         if retval == False:
108             self.__screen.addstr(unichr(c).encode("utf-8"))
109             self.__screen.refresh()
110         return True
111
112     def __commit_text_cb(self, ic, text):
113         self.__screen.addstr(text.text)
114         self.__screen.refresh()
115
116     def __update_preedit_text_cb(self, ic, text, cursor_pos, visible):
117         self.__preedit = text
118         self.__preedit_visible = visible
119         self.__invalidate()
120
121     def __show_preedit_text_cb(self, ic):
122         if self.__preedit_visible:
123             return
124         self.__preedit_visible = True
125         self.__invalidate()
126
127     def __hide_preedit_text_cb(self, ic):
128         if not self.__preedit_visible:
129             return
130         self.__preedit_visible = False
131         self.__invalidate()
132
133     def __update_aux_text_cb(self, ic, text, visible):
134         self.__aux_string = text
135         self.__aux_string_visible = visible
136         self.__invalidate()
137
138     def __show_aux_text_cb(self, ic):
139         if self.__aux_string_visible:
140             return
141         self.__aux_string_visible = True
142         self.__invalidate()
143
144     def __hide_aux_text_cb(self, ic):
145         if not self.__aux_string_visible:
146             return
147         self.__aux_string_visible = False
148         self.__invalidate()
149
150
151     def __update_lookup_table_cb(self, ic, lookup_table, visible):
152         self.__lookup_table = lookup_table
153         self.__lookup_table_visible = visible
154         self.__invalidate()
155
156     def __show_lookup_table_cb(self, ic):
157         if self.__lookup_table_visible:
158             return
159         self.__lookup_table_visible = True
160         self.__invalidate()
161
162     def __hide_lookup_table_cb(self, ic):
163         if not self.__lookup_table_visible:
164             return
165         self.__lookup_table_visible = False
166         self.__invalidate()
167
168     def __invalidate(self):
169         if self.__is_invalidate:
170             return
171         self.__is_invalidate = True
172         glib.idle_add(self.__update)
173
174     def __update(self):
175         if not self.__is_invalidate:
176             return False
177         self.__is_invalidate = False
178
179         y, x = self.__screen.getmaxyx()
180         if self.__max_x != x or self.__max_y != y:
181             self.__max_x = x
182             self.__max_y = y
183             self.__state_pad = curses.newpad(2, self.__max_x)
184             self.__state_pad.bkgd(' ', curses.A_REVERSE)
185             self.__state_pad.addstr(0, 0, "Press Ctrl + v to enable or disable input method")
186             self.__screen.clear()
187
188         self.__state_pad.clear()
189
190         # update preedit
191         if self.__preedit_visible and self.__preedit:
192             self.__state_pad.addstr(0, 0, self.__preedit.text, curses.A_REVERSE)
193         else:
194             self.__state_pad.addstr(0, 0, "", curses.A_REVERSE)
195
196         # update aux string
197         if self.__aux_string_visible and self.__aux_string:
198             self.__state_pad.addstr("  ", curses.A_REVERSE)
199             self.__state_pad.addstr(self.__aux_string.text, curses.A_REVERSE)
200         self.__state_pad.addstr(1, 0, "", curses.A_REVERSE)
201
202         # update lookup table
203         if self.__lookup_table_visible and self.__lookup_table:
204             candidates = self.__lookup_table.get_candidates_in_current_page()
205             for i, c in enumerate(candidates):
206                 text = u"%d.%s " % (i + 1, c.text)
207                 self.__state_pad.addstr(text.encode("utf-8"), curses.A_REVERSE)
208                 i += 1
209
210         if self.__preedit_visible == False and self.__aux_string_visible == False and self.__lookup_table_visible == False:
211             self.__state_pad.addstr(0, 0, "Press Ctrl + v to enable or disable input method")
212
213         self.__state_pad.refresh(0, 0, self.__max_y - 2, 0, self.__max_y, self.__max_x)
214         self.__screen.refresh()
215
216         return False
217
218     def __run_shell(self):
219         pid = os.fork()
220         if pid == 0: # child
221             os.close(0)
222             os.close(1)
223             os.close(2)
224             os.close(self.__master_fd)
225             os.dup2(self.__slave_fd, 0)
226             os.dup2(self.__slave_fd, 1)
227             os.dup2(self.__slave_fd, 2)
228             os.close(self.__slave_fd)
229             os.execv('/bin/bash', ["bash"])
230             os.exit(1)
231
232
233
234     def run(self):
235         self.__loop = glib.MainLoop()
236         self.__loop.run()
237
238     def close(self):
239         self.__fini_curses()
240         pass
241
242 def old_main():
243     locale.setlocale(locale.LC_ALL, "")
244     old = termios.tcgetattr(0)
245     term = DemoTerm()
246     try:
247         term.run()
248     except:
249         term.close()
250         termios.tcsetattr(0, termios.TCSAFLUSH, old)
251         import traceback
252         traceback.print_exc()
253     finally:
254         term.close()
255         termios.tcsetattr(0, termios.TCSAFLUSH, old)
256
257 def main():
258     term = DemoTerm()
259
260 if __name__ == "__main__":
261     old_main()
262