1 // $Id$
2 //
3 // Test basic functionality of Curses class
4 #ifdef HAVE_CONFIG_H
5 #include "config.h"
6 #endif
7 
8 #include <unistd.h>
9 
10 #ifdef HAVE_SYS_IOCTL_H
11 #include <sys/ioctl.h>
12 #endif  // HAVE_SYS_IOCTL_H
13 
14 #ifdef HAVE_SYS_TYPES_H
15 #include <sys/types.h>
16 #endif  // HAVE_SYS_TYPES_H
17 
18 #ifdef HAVE_STROPTS_H
19 #include <stropts.h>
20 #endif  // HAVE_STROPTS_H
21 
22 #ifdef HAVE_TERMIOS_H
23 #include <termios.h>
24 #else  // HAVE_TERMIOS_H
25 #ifdef HAVE_SYS_TERMIOS_H
26 #include <sys/termios.h>
27 #endif  // HAVE_SYS_TERMIOS_H
28 #endif  // HAVE_TERMIOS_H
29 
30 #include <iostream>
31 #include <sstream>
32 
33 #include "yacurs.h"
34 
35 // Used when preloading libtestpreload.so
36 #ifdef YACURS_USE_WCHAR
37 wint_t
38 #else
39 int
40 #endif
41     __test_data[] = {' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
42                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
43                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
44                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
45                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
46                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
47                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
48                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
49                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
50                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
51                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
52                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
53                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
54                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
55                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
56                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
57                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
58                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_UP,
59                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
60                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
61                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
62                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
63                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
64                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
65                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
66                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
67                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
68                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
69                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
70                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
71                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
72                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
73                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
74                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
75                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
76                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
77                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
78                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
79                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
80                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
81                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
82                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
83                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
84                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
85                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
86                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
87                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
88                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
89                      ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,   ' ', KEY_UP,
90                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
91                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
92                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
93                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
94                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
95                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
96                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
97                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
98                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
99                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
100                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
101                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
102                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
103                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
104                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
105                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
106                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
107                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
108                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
109                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
110                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
111                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
112                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
113                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
114                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
115                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
116                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
117                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
118                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
119                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
120                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
121                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
122                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
123                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
124                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
125                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
126                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
127                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
128                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
129                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
130                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
131                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
132                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
133                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
134                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
135                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
136                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
137                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
138                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
139                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
140                      ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN, ' ', KEY_DOWN,
141                      'Q', 0};
142 
143 #ifdef YACURS_USE_WCHAR
__test_wget_wch(void *,wint_t * i)144 extern "C" int __test_wget_wch(void*, wint_t* i) {
145     static wint_t* ptr2 = __test_data;
146 
147 #ifdef SLOW_TESTS
148     usleep(70000);
149 #endif
150 
151     if (*ptr2 == 0) {
152         abort();
153     }
154 
155     *i = *ptr2++;
156 
157     return OK;
158 }
159 #else
__test_wgetch(void *)160 extern "C" int __test_wgetch(void*) {
161     static int* ptr2 = __test_data;
162 
163 #ifdef SLOW_TESTS
164     usleep(70000);
165 #endif
166 
167     if (*ptr2 == 0) {
168         abort();
169     }
170 
171     return *ptr2++;
172 }
173 #endif
174 
175 class HotKeyQuit : public YACURS::HotKey {
176    public:
HotKeyQuit(int k)177     HotKeyQuit(int k) : HotKey(k) {}
178 
HotKeyQuit(const HotKeyQuit & hk)179     HotKeyQuit(const HotKeyQuit& hk) : HotKey(hk) {}
180 
action()181     void action() { YACURS::EventQueue::submit(YACURS::EVT_QUIT); }
182 
clone() const183     HotKey* clone() const { return new HotKeyQuit(*this); }
184 };
185 
main()186 int main() {
187     // test will not be run if stdout or stdin is not a tty.
188     if (isatty(STDOUT_FILENO) != 1 || isatty(STDIN_FILENO) != 1) exit(77);
189 
190 #ifdef YACURS_USE_WCHAR
191     if (setlocale(LC_ALL, "en_US.UTF-8") == 0) exit(77);
192 #endif
193 
194     try {
195         YACURS::Curses::init();
196 
197         YACURS::TitleBar* title =
198             new YACURS::TitleBar(YACURS::TitleBar::POS_TOP, "ListBox 1");
199         YACURS::Curses::title(title);
200 
201         // NOTE:
202         //
203         // The order the objects are created (MyWindow, StatusBar) is
204         // important here. Because MyWindow calls
205         // StatusBar::put_msg() on resize we have to make sure
206         // StatusBar is resized first. Since YACURS::EventQueue calls the
207         // last YACURS::EventConnector connected first, StatusBar has to be
208         // created AFTER MyWindow.
209 
210         YACURS::Window* w1 = new YACURS::Window(YACURS::Margin(1, 0, 1, 0));
211         w1->frame(true);
212         w1->add_hotkey(HotKeyQuit('q'));
213         w1->add_hotkey(HotKeyQuit('Q'));
214 
215         std::vector<std::string> items;
216 #ifdef YACURS_USE_WCHAR
217         items.push_back("It€m 1");
218         items.push_back("It€m 2");
219         items.push_back("It€m 3");
220         items.push_back("It€m 5");
221         items.push_back("It€m 6");
222         items.push_back("It€m 7");
223         items.push_back("It€m 8");
224         items.push_back("It€m 9");
225         items.push_back("It€m 10");
226         YACURS::RadioBox* rabx1 = new YACURS::RadioBox("It€ms¹2³4⁵", items);
227 #else
228         items.push_back("Item 1");
229         items.push_back("Item 2");
230         items.push_back("Item 3");
231         items.push_back("Item 5");
232         items.push_back("Item 6");
233         items.push_back("Item 7");
234         items.push_back("Item 8");
235         items.push_back("Item 9");
236         items.push_back("Item 10");
237         YACURS::RadioBox* rabx1 = new YACURS::RadioBox("Items12345", items);
238 #endif
239 
240         w1->widget(rabx1);
241 
242         YACURS::StatusBar* sl = new YACURS::StatusBar();
243         YACURS::Curses::statusbar(sl);
244         sl->push("Press Q to quit");
245 
246         YACURS::Curses::mainwindow(w1);
247 
248         YACURS::Curses::run();
249 
250         delete title;
251         delete rabx1;
252         delete w1;
253         delete sl;
254         YACURS::Curses::end();
255     } catch (std::exception& e) {
256         YACURS::Curses::end();
257         std::cerr << e.what() << std::endl;
258         return 1;
259     }
260 
261     return 0;
262 }
263