1 /* TN5250 - An implementation of the 5250 telnet protocol.
2 * Copyright (C) 1997-2008 Michael Madore
3 *
4 * This file is part of TN5250.
5 *
6 * TN5250 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1, or (at your option)
9 * any later version.
10 *
11 * TN5250 is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this software; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307 USA
20 *
21 */
22 #define _TN5250_TERMINAL_PRIVATE_DEFINED
23 #include "tn5250-private.h"
24 #include "slangterm.h"
25
26 #if USE_SLANG
27
28 /* Mapping of 5250 colors to curses colors */
29 #define A_5250_WHITE 0x100
30 #define A_5250_RED 0x200
31 #define A_5250_TURQ 0x300
32 #define A_5250_YELLOW 0x400
33 #define A_5250_PINK 0x500
34 #define A_5250_BLUE 0x600
35 #define A_5250_BLACK 0x700
36 #define A_5250_GREEN 0x800
37
38 #define A_COLOR_MASK 0xf00
39
40 #define A_REVERSE 0x1000
41 #define A_UNDERLINE 0x2000
42 #define A_BLINK 0x4000
43 #define A_VERTICAL 0x8000
44
45 static int attribute_map[] =
46 {A_5250_GREEN,
47 A_5250_GREEN | A_REVERSE,
48 A_5250_WHITE,
49 A_5250_WHITE | A_REVERSE,
50 A_5250_GREEN | A_UNDERLINE,
51 A_5250_GREEN | A_UNDERLINE | A_REVERSE,
52 A_5250_WHITE | A_UNDERLINE,
53 0x00,
54 A_5250_RED,
55 A_5250_RED | A_REVERSE,
56 A_5250_RED | A_BLINK,
57 A_5250_RED | A_BLINK | A_REVERSE,
58 A_5250_RED | A_UNDERLINE,
59 A_5250_RED | A_UNDERLINE | A_REVERSE,
60 A_5250_RED | A_UNDERLINE | A_BLINK,
61 0x00,
62 A_5250_TURQ | A_VERTICAL,
63 A_5250_TURQ | A_VERTICAL | A_REVERSE,
64 A_5250_YELLOW | A_VERTICAL,
65 A_5250_YELLOW | A_VERTICAL | A_REVERSE,
66 A_5250_TURQ | A_UNDERLINE | A_VERTICAL,
67 A_5250_TURQ | A_UNDERLINE | A_REVERSE | A_VERTICAL,
68 A_5250_YELLOW | A_UNDERLINE | A_VERTICAL,
69 0x00,
70 A_5250_PINK,
71 A_5250_PINK | A_REVERSE,
72 A_5250_BLUE,
73 A_5250_BLUE | A_REVERSE,
74 A_5250_PINK | A_UNDERLINE,
75 A_5250_PINK | A_UNDERLINE | A_REVERSE,
76 A_5250_BLUE | A_UNDERLINE,
77 0x00};
78
79 static void slang_terminal_init(Tn5250Terminal * This);
80 static void slang_terminal_term(Tn5250Terminal * This);
81 static void slang_terminal_destroy(Tn5250Terminal /*@only@*/ * This);
82 static int slang_terminal_width(Tn5250Terminal * This);
83 static int slang_terminal_height(Tn5250Terminal * This);
84 static int slang_terminal_flags(Tn5250Terminal * This);
85 static void slang_terminal_update(Tn5250Terminal * This,
86 Tn5250Display * display);
87 static void slang_terminal_update_indicators(Tn5250Terminal * This,
88 Tn5250Display *display);
89 static int slang_terminal_waitevent(Tn5250Terminal * This);
90 static int slang_terminal_getkey(Tn5250Terminal * This);
91 static void slang_terminal_beep(Tn5250Terminal * This);
92 static int slang_terminal_enhanced (Tn5250Terminal * This);
93 static int slang_terminal_get_esc_key(Tn5250Terminal * This, int is_esc);
94 static void slang_terminal_set_attrs (Tn5250Terminal * This, int attrs);
95
96 struct _Tn5250TerminalPrivate {
97 int quit_flag;
98 int last_width, last_height;
99 int attrs;
100 };
101
102 /****f* lib5250/tn5250_slang_terminal_new
103 * NAME
104 * tn5250_slang_terminal_new
105 * SYNOPSIS
106 * ret = tn5250_slang_terminal_new ();
107 * INPUTS
108 * None
109 * DESCRIPTION
110 * Create a new curses terminal object.
111 *****/
tn5250_slang_terminal_new()112 Tn5250Terminal *tn5250_slang_terminal_new()
113 {
114 Tn5250Terminal *r = tn5250_new(Tn5250Terminal, 1);
115 if (r == NULL)
116 return NULL;
117
118 r->data = tn5250_new(struct _Tn5250TerminalPrivate, 1);
119 if (r->data == NULL) {
120 free(r);
121 return NULL;
122 }
123
124 r->data->quit_flag = 0;
125 r->data->last_width = 0;
126 r->data->last_height = 0;
127 r->data->attrs = 0;
128
129 r->conn_fd = -1;
130 r->init = slang_terminal_init;
131 r->term = slang_terminal_term;
132 r->destroy = slang_terminal_destroy;
133 r->width = slang_terminal_width;
134 r->height = slang_terminal_height;
135 r->flags = slang_terminal_flags;
136 r->update = slang_terminal_update;
137 r->update_indicators = slang_terminal_update_indicators;
138 r->waitevent = slang_terminal_waitevent;
139 r->getkey = slang_terminal_getkey;
140 r->putkey = NULL;
141 r->beep = slang_terminal_beep;
142 r->flags = slang_terminal_enhanced;
143 return r;
144 }
145
146 /****i* lib5250/slang_terminal_init
147 * NAME
148 * slang_terminal_init
149 * SYNOPSIS
150 * slang_terminal_init (This);
151 * INPUTS
152 * Tn5250Terminal * This -
153 * DESCRIPTION
154 * DOCUMENT ME!!!
155 *****/
slang_terminal_init(Tn5250Terminal * This)156 static void slang_terminal_init(Tn5250Terminal * This)
157 {
158 SLtt_get_terminfo ();
159 if (-1 == SLkp_init ()) {
160 SLang_doerror ("SLkp_init failed.");
161 exit (255);
162 }
163 if (-1 == SLang_init_tty (K_CTRL('Q'), 1, 0)) {
164 SLang_doerror ("SLang_init_tty failed.");
165 exit (255);
166 }
167 SLang_set_abort_signal (NULL);
168 if (-1 == SLsmg_init_smg ()) {
169 SLang_doerror ("SLsmg_init_smg failed.");
170 exit (255);
171 }
172
173 SLtt_set_color_fgbg (1, SLSMG_COLOR_BRIGHT_WHITE, SLSMG_COLOR_BLACK);
174 SLtt_set_color_fgbg (2, SLSMG_COLOR_RED, SLSMG_COLOR_BLACK);
175 SLtt_set_color_fgbg (3, SLSMG_COLOR_BLUE, SLSMG_COLOR_BLACK);
176 SLtt_set_color_fgbg (4, SLSMG_COLOR_BRIGHT_BROWN, SLSMG_COLOR_BLACK);
177 SLtt_set_color_fgbg (5, SLSMG_COLOR_BRIGHT_MAGENTA, SLSMG_COLOR_BLACK);
178 SLtt_set_color_fgbg (6, SLSMG_COLOR_BRIGHT_BLUE, SLSMG_COLOR_BLACK);
179 SLtt_set_color_fgbg (7, SLSMG_COLOR_BLACK, SLSMG_COLOR_BLACK);
180 SLtt_set_color_fgbg (8, SLSMG_COLOR_GREEN, SLSMG_COLOR_BLACK);
181
182 SLsmg_cls ();
183 SLsmg_refresh ();
184 This->data->quit_flag = 0;
185 }
186
187 /****i* lib5250/slang_terminal_term
188 * NAME
189 * slang_terminal_term
190 * SYNOPSIS
191 * slang_terminal_term (This);
192 * INPUTS
193 * Tn5250Terminal * This -
194 * DESCRIPTION
195 * DOCUMENT ME!!!
196 *****/
slang_terminal_term(Tn5250Terminal * This)197 static void slang_terminal_term(Tn5250Terminal * This)
198 {
199 SLsmg_reset_smg ();
200 SLang_reset_tty ();
201 }
202
203 /****i* lib5250/slang_terminal_destroy
204 * NAME
205 * slang_terminal_destroy
206 * SYNOPSIS
207 * slang_terminal_destroy (This);
208 * INPUTS
209 * Tn5250Terminal * This -
210 * DESCRIPTION
211 * DOCUMENT ME!!!
212 *****/
slang_terminal_destroy(Tn5250Terminal * This)213 static void slang_terminal_destroy(Tn5250Terminal * This)
214 {
215 if (This->data != NULL)
216 free(This->data);
217 free(This);
218 }
219
220 /****i* lib5250/slang_terminal_width
221 * NAME
222 * slang_terminal_width
223 * SYNOPSIS
224 * ret = slang_terminal_width (This);
225 * INPUTS
226 * Tn5250Terminal * This -
227 * DESCRIPTION
228 * DOCUMENT ME!!!
229 *****/
slang_terminal_width(Tn5250Terminal * This)230 static int slang_terminal_width(Tn5250Terminal /*@unused@*/ * This)
231 {
232 SLtt_get_screen_size();
233 return SLtt_Screen_Cols;
234 }
235
236 /****i* lib5250/slang_terminal_height
237 * NAME
238 * slang_terminal_height
239 * SYNOPSIS
240 * ret = slang_terminal_height (This);
241 * INPUTS
242 * Tn5250Terminal * This -
243 * DESCRIPTION
244 * DOCUMENT ME!!!
245 *****/
slang_terminal_height(Tn5250Terminal * This)246 static int slang_terminal_height(Tn5250Terminal /*@unused@*/ * This)
247 {
248 SLtt_get_screen_size();
249 return SLtt_Screen_Rows;
250 }
251
252 /****i* lib5250/slang_terminal_flags
253 * NAME
254 * slang_terminal_flags
255 * SYNOPSIS
256 * ret = slang_terminal_flags (This);
257 * INPUTS
258 * Tn5250Terminal * This -
259 * DESCRIPTION
260 * DOCUMENT ME!!!
261 *****/
slang_terminal_flags(Tn5250Terminal * This)262 static int slang_terminal_flags(Tn5250Terminal /*@unused@*/ * This)
263 {
264 int f = 0;
265 if (SLtt_Use_Ansi_Colors)
266 f |= TN5250_TERMINAL_HAS_COLOR;
267 return f;
268 }
269
270 /****i* lib5250/slang_terminal_update
271 * NAME
272 * slang_terminal_update
273 * SYNOPSIS
274 * slang_terminal_update (This, display);
275 * INPUTS
276 * Tn5250Terminal * This -
277 * Tn5250Display * display -
278 * DESCRIPTION
279 * DOCUMENT ME!!!
280 *****/
slang_terminal_update(Tn5250Terminal * This,Tn5250Display * display)281 static void slang_terminal_update(Tn5250Terminal * This, Tn5250Display * display)
282 {
283 int my, mx;
284 int y, x;
285 int curs_attr, temp_attr;
286 unsigned char a = 0x20, c;
287
288 if (This->data->last_width != tn5250_display_width(display)
289 || This->data->last_height != tn5250_display_height(display)) {
290 SLsmg_cls ();
291 This->data->last_width = tn5250_display_width(display);
292 This->data->last_height = tn5250_display_height(display);
293 slang_terminal_update_indicators(This, display);
294 }
295 SLsmg_normal_video ();
296 my = SLtt_Screen_Rows - 1;
297 mx = SLtt_Screen_Cols - 1;
298 for (y = 0; y < tn5250_display_height(display); y++) {
299 if (y > my)
300 break;
301
302 SLsmg_gotorc (y, 0);
303 for (x = 0; x < tn5250_display_width(display); x++) {
304 c = tn5250_display_char_at(display, y, x);
305 if ((c & 0xe0) == 0x20) { /* ATTRIBUTE */
306 a = (c & 0xff);
307 temp_attr = This->data->attrs;
308 slang_terminal_set_attrs (This, attribute_map[0]);
309 SLsmg_write_char (' ');
310 slang_terminal_set_attrs (This, temp_attr);
311 } else { /* DATA */
312 curs_attr = attribute_map[a - 0x20];
313 if (curs_attr == 0x00) { /* NONDISPLAY */
314 temp_attr = This->data->attrs;
315 slang_terminal_set_attrs (This, attribute_map[0]);
316 SLsmg_write_char (' ');
317 slang_terminal_set_attrs (This, temp_attr);
318 } else {
319 c = tn5250_char_map_to_local (tn5250_display_char_map (display), c);
320 if ((c < 0x20 && c > 0x00) || c >= 0x7f) { /* UNPRINTABLE */
321 c = ' ';
322 curs_attr ^= A_REVERSE;
323 }
324 if ((curs_attr & A_VERTICAL) != 0) {
325 curs_attr |= A_UNDERLINE;
326 curs_attr &= ~A_VERTICAL;
327 }
328 /* This is a kludge since vga hardware doesn't support under-
329 * lining characters. It's pretty ugly. */
330 if ((curs_attr & A_UNDERLINE) != 0) {
331 curs_attr &= ~A_UNDERLINE;
332 if (c == ' ')
333 c = '_';
334 }
335 slang_terminal_set_attrs (This, curs_attr);
336 SLsmg_write_char (c);
337 }
338 } /* if ((c & 0xe0) ... */
339 } /* for (int x ... */
340 } /* for (int y ... */
341
342 SLsmg_gotorc (tn5250_display_cursor_y(display), tn5250_display_cursor_x(display));
343 SLsmg_refresh();
344 }
345
346 /****i* lib5250/slang_terminal_update_indicators
347 * NAME
348 * slang_terminal_update_indicators
349 * SYNOPSIS
350 * slang_terminal_update_indicators (This, display);
351 * INPUTS
352 * Tn5250Terminal * This -
353 * Tn5250Display * display -
354 * DESCRIPTION
355 * DOCUMENT ME!!!
356 *****/
slang_terminal_update_indicators(Tn5250Terminal * This,Tn5250Display * display)357 static void slang_terminal_update_indicators(Tn5250Terminal * This, Tn5250Display * display)
358 {
359 int inds = tn5250_display_indicators(display);
360 char ind_buf[80];
361
362 memset(ind_buf, ' ', sizeof(ind_buf));
363 memcpy(ind_buf, "5250", 4);
364 if ((inds & TN5250_DISPLAY_IND_MESSAGE_WAITING) != 0) {
365 memcpy(ind_buf + 23, "MW", 2);
366 }
367 if ((inds & TN5250_DISPLAY_IND_INHIBIT) != 0) {
368 memcpy(ind_buf + 9, "X II", 4);
369 } else if ((inds & TN5250_DISPLAY_IND_X_CLOCK) != 0) {
370 memcpy(ind_buf + 9, "X CLOCK", 7);
371 } else if ((inds & TN5250_DISPLAY_IND_X_SYSTEM) != 0) {
372 memcpy(ind_buf + 9, "X SYSTEM", 8);
373 }
374 if ((inds & TN5250_DISPLAY_IND_INSERT) != 0) {
375 memcpy(ind_buf + 30, "IM", 2);
376 }
377 if ((inds & TN5250_DISPLAY_IND_MACRO) != 0) {
378 memcpy(ind_buf + 54, tn5250_macro_printstate (display), 11);
379 }
380 SLsmg_normal_video ();
381 SLsmg_gotorc (tn5250_display_height (display), 0);
382 SLsmg_write_nchars (ind_buf, 80);
383 SLsmg_gotorc (tn5250_display_cursor_y(display), tn5250_display_cursor_x(display));
384 SLsmg_refresh();
385 }
386
387 /****i* lib5250/slang_terminal_waitevent
388 * NAME
389 * slang_terminal_waitevent
390 * SYNOPSIS
391 * ret = slang_terminal_waitevent (This);
392 * INPUTS
393 * Tn5250Terminal * This -
394 * DESCRIPTION
395 * DOCUMENT ME!!!
396 *****/
slang_terminal_waitevent(Tn5250Terminal * This)397 static int slang_terminal_waitevent(Tn5250Terminal * This)
398 {
399 #if !defined(WIN32) && !defined(WINE)
400 fd_set fdr;
401 int result = 0;
402 int sm;
403
404 if (SLang_Error == USER_BREAK)
405 This->data->quit_flag = 1;
406 if (This->data->quit_flag)
407 return TN5250_TERMINAL_EVENT_QUIT;
408
409 FD_ZERO(&fdr);
410 FD_SET(0, &fdr);
411 sm = 1;
412 if (This->conn_fd >= 0) {
413 FD_SET(This->conn_fd, &fdr);
414 sm = This->conn_fd + 1;
415 }
416
417 select(sm, &fdr, NULL, NULL, NULL);
418
419 if (FD_ISSET(0, &fdr))
420 result |= TN5250_TERMINAL_EVENT_KEY;
421
422 if (This->conn_fd >= 0 && FD_ISSET(This->conn_fd, &fdr))
423 result |= TN5250_TERMINAL_EVENT_DATA;
424
425 return result;
426 #else
427 /* XXX: WIN32/WINE - need to do this using WaitForMultipleObjects */
428 #endif
429 }
430
431 /****i* lib5250/slang_terminal_getkey
432 * NAME
433 * slang_terminal_getkey
434 * SYNOPSIS
435 * ret = slang_terminal_getkey (This);
436 * INPUTS
437 * Tn5250Terminal * This -
438 * DESCRIPTION
439 * DOCUMENT ME!!!
440 *****/
slang_terminal_getkey(Tn5250Terminal * This)441 static int slang_terminal_getkey(Tn5250Terminal * This)
442 {
443 unsigned int key;
444
445 if (!SLang_input_pending (0))
446 return -1;
447
448 key = SLkp_getkey ();
449 while (1) {
450 switch (key) {
451 case 0x0d:
452 case 0x0a:
453 return K_ENTER;
454
455 case 0x1b:
456 if ((key = slang_terminal_get_esc_key(This, 1)) != SL_KEY_ERR)
457 return key;
458 break;
459
460 case K_CTRL('A'):
461 return K_ATTENTION;
462 case K_CTRL('B'):
463 return K_ROLLDN;
464 case K_CTRL('C'):
465 return K_SYSREQ;
466 case K_CTRL('D'):
467 return K_ROLLUP;
468 case K_CTRL('E'):
469 return K_ERASE;
470 case K_CTRL('F'):
471 return K_ROLLUP;
472 case K_CTRL('K'):
473 return K_FIELDEXIT;
474 case K_CTRL('L'):
475 return K_REFRESH;
476 case K_CTRL('O'):
477 return K_HOME;
478 case K_CTRL('P'):
479 return K_PRINT;
480 case K_CTRL('R'):
481 return K_RESET; /* Error Reset */
482 case K_CTRL('S'):
483 return K_MEMO;
484 case K_CTRL('T'):
485 return K_TESTREQ;
486 case K_CTRL('U'):
487 return K_ROLLDN;
488 case K_CTRL('W'):
489 return K_EXEC;
490 case K_CTRL('X'):
491 return K_FIELDEXIT;
492
493 case K_CTRL('Q'):
494 This->data->quit_flag = 1;
495 return -1;
496
497 case K_CTRL('G'): /* C-g <function-key-shortcut> */
498 if ((key = slang_terminal_get_esc_key(This, 0)) != SL_KEY_ERR)
499 return key;
500 break;
501
502 case SL_KEY_ERR:
503 if (SLang_Error == USER_BREAK)
504 This->data->quit_flag = 1;
505 return -1;
506
507 case SL_KEY_DELETE:
508 return K_DELETE;
509
510 case SL_KEY_F(1):
511 return K_F1;
512 case SL_KEY_F(2):
513 return K_F2;
514 case SL_KEY_F(3):
515 return K_F3;
516 case SL_KEY_F(4):
517 return K_F4;
518 case SL_KEY_F(5):
519 return K_F5;
520 case SL_KEY_F(6):
521 return K_F6;
522 case SL_KEY_F(7):
523 return K_F7;
524 case SL_KEY_F(8):
525 return K_F8;
526 case SL_KEY_F(9):
527 return K_F9;
528 case SL_KEY_F(10):
529 return K_F10;
530 case SL_KEY_F(11):
531 return K_F11;
532 case SL_KEY_F(12):
533 return K_F12;
534 case SL_KEY_F(13):
535 return K_F13;
536 case SL_KEY_F(14):
537 return K_F14;
538 case SL_KEY_F(15):
539 return K_F15;
540 case SL_KEY_F(16):
541 return K_F16;
542 case SL_KEY_F(17):
543 return K_F17;
544 case SL_KEY_F(18):
545 return K_F18;
546 case SL_KEY_F(19):
547 return K_F19;
548 case SL_KEY_F(20):
549 return K_F20;
550 case SL_KEY_F(21):
551 return K_F21;
552 case SL_KEY_F(22):
553 return K_F22;
554 case SL_KEY_F(23):
555 return K_F23;
556 case SL_KEY_F(24):
557 return K_F24;
558 case SL_KEY_BACKSPACE:
559 return K_BACKSPACE;
560 case SL_KEY_IC:
561 return K_INSERT;
562
563 case SL_KEY_HOME:
564 case SL_KEY_A1:
565 return K_HOME;
566
567 case SL_KEY_PPAGE:
568 case SL_KEY_A3:
569 return K_ROLLDN;
570
571 case SL_KEY_END:
572 case SL_KEY_C1:
573 return K_END;
574
575 case SL_KEY_NPAGE:
576 case SL_KEY_C3:
577 return K_ROLLUP;
578
579 case SL_KEY_ENTER:
580 return K_FIELDEXIT;
581
582 case SL_KEY_UP:
583 return K_UP;
584
585 case SL_KEY_DOWN:
586 return K_DOWN;
587
588 case SL_KEY_LEFT:
589 return K_LEFT;
590
591 case SL_KEY_RIGHT:
592 return K_RIGHT;
593
594 default:
595 return key;
596 }
597 }
598 }
599
600 /****i* lib5250/slang_terminal_beep
601 * NAME
602 * slang_terminal_beep
603 * SYNOPSIS
604 * slang_terminal_beep (This);
605 * INPUTS
606 * Tn5250Terminal * This -
607 * DESCRIPTION
608 * DOCUMENT ME!!!
609 *****/
slang_terminal_beep(Tn5250Terminal * This)610 static void slang_terminal_beep (Tn5250Terminal * This)
611 {
612 SLtt_beep ();
613 }
614
615
616 /***** lib5250/slang_terminal_enhanced
617 * NAME
618 * slang_terminal_enhanced
619 * SYNOPSIS
620 * ret = slang_terminal_enhanced (This);
621 * INPUTS
622 * Tn5250Terminal * This -
623 * DESCRIPTION
624 * Return 1 if we support the enhanced 5250 protocol, 0 otherwise.
625 *****/
626 static int
slang_terminal_enhanced(Tn5250Terminal * This)627 slang_terminal_enhanced (Tn5250Terminal * This)
628 {
629 return (0);
630 }
631
632
633 /****i* lib5250/slang_terminal_get_esc_key
634 * NAME
635 * slang_terminal_get_esc_key
636 * SYNOPSIS
637 * ret = slang_terminal_get_esc_key (This, is_esc);
638 * INPUTS
639 * Tn5250Terminal * This -
640 * int is_esc -
641 * DESCRIPTION
642 * If a vt100 escape key sequence was introduced (using either
643 * <Esc> or <Ctrl+g>), handle the next key in the sequence.
644 *****/
slang_terminal_get_esc_key(Tn5250Terminal * This,int is_esc)645 static int slang_terminal_get_esc_key(Tn5250Terminal * This, int is_esc)
646 {
647 int y, x, key, display_key;
648
649 y = SLsmg_get_row ();
650 x = SLsmg_get_column ();
651 SLsmg_normal_video ();
652 SLsmg_gotorc (This->data->last_height, 60);
653 if (is_esc)
654 SLsmg_write_string ("Esc ");
655 else
656 SLsmg_write_string ("C-g ");
657 SLsmg_gotorc (y, x);
658 SLsmg_refresh();
659
660 #if !defined(WIN32) && !defined(WINE)
661 {
662 fd_set fdr;
663 FD_ZERO(&fdr);
664 FD_SET(0, &fdr);
665 select(1, &fdr, NULL, NULL, NULL);
666 }
667 #else
668 /* XXX: What do we need that for? */
669 #endif
670 key = SLkp_getkey ();
671
672 if (isalpha(key))
673 key = toupper(key);
674
675 display_key = key;
676 switch (key) {
677
678 /* Function keys */
679 case '1':
680 key = K_F1;
681 break;
682 case '2':
683 key = K_F2;
684 break;
685 case '3':
686 key = K_F3;
687 break;
688 case '4':
689 key = K_F4;
690 break;
691 case '5':
692 key = K_F5;
693 break;
694 case '6':
695 key = K_F6;
696 break;
697 case '7':
698 key = K_F7;
699 break;
700 case '8':
701 key = K_F8;
702 break;
703 case '9':
704 key = K_F9;
705 break;
706 case '0':
707 key = K_F10;
708 break;
709 case '-':
710 key = K_F11;
711 break;
712 case '=':
713 key = K_F12;
714 break;
715 case '!':
716 key = K_F13;
717 break;
718 case '@':
719 key = K_F14;
720 break;
721 case '#':
722 key = K_F15;
723 break;
724 case '$':
725 key = K_F16;
726 break;
727 case '%':
728 key = K_F17;
729 break;
730 case '^':
731 key = K_F18;
732 break;
733 case '&':
734 key = K_F19;
735 break;
736 case '*':
737 key = K_F20;
738 break;
739 case '(':
740 key = K_F21;
741 break;
742 case ')':
743 key = K_F22;
744 break;
745 case '_':
746 key = K_F23;
747 break;
748 case '+':
749 key = K_F24;
750 break;
751
752 /* AS/400 strangeness */
753 case 'A':
754 key = K_ATTENTION;
755 break;
756 case 'C':
757 key = K_CLEAR;
758 break;
759 case 'D':
760 key = K_DUPLICATE;
761 break;
762 case 'H':
763 key = K_HELP;
764 break;
765 case 'I':
766 key = K_INSERT;
767 break;
768 case 'L':
769 key = K_REFRESH;
770 break;
771 case 'M':
772 key = K_FIELDMINUS;
773 break;
774 case 'P':
775 key = K_PRINT;
776 break;
777 case 'R':
778 key = K_RESET;
779 break;
780 case 'S':
781 key = K_SYSREQ;
782 break;
783 case 'T':
784 key = K_TOGGLE;
785 break;
786 case 'X':
787 key = K_FIELDEXIT;
788 break;
789
790 case 127:
791 key = K_INSERT;
792 break; /* ESC DEL */
793 case SL_KEY_DELETE:
794 key = K_INSERT;
795 break; /* ESC DEL, also */
796 case K_CTRL('J'):
797 key = K_NEWLINE;
798 break;
799
800 case 'Q':
801 This->data->quit_flag = 1;
802 key = SL_KEY_ERR;
803 break;
804
805 default:
806 SLtt_beep();
807 key = SL_KEY_ERR;
808 break;
809 }
810
811 SLsmg_gotorc (This->data->last_height, 64);
812 if (key == SL_KEY_ERR)
813 SLsmg_write_string ("???");
814 else
815 SLsmg_write_char (display_key);
816 SLsmg_gotorc (y, x);
817 SLsmg_refresh ();
818 return key;
819 }
820
821 /****i* lib5250/slang_terminal_set_attrs
822 * NAME
823 * slang_terminal_set_attrs
824 * SYNOPSIS
825 * slang_terminal_set_attrs (This, attrs);
826 * INPUTS
827 * Tn5250Terminal * This -
828 * int attrs -
829 * DESCRIPTION
830 * DOCUMENT ME!!!
831 *****/
slang_terminal_set_attrs(Tn5250Terminal * This,int attrs)832 static void slang_terminal_set_attrs (Tn5250Terminal * This, int attrs)
833 {
834 if (attrs == This->data->attrs)
835 return;
836 SLsmg_normal_video ();
837 SLsmg_set_color ((attrs & A_COLOR_MASK) >> 8);
838 if ((attrs & A_REVERSE) != 0)
839 SLsmg_reverse_video ();
840 /* FIXME: Handle A_BLINK */
841 This->data->attrs = attrs;
842 }
843
844 #else /* USE_SLANG */
845
846 /* When compiled with -Wall -pedantic: ANSI C forbids empty source file. */
847 struct NoSlang {
848 long dummy;
849 };
850
851 #endif /* USE_SLANG */
852
853 /* vi:set cindent sts=3 sw=3: */
854