1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 #include "os2.h"
28 #include "osctty.h"
29 #include "ossig.h"
30 
31 #define CONTROL_B_ENABLE		(0x1)
32 #define CONTROL_G_ENABLE		(0x2)
33 #define CONTROL_U_ENABLE		(0x4)
34 #define CONTROL_X_ENABLE		(0x8)
35 #define INTERACTIVE_INTERRUPT_ENABLE	(0x10)
36 #define TERMINATE_INTERRUPT_ENABLE	(0x20)
37 
38 #define ALL_ENABLES							\
39   (CONTROL_B_ENABLE | CONTROL_G_ENABLE | CONTROL_U_ENABLE | CONTROL_X_ENABLE)
40 
41 #define CONTROL_B			'\002'
42 #define CONTROL_G			'\007'
43 #define CONTROL_U			'\025'
44 #define CONTROL_X			'\030'
45 #define CONTROL_C			'\003'
46 
47 #define KB_INT_CHARS_SIZE 5
48 #define KB_INT_TABLE_SIZE 256
49 
50 static char keyboard_interrupt_characters [KB_INT_CHARS_SIZE];
51 static enum interrupt_handler keyboard_interrupt_handlers [KB_INT_CHARS_SIZE];
52 static enum interrupt_handler keyboard_interrupt_table [KB_INT_TABLE_SIZE];
53 static enum interrupt_handler keyboard_break_interrupt;
54 static Tinterrupt_enables keyboard_interrupt_enables;
55 
56 static void
update_keyboard_interrupt_characters(void)57 update_keyboard_interrupt_characters (void)
58 {
59   unsigned int i;
60   for (i = 0; (i < KB_INT_TABLE_SIZE); i += 1)
61     (keyboard_interrupt_table[i]) = interrupt_handler_ignore;
62   for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
63     (keyboard_interrupt_table [keyboard_interrupt_characters [i]]) =
64       (keyboard_interrupt_handlers[i]);
65 }
66 
67 void
OS2_initialize_keyboard_interrupts(void)68 OS2_initialize_keyboard_interrupts (void)
69 {
70   (keyboard_interrupt_characters[0]) = CONTROL_B;
71   (keyboard_interrupt_handlers[0]) = interrupt_handler_control_b;
72   (keyboard_interrupt_characters[1]) = CONTROL_G;
73   (keyboard_interrupt_handlers[1]) = interrupt_handler_control_g;
74   (keyboard_interrupt_characters[2]) = CONTROL_U;
75   (keyboard_interrupt_handlers[2]) = interrupt_handler_control_u;
76   (keyboard_interrupt_characters[3]) = CONTROL_X;
77   (keyboard_interrupt_handlers[3]) = interrupt_handler_control_x;
78   (keyboard_interrupt_characters[4]) = CONTROL_C;
79   (keyboard_interrupt_handlers[4]) = interrupt_handler_interactive;
80   keyboard_break_interrupt = interrupt_handler_terminate;
81   update_keyboard_interrupt_characters ();
82   keyboard_interrupt_enables = ALL_ENABLES;
83 }
84 
85 void
OS_ctty_get_interrupt_enables(Tinterrupt_enables * mask)86 OS_ctty_get_interrupt_enables (Tinterrupt_enables * mask)
87 {
88   (*mask) = keyboard_interrupt_enables;
89 }
90 
91 void
OS_ctty_set_interrupt_enables(Tinterrupt_enables * mask)92 OS_ctty_set_interrupt_enables (Tinterrupt_enables * mask)
93 {
94   keyboard_interrupt_enables = ((*mask) & ALL_ENABLES);
95 }
96 
97 unsigned int
OS_ctty_num_int_chars(void)98 OS_ctty_num_int_chars (void)
99 {
100   return (KB_INT_CHARS_SIZE + 1);
101 }
102 
103 cc_t
OS_tty_map_interrupt_char(cc_t int_char)104 OS_tty_map_interrupt_char (cc_t int_char)
105 {
106   return (int_char);
107 }
108 
109 cc_t *
OS_ctty_get_int_chars(void)110 OS_ctty_get_int_chars (void)
111 {
112   static cc_t characters [KB_INT_CHARS_SIZE + 1];
113   unsigned int i;
114   for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
115     (characters[i]) = (keyboard_interrupt_characters[i]);
116   (characters[i]) = '\0';	/* dummy for control-break */
117   return (characters);
118 }
119 
120 void
OS_ctty_set_int_chars(cc_t * characters)121 OS_ctty_set_int_chars (cc_t * characters)
122 {
123   unsigned int i;
124   for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
125     (keyboard_interrupt_characters[i]) = (characters[i]);
126   update_keyboard_interrupt_characters ();
127 }
128 
129 cc_t *
OS_ctty_get_int_char_handlers(void)130 OS_ctty_get_int_char_handlers (void)
131 {
132   static cc_t handlers [KB_INT_CHARS_SIZE + 1];
133   unsigned int i;
134   for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
135     (handlers[i]) = ((cc_t) (keyboard_interrupt_handlers[i]));
136   (handlers[i]) = ((cc_t) keyboard_break_interrupt);
137   return (handlers);
138 }
139 
140 void
OS_ctty_set_int_char_handlers(cc_t * handlers)141 OS_ctty_set_int_char_handlers (cc_t * handlers)
142 {
143   unsigned int i;
144   for (i = 0; (i < KB_INT_CHARS_SIZE); i += 1)
145     (keyboard_interrupt_handlers[i]) =
146       ((enum interrupt_handler) (handlers[i]));
147   keyboard_break_interrupt = ((enum interrupt_handler) (handlers[i]));
148   update_keyboard_interrupt_characters ();
149 }
150 
151 static char
check_if_enabled(enum interrupt_handler handler)152 check_if_enabled (enum interrupt_handler handler)
153 {
154   unsigned int bitmask;
155   char result;
156   switch (handler)
157     {
158     case interrupt_handler_control_b:
159       bitmask = CONTROL_B_ENABLE;
160       result = 'B';
161       break;
162     case interrupt_handler_control_g:
163       bitmask = CONTROL_G_ENABLE;
164       result = 'G';
165       break;
166     case interrupt_handler_control_u:
167       bitmask = CONTROL_U_ENABLE;
168       result = 'U';
169       break;
170     case interrupt_handler_control_x:
171       bitmask = CONTROL_X_ENABLE;
172       result = 'X';
173       break;
174     case interrupt_handler_interactive:
175       bitmask = INTERACTIVE_INTERRUPT_ENABLE;
176       result = '!';
177       break;
178     case interrupt_handler_terminate:
179       bitmask = TERMINATE_INTERRUPT_ENABLE;
180       result = '@';
181       break;
182     default:
183       bitmask = 0;
184       result = '\0';
185       break;
186     }
187   return (((keyboard_interrupt_enables & bitmask) == 0) ? '\0' : result);
188 }
189 
190 char
OS2_keyboard_interrupt_handler(char c)191 OS2_keyboard_interrupt_handler (char c)
192 {
193   return (check_if_enabled (keyboard_interrupt_table[c]));
194 }
195 
196 char
OS2_keyboard_break_interrupt_handler(void)197 OS2_keyboard_break_interrupt_handler (void)
198 {
199   return (check_if_enabled (keyboard_break_interrupt));
200 }
201