1 /* This module implements an interface to the SLang SMG routines */
2 /* -*- mode: C; mode: fold -*-
3 Copyright (C) 2010-2017,2018 John E. Davis
4 
5 This file is part of the S-Lang Library.
6 
7 The S-Lang Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11 
12 The S-Lang Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 USA.
21 */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <slang.h>
25 
26 SLANG_MODULE(slsmg);
27 
28 /* If this is +1, the then it is ok to call the SLsmg routines.  If it is
29  * 0, then only SLsmg_init_smg may be called.  If it is -1, then SLsmg is
30  * suspended and one must call SLsmg_resume_smg.
31  */
32 
33 static int Smg_Initialized;
34 
35 #ifndef IBMPC_SYSTEM
smg_write_to_status_line(char * s)36 static void smg_write_to_status_line (char *s)
37 {
38    if (Smg_Initialized <= 0)
39      return;
40 
41    (void) SLtt_write_to_status_line (s, 0);
42 }
43 #endif
44 
smg_suspend_smg(void)45 static void smg_suspend_smg (void)
46 {
47    if (Smg_Initialized <= 0)
48      return;
49 
50    (void) SLsmg_suspend_smg ();
51    Smg_Initialized = -1;
52 }
53 
smg_resume_smg(void)54 static void smg_resume_smg (void)
55 {
56    if (Smg_Initialized != -1)
57      return;
58 
59    (void) SLsmg_resume_smg ();
60    Smg_Initialized = 1;
61 }
62 
smg_erase_eol(void)63 static void smg_erase_eol (void)
64 {
65    if (Smg_Initialized <= 0)
66      return;
67    SLsmg_erase_eol ();
68 }
69 
smg_gotorc(int * r,int * c)70 static void smg_gotorc (int *r, int *c)
71 {
72    if (Smg_Initialized <= 0)
73      return;
74    SLsmg_gotorc (*r, *c);
75 }
76 
smg_erase_eos(void)77 static void smg_erase_eos (void)
78 {
79    if (Smg_Initialized <= 0)
80      return;
81    SLsmg_erase_eos ();
82 }
83 
smg_reverse_video(void)84 static void smg_reverse_video (void)
85 {
86    if (Smg_Initialized <= 0)
87      return;
88    SLsmg_reverse_video ();
89 }
90 
smg_set_color(int * c)91 static void smg_set_color (int *c)
92 {
93    if (Smg_Initialized <= 0)
94      return;
95    SLsmg_set_color (*c);
96 }
97 
smg_normal_video(void)98 static void smg_normal_video (void)
99 {
100    if (Smg_Initialized <= 0)
101      return;
102    SLsmg_normal_video ();
103 }
104 
smg_write_string(char * s)105 static void smg_write_string (char *s)
106 {
107    if (Smg_Initialized <= 0)
108      return;
109    SLsmg_write_string (s);
110 }
111 
smg_write_nstring(char * s,int * len)112 static void smg_write_nstring (char *s, int *len)
113 {
114    if ((Smg_Initialized <= 0)
115        || (*len < 0))
116      return;
117 
118    SLsmg_write_nstring (s, (unsigned int) *len);
119 }
120 
smg_write_wrapped_string(char * s,int * r,int * c,int * dr,int * dc,int * fill)121 static void smg_write_wrapped_string (char *s, int *r, int *c, int *dr, int *dc,
122 				      int *fill)
123 {
124    if (Smg_Initialized <= 0)
125      return;
126 
127    SLsmg_write_wrapped_string ((SLuchar_Type *)s, *r, *c, *dr, *dc, *fill);
128 }
129 
smg_char_at(void)130 static int smg_char_at (void)
131 {
132    SLsmg_Char_Type c;
133    if (Smg_Initialized <= 0) return -1;
134 
135    if (-1 == SLsmg_char_at (&c))
136      return 0;
137 
138    if (c.nchars == 0)
139      return 0;
140 
141    return (int) c.wchars[0];
142 }
143 
smg_set_screen_start(int * rp,int * cp)144 static void smg_set_screen_start (int *rp, int *cp)
145 {
146    int r, c;
147 
148    if (Smg_Initialized <= 0) return;
149    r = *rp;
150    c = *cp;
151    SLsmg_set_screen_start (&r, &c);
152 }
153 
smg_draw_hline(int * dn)154 static void smg_draw_hline (int *dn)
155 {
156    if (Smg_Initialized <= 0)
157      return;
158 
159    SLsmg_draw_hline (*dn);
160 }
161 
smg_draw_vline(int * dn)162 static void smg_draw_vline (int *dn)
163 {
164    if (Smg_Initialized <= 0)
165      return;
166 
167    SLsmg_draw_vline (*dn);
168 }
169 
smg_draw_object(int * r,int * c,int * obj)170 static void smg_draw_object (int *r, int *c, int *obj)
171 {
172    if (Smg_Initialized <= 0) return;
173    SLsmg_draw_object (*r, *c, *obj);
174 }
175 
smg_draw_box(int * r,int * c,int * dr,int * dc)176 static void smg_draw_box (int *r, int *c,int *dr, int *dc)
177 {
178    if (Smg_Initialized <= 0) return;
179    SLsmg_draw_box (*r, *c, *dr, *dc);
180 }
181 
smg_get_column(void)182 static int smg_get_column (void)
183 {
184    if (Smg_Initialized <= 0) return -1;
185    return SLsmg_get_column();
186 }
187 
smg_get_row(void)188 static int smg_get_row (void)
189 {
190    if (Smg_Initialized <= 0) return -1;
191    return SLsmg_get_row();
192 }
193 
smg_forward(int * n)194 static void smg_forward (int *n)
195 {
196    if (Smg_Initialized <= 0) return;
197    SLsmg_forward (*n);
198 }
199 
smg_set_color_in_region(int * color,int * r,int * c,int * dr,int * dc)200 static void smg_set_color_in_region (int *color, int *r, int *c, int *dr, int *dc)
201 {
202    if (Smg_Initialized <= 0) return;
203    SLsmg_set_color_in_region (*color, *r, *c, *dr, *dc);
204 }
205 
smg_cls(void)206 static void smg_cls (void)
207 {
208    if (Smg_Initialized <= 0)
209      return;
210    SLsmg_cls ();
211 }
212 
smg_refresh(void)213 static void smg_refresh (void)
214 {
215    if (Smg_Initialized <= 0)
216      return;
217    SLsig_block_signals ();
218    SLsmg_refresh ();
219    SLsig_unblock_signals ();
220 }
221 
smg_reset_smg(void)222 static void smg_reset_smg (void)
223 {
224    if (Smg_Initialized <= 0)
225      return;
226    SLsig_block_signals ();
227    SLsmg_reset_smg ();
228    SLsig_unblock_signals ();
229    Smg_Initialized = 0;
230 }
231 
smg_init_smg(void)232 static void smg_init_smg (void)
233 {
234    if (Smg_Initialized != 0)
235      return;
236    SLsig_block_signals ();
237    (void) SLsmg_init_smg ();
238    SLsig_unblock_signals ();
239    Smg_Initialized = 1;
240 }
241 
smg_define_color(int * obj,char * fg,char * bg)242 static void smg_define_color (int *obj, char *fg, char *bg)
243 {
244    SLtt_set_color (*obj, NULL, fg, bg);
245 }
246 
247 #define I SLANG_INT_TYPE
248 #define S SLANG_STRING_TYPE
249 static SLang_Intrin_Fun_Type Smg_Intrinsics [] =
250 {
251    MAKE_INTRINSIC_0("slsmg_suspend_smg", smg_suspend_smg, SLANG_VOID_TYPE),
252    MAKE_INTRINSIC_0("slsmg_resume_smg", smg_resume_smg, SLANG_VOID_TYPE),
253    MAKE_INTRINSIC_0("slsmg_erase_eol", smg_erase_eol, SLANG_VOID_TYPE),
254    MAKE_INTRINSIC_II("slsmg_gotorc", smg_gotorc, SLANG_VOID_TYPE),
255    MAKE_INTRINSIC_0("slsmg_erase_eos", smg_erase_eos, SLANG_VOID_TYPE),
256    MAKE_INTRINSIC_0("slsmg_reverse_video", smg_reverse_video, SLANG_VOID_TYPE),
257    MAKE_INTRINSIC_I("slsmg_set_color", smg_set_color, SLANG_VOID_TYPE),
258    MAKE_INTRINSIC_0("slsmg_normal_video", smg_normal_video, SLANG_VOID_TYPE),
259    MAKE_INTRINSIC_S("slsmg_write_string", smg_write_string, SLANG_VOID_TYPE),
260    MAKE_INTRINSIC_0("slsmg_cls", smg_cls, SLANG_VOID_TYPE),
261    MAKE_INTRINSIC_0("slsmg_refresh", smg_refresh, SLANG_VOID_TYPE),
262    MAKE_INTRINSIC_0("slsmg_reset_smg", smg_reset_smg, SLANG_VOID_TYPE),
263    MAKE_INTRINSIC_0("slsmg_init_smg", smg_init_smg, SLANG_VOID_TYPE),
264 
265    MAKE_INTRINSIC_SI("slsmg_write_nstring", smg_write_nstring, SLANG_VOID_TYPE),
266    MAKE_INTRINSIC_6("slsmg_write_wrapped_string", smg_write_wrapped_string, SLANG_VOID_TYPE, S,I,I,I,I,I),
267    MAKE_INTRINSIC_0("slsmg_char_at", smg_char_at, SLANG_INT_TYPE),
268    MAKE_INTRINSIC_II("slsmg_set_screen_start", smg_set_screen_start, SLANG_VOID_TYPE),
269    MAKE_INTRINSIC_I("slsmg_draw_hline", smg_draw_hline, SLANG_VOID_TYPE),
270    MAKE_INTRINSIC_I("slsmg_draw_vline", smg_draw_vline, SLANG_VOID_TYPE),
271    MAKE_INTRINSIC_III("slsmg_draw_object", smg_draw_object, SLANG_VOID_TYPE),
272    MAKE_INTRINSIC_4("slsmg_draw_box", smg_draw_box, SLANG_VOID_TYPE,I,I,I,I),
273    MAKE_INTRINSIC_0("slsmg_get_column", smg_get_column, SLANG_INT_TYPE),
274    MAKE_INTRINSIC_0("slsmg_get_row", smg_get_row, SLANG_INT_TYPE),
275    MAKE_INTRINSIC_I("slsmg_forward", smg_forward, SLANG_VOID_TYPE),
276    MAKE_INTRINSIC_5("slsmg_set_color_in_region", smg_set_color_in_region, SLANG_VOID_TYPE, I, I, I, I, I),
277 
278    MAKE_INTRINSIC_ISS("slsmg_define_color", smg_define_color, SLANG_VOID_TYPE),
279 #ifndef IBMPC_SYSTEM
280    MAKE_INTRINSIC_S("slsmg_write_to_status_line", smg_write_to_status_line, SLANG_VOID_TYPE),
281 #endif
282    SLANG_END_INTRIN_FUN_TABLE
283 };
284 
285 static SLang_IConstant_Type Smg_Constants [] =
286 {
287    MAKE_ICONSTANT("SLSMG_NEWLINE_IGNORED", SLSMG_NEWLINE_IGNORED),
288    MAKE_ICONSTANT("SLSMG_NEWLINE_MOVES", SLSMG_NEWLINE_MOVES),
289    MAKE_ICONSTANT("SLSMG_NEWLINE_SCROLLS", SLSMG_NEWLINE_SCROLLS),
290    MAKE_ICONSTANT("SLSMG_NEWLINE_PRINTABLE", SLSMG_NEWLINE_PRINTABLE),
291 
292    MAKE_ICONSTANT("SLSMG_HLINE_CHAR", SLSMG_HLINE_CHAR),
293    MAKE_ICONSTANT("SLSMG_VLINE_CHAR", SLSMG_VLINE_CHAR),
294    MAKE_ICONSTANT("SLSMG_ULCORN_CHAR", SLSMG_ULCORN_CHAR),
295    MAKE_ICONSTANT("SLSMG_URCORN_CHAR", SLSMG_URCORN_CHAR),
296    MAKE_ICONSTANT("SLSMG_LLCORN_CHAR", SLSMG_LLCORN_CHAR),
297    MAKE_ICONSTANT("SLSMG_LRCORN_CHAR", SLSMG_LRCORN_CHAR),
298    MAKE_ICONSTANT("SLSMG_CKBRD_CHAR", SLSMG_CKBRD_CHAR),
299    MAKE_ICONSTANT("SLSMG_RTEE_CHAR", SLSMG_RTEE_CHAR),
300    MAKE_ICONSTANT("SLSMG_LTEE_CHAR", SLSMG_LTEE_CHAR),
301    MAKE_ICONSTANT("SLSMG_UTEE_CHAR", SLSMG_UTEE_CHAR),
302    MAKE_ICONSTANT("SLSMG_DTEE_CHAR", SLSMG_DTEE_CHAR),
303    MAKE_ICONSTANT("SLSMG_PLUS_CHAR", SLSMG_PLUS_CHAR),
304 
305    SLANG_END_ICONST_TABLE
306 };
307 #undef I
308 #undef S
309 
init_slsmg_module_ns(char * ns_name)310 int init_slsmg_module_ns (char *ns_name)
311 {
312    SLang_NameSpace_Type *ns;
313    static int inited = 0;
314 
315    if (inited == 0)
316      {
317 #if defined(VMS) || defined(REAL_UNIX_SYSTEM)
318 	int status;
319 	char *term = getenv ("TERM");
320 
321 	if (term == NULL)
322 	  {
323 	     SLang_verror (SL_Application_Error, "The TERM environment variable is not set");
324 	     return -1;
325 	  }
326 	status = SLtt_initialize (term);
327 	if (status == -1)
328 	  {
329 	     SLang_verror (SL_RunTime_Error, "Cannot deduce properties for '%s' terminal", term);
330 	     return -1;
331 	  }
332 	if (status < 0)
333 	  {
334 	     SLang_verror (SL_RunTime_Error, "The terminal '%s' lacks sufficient capabilities for controlling it", term);
335 	     return -1;
336 	  }
337 #else
338 	SLtt_get_terminfo ();
339 #endif
340 	inited = 1;
341      }
342 
343    ns = SLns_create_namespace (ns_name);
344    if (ns == NULL)
345      return -1;
346 
347    if ((-1 == SLns_add_intrin_fun_table (ns, Smg_Intrinsics, "__SLSMG__"))
348        || (-1 == SLns_add_iconstant_table (ns, Smg_Constants, NULL)))
349      return -1;
350 
351    if ((-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Display_Eight_Bit", (VOID_STAR)&SLsmg_Display_Eight_Bit, SLANG_INT_TYPE, 0))
352        || (-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Tab_Width", (VOID_STAR)&SLsmg_Tab_Width, SLANG_INT_TYPE, 0))
353        || (-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Newline_Behavior", (VOID_STAR)&SLsmg_Newline_Behavior, SLANG_INT_TYPE, 0))
354        || (-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Backspace_Moves", (VOID_STAR)&SLsmg_Backspace_Moves, SLANG_INT_TYPE, 0))
355        || (-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Screen_Rows", (VOID_STAR)&SLtt_Screen_Rows, SLANG_INT_TYPE, 0))
356        || (-1 == SLns_add_intrinsic_variable(ns, "SLsmg_Screen_Cols", (VOID_STAR)&SLtt_Screen_Cols, SLANG_INT_TYPE, 0)))
357      return -1;
358 
359    Smg_Initialized = 0;
360    return 0;
361 }
362 
363 /* This function is optional */
deinit_slsmg_module(void)364 void deinit_slsmg_module (void)
365 {
366    smg_reset_smg ();
367 }
368