1 /* Public Domain Curses */
2 
3 #include "pdcsdl.h"
4 
5 RCSID("$Id: pdcscrn.c,v 1.34 2008/07/14 04:24:52 wmcbrine Exp $")
6 
7 #include <stdlib.h>
8 #include "deffont.h"
9 #include "deficon.h"
10 
11 SDL_Surface *pdc_screen = NULL, *pdc_font = NULL, *pdc_icon = NULL,
12             *pdc_back = NULL, *pdc_tileback = NULL;
13 int pdc_sheight = 0, pdc_swidth = 0, pdc_yoffset = 0, pdc_xoffset = 0;
14 
15 SDL_Color pdc_color[16];
16 Uint32 pdc_mapped[16];
17 int pdc_fheight, pdc_fwidth, pdc_flastc;
18 bool pdc_own_screen;
19 
20 /* COLOR_PAIR to attribute encoding table. */
21 
22 static struct {short f, b;} atrtab[PDC_COLOR_PAIRS];
23 
PDC_retile(void)24 void PDC_retile(void)
25 {
26     if (pdc_tileback)
27         SDL_FreeSurface(pdc_tileback);
28 
29     pdc_tileback = SDL_DisplayFormat(pdc_screen);
30 
31     if (pdc_back)
32     {
33         SDL_Rect dest;
34 
35         dest.y = 0;
36 
37         while (dest.y < pdc_tileback->h)
38         {
39             dest.x = 0;
40 
41             while (dest.x < pdc_tileback->w)
42             {
43                 SDL_BlitSurface(pdc_back, 0, pdc_tileback, &dest);
44                 dest.x += pdc_back->w;
45             }
46 
47             dest.y += pdc_back->h;
48         }
49 
50         SDL_BlitSurface(pdc_tileback, 0, pdc_screen, 0);
51     }
52 }
53 
PDC_scr_close(void)54 void PDC_scr_close(void)
55 {
56     PDC_LOG(("PDC_scr_close() - called\n"));
57 }
58 
PDC_scr_free(void)59 void PDC_scr_free(void)
60 {
61     if (SP)
62         free(SP);
63 }
64 
65 /* open the physical screen -- allocate SP, miscellaneous intialization */
66 
PDC_scr_open(int argc,char ** argv)67 int PDC_scr_open(int argc, char **argv)
68 {
69     int i;
70 
71     PDC_LOG(("PDC_scr_open() - called\n"));
72 
73     SP = calloc(1, sizeof(SCREEN));
74 
75     if (!SP)
76         return ERR;
77 
78     pdc_own_screen = !pdc_screen;
79 
80     if (pdc_own_screen)
81     {
82         if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
83         {
84             fprintf(stderr, "Could not start SDL: %s\n", SDL_GetError());
85             return ERR;
86         }
87 
88         atexit(SDL_Quit);
89     }
90 
91     if (!pdc_font)
92     {
93         const char *fname = getenv("PDC_FONT");
94         pdc_font = SDL_LoadBMP(fname ? fname : "pdcfont.bmp");
95     }
96 
97     if (!pdc_font)
98         pdc_font = SDL_LoadBMP_RW(SDL_RWFromMem(deffont, sizeof(deffont)), 0);
99 
100     if (!pdc_font)
101     {
102         fprintf(stderr, "Could not load font\n");
103         return ERR;
104     }
105 
106     SP->mono = !pdc_font->format->palette;
107 
108     if (!SP->mono && !pdc_back)
109     {
110         const char *bname = getenv("PDC_BACKGROUND");
111         pdc_back = SDL_LoadBMP(bname ? bname : "pdcback.bmp");
112     }
113 
114     if (!SP->mono && (pdc_back || !pdc_own_screen))
115     {
116         SP->orig_attr = TRUE;
117         SP->orig_fore = COLOR_WHITE;
118         SP->orig_back = -1;
119     }
120     else
121         SP->orig_attr = FALSE;
122 
123     pdc_fheight = pdc_font->h / 8;
124     pdc_fwidth = pdc_font->w / 32;
125 
126     if (!SP->mono)
127         pdc_flastc = pdc_font->format->palette->ncolors - 1;
128 
129     if (pdc_own_screen && !pdc_icon)
130     {
131         const char *iname = getenv("PDC_ICON");
132         pdc_icon = SDL_LoadBMP(iname ? iname : "pdcicon.bmp");
133 
134         if (!pdc_icon)
135             pdc_icon = SDL_LoadBMP_RW(SDL_RWFromMem(deficon,
136                                                     sizeof(deficon)), 0);
137 
138         if (pdc_icon)
139             SDL_WM_SetIcon(pdc_icon, NULL);
140     }
141 
142     if (pdc_own_screen)
143     {
144         const char *env = getenv("PDC_LINES");
145         pdc_sheight = (env ? atoi(env) : 25) * pdc_fheight;
146 
147         env = getenv("PDC_COLS");
148         pdc_swidth = (env ? atoi(env) : 80) * pdc_fwidth;
149 
150         pdc_screen = SDL_SetVideoMode(pdc_swidth, pdc_sheight, 0,
151             SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
152     }
153     else
154     {
155         if (!pdc_sheight)
156             pdc_sheight = pdc_screen->h - pdc_yoffset;
157 
158         if (!pdc_swidth)
159             pdc_swidth = pdc_screen->w - pdc_xoffset;
160     }
161 
162     if (!pdc_screen)
163     {
164         fprintf(stderr, "Couldn't create a surface: %s\n", SDL_GetError());
165         return ERR;
166     }
167 
168     if (SP->orig_attr)
169         PDC_retile();
170 
171     for (i = 0; i < 8; i++)
172     {
173         pdc_color[i].r = (i & COLOR_RED) ? 0xc0 : 0;
174         pdc_color[i].g = (i & COLOR_GREEN) ? 0xc0 : 0;
175         pdc_color[i].b = (i & COLOR_BLUE) ? 0xc0 : 0;
176 
177         pdc_color[i + 8].r = (i & COLOR_RED) ? 0xff : 0x40;
178         pdc_color[i + 8].g = (i & COLOR_GREEN) ? 0xff : 0x40;
179         pdc_color[i + 8].b = (i & COLOR_BLUE) ? 0xff : 0x40;
180     }
181 
182     for (i = 0; i < 16; i++)
183         pdc_mapped[i] = SDL_MapRGB(pdc_screen->format, pdc_color[i].r,
184                                    pdc_color[i].g, pdc_color[i].b);
185 
186     SDL_EnableUNICODE(1);
187 
188     PDC_mouse_set();
189 
190     if (pdc_own_screen)
191         PDC_set_title(argc ? argv[0] : "PDCurses");
192 
193     SP->lines = PDC_get_rows();
194     SP->cols = PDC_get_columns();
195 
196     SP->mouse_wait = PDC_CLICK_PERIOD;
197     SP->audible = FALSE;
198 
199     PDC_reset_prog_mode();
200 
201     return OK;
202 }
203 
204 /* the core of resize_term() */
205 
PDC_resize_screen(int nlines,int ncols)206 int PDC_resize_screen(int nlines, int ncols)
207 {
208     if (!pdc_own_screen)
209         return ERR;
210 
211     if (nlines && ncols)
212     {
213         pdc_sheight = nlines * pdc_fheight;
214         pdc_swidth = ncols * pdc_fwidth;
215     }
216 
217     SDL_FreeSurface(pdc_screen);
218 
219     pdc_screen = SDL_SetVideoMode(pdc_swidth, pdc_sheight, 0,
220         SDL_SWSURFACE|SDL_ANYFORMAT|SDL_RESIZABLE);
221 
222     if (pdc_tileback)
223         PDC_retile();
224 
225     SP->resized = FALSE;
226     SP->cursrow = SP->curscol = 0;
227 
228     return OK;
229 }
230 
PDC_reset_prog_mode(void)231 void PDC_reset_prog_mode(void)
232 {
233     PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
234 
235     PDC_flushinp();
236     SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
237 }
238 
PDC_reset_shell_mode(void)239 void PDC_reset_shell_mode(void)
240 {
241     PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
242 
243     SDL_EnableKeyRepeat(0, 0);
244     PDC_flushinp();
245 }
246 
PDC_restore_screen_mode(int i)247 void PDC_restore_screen_mode(int i)
248 {
249 }
250 
PDC_save_screen_mode(int i)251 void PDC_save_screen_mode(int i)
252 {
253 }
254 
PDC_init_pair(short pair,short fg,short bg)255 void PDC_init_pair(short pair, short fg, short bg)
256 {
257     atrtab[pair].f = fg;
258     atrtab[pair].b = bg;
259 }
260 
PDC_pair_content(short pair,short * fg,short * bg)261 int PDC_pair_content(short pair, short *fg, short *bg)
262 {
263     *fg = atrtab[pair].f;
264     *bg = atrtab[pair].b;
265 
266     return OK;
267 }
268 
PDC_can_change_color(void)269 bool PDC_can_change_color(void)
270 {
271     return TRUE;
272 }
273 
PDC_color_content(short color,short * red,short * green,short * blue)274 int PDC_color_content(short color, short *red, short *green, short *blue)
275 {
276     *red = DIVROUND(pdc_color[color].r * 1000, 255);
277     *green = DIVROUND(pdc_color[color].g * 1000, 255);
278     *blue = DIVROUND(pdc_color[color].b * 1000, 255);
279 
280     return OK;
281 }
282 
PDC_init_color(short color,short red,short green,short blue)283 int PDC_init_color(short color, short red, short green, short blue)
284 {
285     pdc_color[color].r = DIVROUND(red * 255, 1000);
286     pdc_color[color].g = DIVROUND(green * 255, 1000);
287     pdc_color[color].b = DIVROUND(blue * 255, 1000);
288 
289     pdc_mapped[color] = SDL_MapRGB(pdc_screen->format, pdc_color[color].r,
290                                    pdc_color[color].g, pdc_color[color].b);
291 
292     wrefresh(curscr);
293 
294     return OK;
295 }
296