Browse code

Theme support

Dario Rodriguez authored on 25/09/2023 14:29:12
Showing 1 changed files
... ...
@@ -47,21 +47,57 @@
47 47
 #define COMMAND_EXIT "Exit"
48 48
 
49 49
 /* "forest" theme */
50
-#define COLOR_STATUSBG "\x14\x3a\xaf\xff"
51
-#define COLOR_STATUSFG "\xe6\xdc\x5d\xff"
52
-#define COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
53
-
54
-#define COLOR_QUERYBG "\xad\x92\x5e\xff"
55
-#define COLOR_QUERYFG "\xd0\xef\x4f\xff"
56
-#define COLOR_QUERYBGOLD "\x83\x75\x59\xff"
57
-#define COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
58
-
59
-#define COLOR_WARNINGBG "\xba\x07\x07\xff"
60
-#define COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
61
-
62
-#define COLOR_INFOBG "\x4e\x8a\x4e\xff"
63
-#define COLOR_INFOFG "\xee\xee\x46\xff"
64
-#define COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
50
+#define DEFAULT_COLOR_BACKGROUND "\xdf\xdf\xdf\xff"
51
+#define DEFAULT_COLOR_PRINTOUTSTRIPE "\xef\xef\xef\xff"
52
+
53
+#define DEFAULT_COLOR_CURSORBG "\x00\x00\x00\xff"
54
+#define DEFAULT_COLOR_CURSORFG "\xff\xff\xff\xff"
55
+
56
+#define DEFAULT_COLOR_TEXT "\x00\x00\x00\xff"
57
+
58
+#define DEFAULT_COLOR_MATCHBG "\xff\xff\xff\xaf"
59
+#define DEFAULT_COLOR_MATCHFG "\xff\x00\x00\x80"
60
+
61
+#define DEFAULT_COLOR_STATUSBG "\x14\x3a\xaf\xff"
62
+#define DEFAULT_COLOR_STATUSFG "\xe6\xdc\x5d\xff"
63
+#define DEFAULT_COLOR_STATUSFGLIGHT "\x6f\x73\xa3\xff"
64
+
65
+#define DEFAULT_COLOR_QUERYBG "\xad\x92\x5e\xff"
66
+#define DEFAULT_COLOR_QUERYFG "\xd0\xef\x4f\xff"
67
+#define DEFAULT_COLOR_QUERYBGOLD "\x83\x75\x59\xff"
68
+#define DEFAULT_COLOR_QUERYFGOLD "\xb1\xc5\x5e\xff"
69
+
70
+#define DEFAULT_COLOR_WARNINGBG "\xba\x07\x07\xff"
71
+#define DEFAULT_COLOR_WARNINGFG "\xe6\xdc\x5d\xff"
72
+
73
+#define DEFAULT_COLOR_INFOBG "\x4e\x8a\x4e\xff"
74
+#define DEFAULT_COLOR_INFOFG "\xee\xee\x46\xff"
75
+#define DEFAULT_COLOR_INFOFGLIGHT "\x84\xa4\x4c\xff"
76
+
77
+#define DEFAULT_COLOR_SELNORMAL "\xde\xcf\x7f\xff"
78
+#define DEFAULT_COLOR_CURLINE "\xf0\xea\xc9\xff"
79
+
80
+#define COLOR_BACKGROUND(re) re->theme.color_background
81
+#define COLOR_PRINTOUTSTRIPE(re) re->theme.color_printoutstripe
82
+#define COLOR_CURSORBG(re) re->theme.color_cursorbg
83
+#define COLOR_CURSORFG(re) re->theme.color_cursorfg
84
+#define COLOR_TEXT(re) re->theme.color_text
85
+#define COLOR_MATCHBG(re) re->theme.color_matchbg
86
+#define COLOR_MATCHFG(re) re->theme.color_matchfg
87
+#define COLOR_STATUSBG(re) re->theme.color_statusbg
88
+#define COLOR_STATUSFG(re) re->theme.color_statusfg
89
+#define COLOR_STATUSFGLIGHT(re) re->theme.color_statusfglight
90
+#define COLOR_QUERYBG(re) re->theme.color_querybg
91
+#define COLOR_QUERYFG(re) re->theme.color_queryfg
92
+#define COLOR_QUERYBGOLD(re) re->theme.color_querybgold
93
+#define COLOR_QUERYFGOLD(re) re->theme.color_queryfgold
94
+#define COLOR_WARNINGBG(re) re->theme.color_warningbg
95
+#define COLOR_WARNINGFG(re) re->theme.color_warningfg
96
+#define COLOR_INFOBG(re) re->theme.color_infobg
97
+#define COLOR_INFOFG(re) re->theme.color_infofg
98
+#define COLOR_INFOFGLIGHT(re) re->theme.color_infofglight
99
+#define COLOR_SELNORMAL(re) re->theme.color_selnormal
100
+#define COLOR_CURLINE(re) re->theme.color_curline
65 101
 
66 102
 typedef struct printout_t {
67 103
         reui_t *ui;
... ...
@@ -73,9 +109,35 @@ typedef struct printout_t {
73 109
         int dirty;
74 110
 } printout_t;
75 111
 
112
+typedef struct theme_t {
113
+        int ntheme;
114
+        char color_background[5];
115
+        char color_printoutstripe[5];
116
+        char color_cursorbg[5];
117
+        char color_cursorfg[5];
118
+        char color_text[5];
119
+        char color_matchbg[5];
120
+        char color_matchfg[5];
121
+        char color_statusbg[5];
122
+        char color_statusfg[5];
123
+        char color_statusfglight[5];
124
+        char color_querybg[5];
125
+        char color_queryfg[5];
126
+        char color_querybgold[5];
127
+        char color_queryfgold[5];
128
+        char color_warningbg[5];
129
+        char color_warningfg[5];
130
+        char color_infobg[5];
131
+        char color_infofg[5];
132
+        char color_infofglight[5];
133
+        char color_selnormal[5];
134
+        char color_curline[5];
135
+} theme_t;
136
+
76 137
 typedef struct re_t {
77 138
         redata_t *data;
78 139
         reui_t *ui;
140
+        theme_t theme;
79 141
         int viewonly;
80 142
         int quirk_duplicates;
81 143
         int flag_newfile;
... ...
@@ -126,7 +188,6 @@ static void sighandler_sigint(int num);
126 188
 static void sighandler_sigpipe(int num);
127 189
 static int mystricmp(const char *s1, const char *s2);
128 190
 
129
-
130 191
 re_t *re_init(int viewonly);
131 192
 void re_free(re_t *re);
132 193
 int re_setuidata(re_t *re);
... ...
@@ -164,6 +225,7 @@ int re_drawcontents(re_t *re, printout_t *printout);
164 225
 redata_t *re_getfunclisting(re_t *re);
165 226
 int re_funclistingxy2line(re_t *re,int mx,int my);
166 227
 int re_wheelaccel(re_t *re, int rawamount);
228
+int re_themeset(re_t *re, int ntheme);
167 229
 
168 230
 
169 231
 int
... ...
@@ -755,6 +817,7 @@ re_init(int viewonly)
755 817
         re->viewonly=(viewonly!=0)?1:0;
756 818
         SDL_GetVersion(&linked_version);
757 819
         re->quirk_duplicates=(linked_version.major==2 && linked_version.minor==0 && linked_version.patch==9)?1:0;
820
+        re_themeset(re,0);
758 821
         return(re);
759 822
 }
760 823
 
... ...
@@ -1265,14 +1328,24 @@ fprintf(stderr,"SDL_KEYDOWN: BACKSPACE%s\n",(event==&fakeevent)?" (fake)":"");
1265 1328
                 re->headerdirty=1;
1266 1329
                 re->contentsdirty=1;
1267 1330
         } else if(event->key.keysym.sym==SDLK_PLUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1268
-#warning XXX TODO: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation)
1269
-                re_changefontsize(re, 1);
1331
+                /* NOTE: Control+'+'/'-' iterates between the font sizes (Control+'0' resets to the default font size) */
1332
+                /* NOTE: Control+shift+'+'/'-' iterates between the color permutations of the current theme in rgb, 6 in total (Control+shift+'0' resets to the default permutation) */
1333
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1334
+                        re_changefontsize(re, 1);
1335
+                else
1336
+                        re_themeset(re, re->theme.ntheme+1);
1270 1337
                 re->ignorenkeys++;
1271 1338
         } else if(event->key.keysym.sym==SDLK_MINUS && (SDL_GetModState()&KMOD_CTRL)!=0) {
1272
-                re_changefontsize(re, -1);
1339
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1340
+                        re_changefontsize(re, -1);
1341
+                else
1342
+                        re_themeset(re, re->theme.ntheme-1);
1273 1343
                 re->ignorenkeys++;
1274 1344
         } else if(event->key.keysym.sym==SDLK_0 && (SDL_GetModState()&KMOD_CTRL)!=0) {
1275
-                re_changefontsize(re, 0);
1345
+                if((SDL_GetModState()&KMOD_SHIFT)==0)
1346
+                        re_changefontsize(re, 0);
1347
+                else
1348
+                        re_themeset(re, 0);
1276 1349
                 if(re->quirk_duplicates)
1277 1350
                         re->ignorenkeys++;
1278 1351
         } else if((event->key.keysym.sym==SDLK_c || event->key.keysym.sym==SDLK_x) && (SDL_GetModState()&KMOD_CTRL)!=0) {
... ...
@@ -2233,7 +2306,7 @@ re_drawheader_editing(re_t *re)
2233 2306
                 return(-1);
2234 2307
         if(redata_linecol2pos(re->data,re->curline,re->curcol,&cursorpos,NULL)!=0)
2235 2308
                 return(0); /* error obtaining position */
2236
-        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needssaving(re->data)?COLOR_STATUSBG:COLOR_INFOBG);
2309
+        reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,redata_needssaving(re->data)?COLOR_STATUSBG(re):COLOR_INFOBG(re));
2237 2310
         /* for the user, lines start at 0 (internally they start at 0) */
2238 2311
         memset(spaces,' ',sizeof(spaces));
2239 2312
         spaces[sizeof(spaces)-1]='\0';
... ...
@@ -2248,10 +2321,10 @@ re_drawheader_editing(re_t *re)
2248 2321
         lenfilename=strlen(re->filename);
2249 2322
         filename=((lenfilename)>(sizeof(spaces)-1))?(re->filename+lenfilename-sizeof(spaces)-1):re->filename;
2250 2323
         spacesfilename=spaces+sizeof(spaces)-1-strlen(filename);
2251
-        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFGLIGHT:COLOR_INFOFGLIGHT
2324
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFGLIGHT(re):COLOR_INFOFGLIGHT(re)
2252 2325
            ,"File:%s%s Line:%s Col:%s Pos:%s Size:%s"
2253 2326
           ,spacesfilename,redata_needssaving(re->data)?"*":" ",spaceslinebuf,spacescolbuf,spacesposbuf,spacessizebuf);
2254
-        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFG:COLOR_INFOFG
2327
+        reui_printf(re->ui,0,0,redata_needssaving(re->data)?COLOR_STATUSFG(re):COLOR_INFOFG(re)
2255 2328
            ,"     %s%s      %s     %s     %s      %s"
2256 2329
           ,filename," ",linebuf,colbuf,posbuf,sizebuf);
2257 2330
         re->headerdirty=0;
... ...
@@ -2267,21 +2340,21 @@ re_drawheader_command(re_t *re)
2267 2340
         if(re->command==NULL)
2268 2341
                 return(-1);
2269 2342
         if(re->command[0]=='\0') {
2270
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2271
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"Command:");
2343
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2344
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"Command:");
2272 2345
         } else if(strcmp(re->command,COMMAND_WARNING)==0 || strcmp(re->command,COMMAND_CONFIRMEXIT)==0) {
2273
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG);
2274
-                reui_printf(re->ui,0,0,COLOR_WARNINGFG,"%s %s",re->command,re->commandbuf);
2346
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_WARNINGBG(re));
2347
+                reui_printf(re->ui,0,0,COLOR_WARNINGFG(re),"%s %s",re->command,re->commandbuf);
2275 2348
         } else if(strcmp(re->command,COMMAND_INFO)==0) {
2276
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_INFOBG);
2277
-                reui_printf(re->ui,0,0,COLOR_INFOFG,"%s %s",re->command,re->commandbuf);
2349
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_INFOBG(re));
2350
+                reui_printf(re->ui,0,0,COLOR_INFOFG(re),"%s %s",re->command,re->commandbuf);
2278 2351
         } else if(strcmp(re->command,COMMAND_QUESTION)==0) {
2279 2352
                 question_t *q;
2280
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2353
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2281 2354
 #warning XXX TODO: suppont arbitrary number of options, highlight current option
2282 2355
                 q=re->question;
2283 2356
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2284
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s %s: %s %s%s%s%s%s%s%s%s: %s"
2357
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"%s %s: %s %s%s%s%s%s%s%s%s: %s"
2285 2358
                    ,re->command
2286 2359
                    ,(q->titleshort!=NULL)?q->titleshort:q->title
2287 2360
                    ,(q->bodyshort!=NULL)?q->bodyshort:q->body
... ...
@@ -2293,18 +2366,18 @@ re_drawheader_command(re_t *re)
2293 2366
         } else {
2294 2367
                 int commandlen;
2295 2368
                 int commandbuflen;
2296
-                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG);
2369
+                reui_fill(re->ui,0,0,re->ui->w,re->ui->fontheight,COLOR_QUERYBG(re));
2297 2370
                 re->commandbuf[sizeof(re->commandbuf)-1]='\0';
2298 2371
                 commandlen=redata_generic_utf8len(re->command,strlen(re->command));
2299
-                reui_printf(re->ui,0,0,COLOR_QUERYFG,"%s",re->command);
2372
+                reui_printf(re->ui,0,0,COLOR_QUERYFG(re),"%s",re->command);
2300 2373
                 commandbuflen=redata_generic_utf8len(re->commandbuf,strlen(re->commandbuf));
2301 2374
                 if(!(re->is_oldcommandbuf) || re->commandbuf[0]=='\0') {
2302
-                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG,"%s",re->commandbuf);
2375
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFG(re),"%s",re->commandbuf);
2303 2376
                         /* draw something that to indicate the end of the commandbuf (useful if commandbuf ends in spaces) */
2304
-                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1+commandbuflen)+1,re->ui->fontheight/2,1,re->ui->fontheight/2,COLOR_QUERYFG);
2377
+                        reui_fill(re->ui,re->ui->fontwidth*(commandlen+1+commandbuflen)+1,re->ui->fontheight/2,1,re->ui->fontheight/2,COLOR_QUERYFG(re));
2305 2378
                 } else {
2306
-                        reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD);
2307
-                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD,"%s",re->commandbuf);
2379
+                        reui_fillrounded(re->ui,re->ui->fontwidth*(commandlen+1)-re->ui->fontwidth/2,0,re->ui->fontwidth*(commandbuflen+1)+1,re->ui->fontheight,COLOR_QUERYBGOLD(re));
2380
+                        reui_printf(re->ui,re->ui->fontwidth*(commandlen+1),0,COLOR_QUERYFGOLD(re),"%s",re->commandbuf);
2308 2381
                 }
2309 2382
         }
2310 2383
         re->headerdirty=0;
... ...
@@ -2329,8 +2402,6 @@ re_drawcontents(re_t *re, printout_t *printout)
2329 2402
         printout_t fakeprintout;
2330 2403
         hcolor_t *colors,fakecolor;
2331 2404
         int ncolors;
2332
-        const char selcolornormal[]={"\xde\xcf\x7f\xff"};
2333
-        const char selcolorcurline[]={"\xf0\xea\xc9\xff"};
2334 2405
         long realstart,realend;
2335 2406
         linecolor_t *linecolors,fakelinecolors;
2336 2407
         int nlinecolors;
... ...
@@ -2391,7 +2462,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2391 2462
         }
2392 2463
         if(redata_linecol2pos(data,curline,curcol,&cursorpos,NULL)!=0)
2393 2464
                 return(0); /* error obtaining position */
2394
-        reui_fill(ui,x0-linenowidth,y0,w,h,"\xdf\xdf\xdf\xff");
2465
+        reui_fill(ui,x0-linenowidth,y0,w,h,COLOR_BACKGROUND(re));
2395 2466
         row=curline-originline;
2396 2467
         pos=cursorpos;
2397 2468
         /* get position/row/col of character at top left of screen */
... ...
@@ -2404,17 +2475,17 @@ re_drawcontents(re_t *re, printout_t *printout)
2404 2475
         }
2405 2476
         /* highlight current line (in printouts, highlight alternating lines) */
2406 2477
         if(printout==NULL) {
2407
-                reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,"\xef\xef\xef\xff");
2478
+                reui_fill(ui,x0-linenowidth,y0+(curline-originline)*ui->fontheight,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2408 2479
         } else {
2409 2480
                 for(y=y0+((printout->data==NULL)?1:(printout->originline%2))*ui->fontheight;y<(y0+h);y+=ui->fontheight*2)
2410
-                        reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,"\xef\xef\xef\xff");
2481
+                        reui_fill(ui,x0-linenowidth,y,w,ui->fontheight+1,COLOR_PRINTOUTSTRIPE(re));
2411 2482
         }
2412 2483
         /* highlight the selection */
2413 2484
         if(printout==NULL && re->selactive) {
2414 2485
                 const char *selcolor;
2415 2486
                 tmprow=row;
2416 2487
                 for(y=y0;y<(y0+h);y+=ui->fontheight,row++) {
2417
-                        selcolor=(row==(curline-originline))?selcolorcurline:selcolornormal;
2488
+                        selcolor=(row==(curline-originline))?COLOR_CURLINE(re):COLOR_SELNORMAL(re);
2418 2489
                         if((originline+row)==re->sellinefrom && (originline+row)==re->sellineto) {
2419 2490
                                 reui_fill(ui,x0+(re->selcolfrom-origincol)*ui->fontwidth,y0+row*ui->fontheight,(re->selcolto-re->selcolfrom)*ui->fontwidth,ui->fontheight+1,selcolor);
2420 2491
                         } else if((originline+row)==re->sellinefrom) {
... ...
@@ -2437,7 +2508,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2437 2508
         if((colors=redata_highlighter_getcolors(data,&ncolors))==NULL) {
2438 2509
                 colors=&fakecolor;
2439 2510
                 ncolors=1;
2440
-                memcpy(fakecolor.rgba,"\x00\x00\x00\xff",5);
2511
+                memcpy(fakecolor.rgba,COLOR_TEXT(re),5);
2441 2512
         }
2442 2513
         drawn_cursor=0;
2443 2514
         matchingpos=-1;
... ...
@@ -2462,7 +2533,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2462 2533
                 }
2463 2534
                 curlinecolor=0;
2464 2535
                 usedlenlinecolor=0;
2465
-                lastcolor="\x00\x00\x00\xff";                      
2536
+                lastcolor=COLOR_TEXT(re);
2466 2537
                 in_error=0;
2467 2538
                 if(flaglineno && origincol==0) {
2468 2539
                         int i,n;
... ...
@@ -2546,22 +2617,22 @@ re_drawcontents(re_t *re, printout_t *printout)
2546 2617
                                 char cursorchar[7];
2547 2618
                                 int usedcursorchar;
2548 2619
                                 /* draw cursor */
2549
-                                reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2620
+                                reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,COLOR_CURSORBG(re));
2550 2621
                                 drawn_cursor=1;
2551 2622
                                 usedcursorchar=0;
2552 2623
                                 redata_getutf8char(re->data,cursorpos,cursorchar,sizeof(cursorchar),&usedcursorchar);
2553 2624
                                 /* tab chars are drawn as an almost filled block, other chars are written as-is */
2554 2625
                                 if(usedcursorchar==1 && *cursorchar=='\t')
2555
-                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol)+1,y+1,ui->fontwidth-2,ui->fontheight+1-2,"\xff\xff\xff\xff");
2626
+                                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol)+1,y+1,ui->fontwidth-2,ui->fontheight+1-2,COLOR_CURSORFG(re));
2556 2627
                                 else
2557
-                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,"\xff\xff\xff\xff",cursorchar,usedcursorchar);
2628
+                                        reui_write(ui,x0+ui->fontwidth*(curcol-origincol),y,COLOR_CURSORFG(re),cursorchar,usedcursorchar);
2558 2629
                                 /* get matching braces/parens/anglebracket/curlybraces for highlighting */
2559 2630
                                 if(usedcursorchar==1 && strchr("[]{}<>()",*cursorchar)!=NULL)
2560 2631
                                         matchingpos=re_getmatchingbracket(re,cursorpos,*cursorchar,&matchingchar);
2561 2632
                         }
2562 2633
                 }
2563 2634
                 if(printout==NULL && row==(curline-originline) && !drawn_cursor)
2564
-                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,"\x00\x00\x00\xff");
2635
+                        reui_fill(ui,x0+ui->fontwidth*(curcol-origincol),y,ui->fontwidth,ui->fontheight+1,COLOR_CURSORBG(re));
2565 2636
                 if(in_error)
2566 2637
                         break;
2567 2638
                 pos=realend+1;
... ...
@@ -2569,8 +2640,8 @@ re_drawcontents(re_t *re, printout_t *printout)
2569 2640
         /* highlight matching parens/brace/... if applicable */
2570 2641
         if(printout==NULL && matchingpos!=-1 && redata_pos2linecol(data,matchingpos,&mline,&mcol)!=-1) {
2571 2642
                 int x,y;
2572
-                char *fg="\xff\x00\x00\x80";
2573
-                char *bg="\xff\xff\xff\xaf";
2643
+                char *fg=COLOR_MATCHFG(re);
2644
+                char *bg=COLOR_MATCHBG(re);
2574 2645
                 x=x0+(mcol-origincol)*ui->fontwidth+(ui->fontwidth/2);
2575 2646
                 x=(x<x0)?x0:(x>=(x0+w))?(x0+w-1):x;
2576 2647
                 y=y0+(mline-originline)*ui->fontheight+(ui->fontheight/2);
... ...
@@ -2605,7 +2676,7 @@ re_drawcontents(re_t *re, printout_t *printout)
2605 2676
                 for(total=redata_line_total(re->funclisting),i=re->originlinefunclisting,ypos=y0;i<total && ypos<re->h;i++,ypos+=(ui->fontheight/((linebuf[0]=='\0')?2:1))) {
2606 2677
                         fg="\xff\xff\xff\xff";
2607 2678
                         if(i==re->curlinefunclisting) {
2608
-                                reui_fill(ui,x0-linenowidth+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,"\xdf\xdf\xdf\xff");
2679
+                                reui_fill(ui,x0-linenowidth+ui->fontwidth*3,ypos,w-ui->fontwidth*6,ui->fontheight,COLOR_BACKGROUND(re));
2609 2680
                                 fg="\x00\x00\x00\xff";
2610 2681
                         }
2611 2682
                         if(redata_line_getstartstr(re->funclisting,i,linebuf,sizeof(linebuf))!=0)
... ...
@@ -2726,12 +2797,70 @@ re_wheelaccel(re_t *re, int rawamount)
2726 2797
         return(wheelamount);
2727 2798
 }
2728 2799
 
2800
+void
2801
+util_applypermutation(int *template3,char *colors,int invert)
2802
+{
2803
+        unsigned char c[3];
2804
+        if(template3==NULL || colors==NULL || template3[0]<0 || template3[0]>2 || template3[1]<0 || template3[1]>2 || template3[2]<0 || template3[2]>2)
2805
+                return; /* sanity check error */
2806
+        if(invert==0) {
2807
+                c[0]=((unsigned char *)colors)[0];
2808
+                c[1]=((unsigned char *)colors)[1];
2809
+                c[2]=((unsigned char *)colors)[2];
2810
+        } else {
2811
+                c[0]=255-((unsigned char *)colors)[0];
2812
+                c[1]=255-((unsigned char *)colors)[1];
2813
+                c[2]=255-((unsigned char *)colors)[2];
2814
+        }
2815
+        ((unsigned char *)colors)[0]=c[template3[0]];
2816
+        ((unsigned char *)colors)[1]=c[template3[1]];
2817
+        ((unsigned char *)colors)[2]=c[template3[2]];
2818
+        return;
2819
+}
2729 2820
 
2730
-
2731
-
2732
-
2733
-
2734
-
2735
-
2736
-
2821
+int
2822
+re_themeset(re_t *re, int ntheme)
2823
+{
2824
+        int permutations[6][3]={{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,1,0},{2,0,1}};
2825
+        int *permutationtemplate;
2826
+        int invert;
2827
+        if(re==NULL)
2828
+                return(-1);
2829
+        /* num. themes: 3*2*1*2=12 (permutations of 3 colors plus inverted colors)*/
2830
+        ntheme=(ntheme<0)?12-((-ntheme)%12):ntheme;
2831
+        ntheme%=12;
2832
+        re->theme.ntheme=ntheme;
2833
+        /* compute invert and the number of permutation */
2834
+        invert=(ntheme>=6)?1:0;
2835
+        ntheme%=6;
2836
+        permutationtemplate=permutations[ntheme];
2837
+        /* reset colors and permutate them */
2838
+        strncpy(re->theme.color_background,DEFAULT_COLOR_BACKGROUND,sizeof(re->theme.color_background)),re->theme.color_background[sizeof(re->theme.color_background)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_background,invert);
2839
+        strncpy(re->theme.color_printoutstripe,DEFAULT_COLOR_PRINTOUTSTRIPE,sizeof(re->theme.color_printoutstripe)),re->theme.color_printoutstripe[sizeof(re->theme.color_printoutstripe)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_printoutstripe,invert);
2840
+        strncpy(re->theme.color_cursorbg,DEFAULT_COLOR_CURSORBG,sizeof(re->theme.color_cursorbg)),re->theme.color_cursorbg[sizeof(re->theme.color_cursorbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_cursorbg,invert);
2841
+        strncpy(re->theme.color_cursorfg,DEFAULT_COLOR_CURSORFG,sizeof(re->theme.color_cursorfg)),re->theme.color_cursorfg[sizeof(re->theme.color_cursorfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_cursorfg,invert);
2842
+        strncpy(re->theme.color_text,DEFAULT_COLOR_TEXT,sizeof(re->theme.color_text)),re->theme.color_text[sizeof(re->theme.color_text)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_text,invert);
2843
+        strncpy(re->theme.color_matchbg,DEFAULT_COLOR_MATCHBG,sizeof(re->theme.color_matchbg)),re->theme.color_matchbg[sizeof(re->theme.color_matchbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_matchbg,invert);
2844
+        strncpy(re->theme.color_matchfg,DEFAULT_COLOR_MATCHFG,sizeof(re->theme.color_matchfg)),re->theme.color_matchfg[sizeof(re->theme.color_matchfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_matchfg,invert);
2845
+        strncpy(re->theme.color_statusbg,DEFAULT_COLOR_STATUSBG,sizeof(re->theme.color_statusbg)),re->theme.color_statusbg[sizeof(re->theme.color_statusbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusbg,invert);
2846
+        strncpy(re->theme.color_statusfg,DEFAULT_COLOR_STATUSFG,sizeof(re->theme.color_statusfg)),re->theme.color_statusfg[sizeof(re->theme.color_statusfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusfg,invert);
2847
+        strncpy(re->theme.color_statusfglight,DEFAULT_COLOR_STATUSFGLIGHT,sizeof(re->theme.color_statusfglight)),re->theme.color_statusfglight[sizeof(re->theme.color_statusfglight)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_statusfglight,invert);
2848
+        strncpy(re->theme.color_querybg,DEFAULT_COLOR_QUERYBG,sizeof(re->theme.color_querybg)),re->theme.color_querybg[sizeof(re->theme.color_querybg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_querybg,invert);
2849
+        strncpy(re->theme.color_queryfg,DEFAULT_COLOR_QUERYFG,sizeof(re->theme.color_queryfg)),re->theme.color_queryfg[sizeof(re->theme.color_queryfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_queryfg,invert);
2850
+        strncpy(re->theme.color_querybgold,DEFAULT_COLOR_QUERYBGOLD,sizeof(re->theme.color_querybgold)),re->theme.color_querybgold[sizeof(re->theme.color_querybgold)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_querybgold,invert);
2851
+        strncpy(re->theme.color_queryfgold,DEFAULT_COLOR_QUERYFGOLD,sizeof(re->theme.color_queryfgold)),re->theme.color_queryfgold[sizeof(re->theme.color_queryfgold)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_queryfgold,invert);
2852
+        strncpy(re->theme.color_warningbg,DEFAULT_COLOR_WARNINGBG,sizeof(re->theme.color_warningbg)),re->theme.color_warningbg[sizeof(re->theme.color_warningbg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_warningbg,invert);
2853
+        strncpy(re->theme.color_warningfg,DEFAULT_COLOR_WARNINGFG,sizeof(re->theme.color_warningfg)),re->theme.color_warningfg[sizeof(re->theme.color_warningfg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_warningfg,invert);
2854
+        strncpy(re->theme.color_infobg,DEFAULT_COLOR_INFOBG,sizeof(re->theme.color_infobg)),re->theme.color_infobg[sizeof(re->theme.color_infobg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infobg,invert);
2855
+        strncpy(re->theme.color_infofg,DEFAULT_COLOR_INFOFG,sizeof(re->theme.color_infofg)),re->theme.color_infofg[sizeof(re->theme.color_infofg)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infofg,invert);
2856
+        strncpy(re->theme.color_infofglight,DEFAULT_COLOR_INFOFGLIGHT,sizeof(re->theme.color_infofglight)),re->theme.color_infofglight[sizeof(re->theme.color_infofglight)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_infofglight,invert);
2857
+        strncpy(re->theme.color_selnormal,DEFAULT_COLOR_SELNORMAL,sizeof(re->theme.color_selnormal)),re->theme.color_selnormal[sizeof(re->theme.color_selnormal)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_selnormal,invert);
2858
+        strncpy(re->theme.color_curline,DEFAULT_COLOR_CURLINE,sizeof(re->theme.color_curline)),re->theme.color_curline[sizeof(re->theme.color_curline)-1]='\0',util_applypermutation(permutationtemplate,re->theme.color_curline,invert);
2859
+        /* set theme in highlighter */
2860
+        redata_highlighter_settheme(re->data,ntheme,invert);
2861
+        /* force redraw */
2862
+        re->contentsdirty=1;
2863
+        re->headerdirty=1;
2864
+        return(0);
2865
+}
2737 2866