1 /* Copyright (c) 2002, 2003, 2004, 2005, 2006 John E. Davis
2  * This file is part of JED editor library source.
3  *
4  * You may distribute this file under the terms the GNU General Public
5  * License.  See the file COPYING for more information.
6  */
7 #include "config.h"
8 #include "jed-feat.h"
9 
10 #include <stdio.h>
11 
12 #ifdef HAVE_STDLIB_H
13 # include <stdlib.h>
14 #endif
15 #include <string.h>
16 #include <slang.h>
17 
18 #include "colors.h"
19 #include "buffer.h"
20 #include "screen.h"
21 #include "display.h"
22 #include "misc.h"
23 
24 typedef struct
25 {
26    char *name;			       /* slstring for new objects */
27    int color;
28    char *fg;			       /* slstring */
29    char *bg;			       /* slstring */
30 }
31 Color_Object_Map_Type;
32 
33 static Color_Object_Map_Type Color_Name_Map [JMAX_COLORS] =
34 {
35    /* %%% COLOR-TABLE-START %%% -- tag used by external script to sync color files */
36    {"normal",		JNORMAL_COLOR, NULL, NULL},
37    {"cursor",		JCURSOR_COLOR, NULL, NULL},
38    {"status",		JSTATUS_COLOR, NULL, NULL},
39    {"region",		JREGION_COLOR, NULL, NULL},
40    {"menu",		JMENU_COLOR, NULL, NULL},
41    {"operator",		JOP_COLOR, NULL, NULL},
42    {"number",		JNUM_COLOR, NULL, NULL},
43    {"string",		JSTR_COLOR, NULL, NULL},
44    {"comment",		JCOM_COLOR, NULL, NULL},
45    {"delimiter",	JDELIM_COLOR, NULL, NULL},
46    {"preprocess",	JPREPROC_COLOR, NULL, NULL},
47    {"message",		JMESSAGE_COLOR, NULL, NULL},
48    {"error",		JERROR_COLOR, NULL, NULL},
49    {"dollar",		JDOLLAR_COLOR, NULL, NULL},
50 #if JED_HAS_LINE_ATTRIBUTES
51    {"...",		JDOTS_COLOR, NULL, NULL},
52 #endif
53 #if JED_HAS_MENUS
54    {"menu_char",	JMENU_CHAR_COLOR, NULL, NULL},
55    {"menu_shadow",	JMENU_SHADOW_COLOR, NULL, NULL},
56    {"menu_selection",	JMENU_SELECTION_COLOR, NULL, NULL},
57    {"menu_popup",	JMENU_POPUP_COLOR, NULL, NULL},
58    {"menu_selection_char", JMENU_SELECTED_CHAR_COLOR, NULL, NULL},
59 #endif
60    {"cursorovr",	JCURSOROVR_COLOR, NULL, NULL},
61    {"linenum",		JLINENUM_COLOR, NULL, NULL},
62    {"trailing_whitespace", JTWS_COLOR, NULL, NULL},
63    {"tab",		JTAB_COLOR, NULL, NULL},
64    /* These may be useful for some modes */
65    {"url",		JURL_COLOR, NULL, NULL},
66    {"italic",		JITALIC_COLOR, NULL, NULL},
67    {"underline",	JUNDERLINE_COLOR, NULL, NULL},
68    {"bold",		JBOLD_COLOR, NULL, NULL},
69    {"html",		JHTML_KEY_COLOR, NULL, NULL},
70    {"keyword",		JKEY_COLOR, NULL, NULL},
71    {"keyword1",		JKEY1_COLOR, NULL, NULL},
72    {"keyword2",		JKEY2_COLOR, NULL, NULL},
73    {"keyword3",		JKEY3_COLOR, NULL, NULL},
74    {"keyword4",		JKEY4_COLOR, NULL, NULL},
75    {"keyword5",		JKEY5_COLOR, NULL, NULL},
76    {"keyword6",		JKEY6_COLOR, NULL, NULL},
77    {"keyword7",		JKEY7_COLOR, NULL, NULL},
78    {"keyword8",		JKEY8_COLOR, NULL, NULL},
79    {"keyword9",		JKEY9_COLOR, NULL, NULL},
80    /* The rest of the colors are user-defined, and the strings are slstrings */
81    /* %%% COLOR-TABLE-STOP %%% */
82    {NULL, -1, NULL, NULL}
83 };
84 
85 
jed_get_color_obj(char * name)86 int jed_get_color_obj (char *name) /*{{{*/
87 {
88    Color_Object_Map_Type *map, *map_max;
89    char ch;
90 
91    map = Color_Name_Map;
92    map_max = Color_Name_Map + JMAX_COLORS;
93    ch = *name;
94    while (map < map_max)
95      {
96 	if (map->name == NULL)
97 	  {
98 	     if (map < Color_Name_Map + FIRST_USER_COLOR)
99 	       {
100 		  map = Color_Name_Map + FIRST_USER_COLOR;
101 		  continue;
102 	       }
103 	     break;
104 	  }
105 	if ((ch == map->name[0])
106 	    && (0 == strcmp (map->name, name)))
107 	  return map->color;
108 
109 	map++;
110      }
111 
112    if (0 == strcmp (name, "keyword0"))
113      return JKEY_COLOR;
114 
115    return -1;
116 }
117 
118 /*}}}*/
119 
add_color_object(char * name)120 static int add_color_object (char *name)
121 {
122    int obj;
123    Color_Object_Map_Type *map, *map_max;
124 
125    obj = jed_get_color_obj (name);
126    if (obj != -1)
127      return obj;
128 
129    map = Color_Name_Map + FIRST_USER_COLOR;
130    map_max = Color_Name_Map + JMAX_COLORS;
131    while (map < map_max)
132      {
133 	if (map->name != NULL)
134 	  {
135 	     map++;
136 	     continue;
137 	  }
138 	if (NULL == (name = SLang_create_slstring (name)))
139 	  return -1;
140 
141 	map->name = name;
142 	map->color = (int) (map - Color_Name_Map);
143 	return map->color;
144      }
145 
146    jed_vmessage (0, "*** Warning: no colors available for %s ***", name);
147    return -1;
148 }
149 
jed_set_color(int obj,char * fg,char * bg)150 int jed_set_color (int obj, char *fg, char *bg) /*{{{*/
151 {
152    Color_Object_Map_Type *map;
153 
154    if ((obj < 0) || (obj >= JMAX_COLORS))
155      return -1;
156 
157    tt_set_color (obj, NULL, fg, bg);
158    map = Color_Name_Map + obj;
159    if (NULL == (fg = SLang_create_slstring (fg)))
160      return -1;
161    if (NULL == (bg = SLang_create_slstring (bg)))
162      {
163 	SLang_free_slstring (fg);
164 	return -1;
165      }
166    SLang_free_slstring (map->fg); map->fg = fg;
167    SLang_free_slstring (map->bg); map->bg = bg;
168 
169    return 0;
170 }
171 
172 /* Intrinsics */
173 
set_color(char * obj,char * fg,char * bg)174 static void set_color (char *obj, char *fg, char *bg) /*{{{*/
175 {
176    int i;
177 
178    if (-1 != (i = jed_get_color_obj (obj)))
179      (void) jed_set_color (i, fg, bg);
180 }
181 
182 /*}}}*/
183 
get_color(char * obj)184 static void get_color (char *obj)
185 {
186    int i;
187    Color_Object_Map_Type *map;
188 
189    i = jed_get_color_obj (obj);
190 
191    /* object may have not been allocated which in practical terms means that
192     * the "normal" color will be used for the object.
193     */
194    if (i == -1)
195      i = JNORMAL_COLOR;
196 
197    map = Color_Name_Map + i;
198    (void) SLang_push_string (map->fg == NULL ? "default" : map->fg);
199    (void) SLang_push_string (map->bg == NULL ? "default" : map->bg);
200 }
201 
add_color_object_cmd(char * name)202 static void add_color_object_cmd (char *name)
203 {
204    (void) add_color_object (name);
205 }
206 
207 #ifndef IBMPC_SYSTEM
set_color_esc(char * obj,char * esc)208 static void set_color_esc (char *obj, char *esc) /*{{{*/
209 {
210 # if SLANG_VERSION < 20000
211    int i;
212 
213    if (tt_set_color_esc == NULL) return;
214    if (-1 != (i = jed_get_color_obj (obj)))
215      tt_set_color_esc (i, esc);
216 # else
217    (void) obj; (void) esc;
218 #endif
219 }
220 
221 /*}}}*/
222 #endif
223 
set_color_object(int * obj,char * fg,char * bg)224 static void set_color_object (int *obj, char *fg, char *bg)
225 {
226    (void) jed_set_color(*obj, fg, bg);
227 }
228 
229 
230 #if JED_HAS_COLOR_COLUMNS
set_column_colors(int * color,int * c0p,int * c1p)231 static void set_column_colors (int *color, int *c0p, int *c1p) /*{{{*/
232 {
233    unsigned char *p, *pmax, ch;
234    int c0, c1;
235    unsigned int num;
236 
237    if ((*color < 0) || (*color >= JMAX_COLORS)) return;
238    ch = (unsigned char) *color;
239 
240    c0 = *c0p - 1;
241    c1 = *c1p;
242 
243    if (c0 < 0) c0 = 0;
244    if (c1 <= c0) return;
245 
246    if ((NULL == (p = CBuf->column_colors))
247        || (c1 > (int) CBuf->num_column_colors))
248      {
249 	num = c1 + Jed_Num_Screen_Cols;
250 	p = (unsigned char *) SLrealloc ((char *)p, num);
251 	if (p == NULL)
252 	  return;
253 	CBuf->column_colors = p;
254 	CBuf->num_column_colors = num;
255 	SLMEMSET ((char *) p, 0, num);
256      }
257 
258    CBuf->coloring_style = 1;
259 
260    pmax = p + c1;
261    p += c0;
262    while (p < pmax) *p++ = ch;
263 }
264 
265 /*}}}*/
266 
267 #endif
268 
set_line_color(int * color)269 static void set_line_color (int *color)
270 {
271    int c = *color;
272    if (c < 0)
273      return;
274    JED_SET_LINE_COLOR (CLine, c);
275 }
276 
get_line_color(void)277 static int get_line_color (void)
278 {
279    return (int)JED_GET_LINE_COLOR(CLine);
280 }
281 
282 
283 static SLang_Intrin_Fun_Type Color_Intrinsics [] = /*{{{*/
284 {
285    MAKE_INTRINSIC_I("set_line_color", set_line_color, SLANG_VOID_TYPE),
286    MAKE_INTRINSIC_0("get_line_color", get_line_color, SLANG_INT_TYPE),
287    MAKE_INTRINSIC_SSS("_set_color", set_color, VOID_TYPE),
288    MAKE_INTRINSIC_S("color_number", jed_get_color_obj, INT_TYPE),
289    MAKE_INTRINSIC_S("get_color", get_color, VOID_TYPE),
290    MAKE_INTRINSIC_S("add_color_object", add_color_object_cmd, VOID_TYPE),
291 #ifndef IBMPC_SYSTEM
292    MAKE_INTRINSIC_SS("set_color_esc", set_color_esc, VOID_TYPE),
293 #endif
294 #if JED_HAS_COLOR_COLUMNS
295    MAKE_INTRINSIC_III("set_column_colors", set_column_colors, VOID_TYPE),
296    MAKE_INTRINSIC_ISS("set_color_object", set_color_object, VOID_TYPE),
297 #endif
298    SLANG_END_INTRIN_FUN_TABLE
299 };
300 
jed_init_color_intrinsics(void)301 int jed_init_color_intrinsics (void)
302 {
303    int i;
304 
305 #if 1
306    /* Sanity check */
307    for (i = 0; i < JMAX_COLORS; i++)
308      {
309 	if ((Color_Name_Map[i].name != NULL)
310 	    && (i != Color_Name_Map[i].color))
311 	  {
312 	     jed_verror ("Internal Error: Color Table is corrupt");
313 	     return -1;
314 	  }
315      }
316 #endif
317 
318    if (-1 == SLadd_intrin_fun_table (Color_Intrinsics, NULL))
319      return -1;
320 
321    return 0;
322 }
323 
324