1 /* X INTERFACE */
2 
3 #include "config.h"
4 
5 #ifdef HAVE_LIBXPM
6 	#define ICON
7 #endif
8 
9 #include <X11/Xlib.h>
10 #include <X11/X.h>
11 #include <X11/Xutil.h>
12 
13 #ifdef ICON
14 	#include <X11/xpm.h>
15 #endif
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "console.h"
22 #include "cfg.h"
23 #include "kbd.h"
24 #include "x.h"
25 
26 #ifdef ICON
27 	#include "icon.h"
28 #endif
29 
30 
31 #define BORDER_WIDTH 4
32 
33 
34 int console_ok=1;
35 
36 Display *display;
37 char * x_display_name;
38 Window window;
39 #ifdef TRI_D
40 	Window window2;
41 #endif
42 
43 int FONT_X_SIZE,FONT_Y_SIZE;
44 char *x_font_name;
45 
46 GC gc;
47 Atom x_delete_window_atom,x_wm_protocols_atom;
48 
49 char * x_color_name[16]={
50 	"black",
51 	"red4",
52 	"green4",
53 	"brown4",
54 	"blue4",
55 	"dark violet",
56 	"cyan4",
57 	"gray40",
58 	"gray20",
59 	"red1",
60 	"green1",
61 	"yellow",
62 	"blue1",
63 	"magenta1",
64 	"cyan1",
65 	"white"
66 };
67 XColor x_color[16];
68 
69 int x_screen;
70 int x_current_x,x_current_y;
71 int x_current_color=0;
72 int x_current_bgcolor=0;
73 int x_width=DEFAULT_X_SIZE,x_height=DEFAULT_Y_SIZE;
74 int display_height,display_width;
75 XFontStruct* x_font;
76 
77 XGCValues gcv;
78 
79 #ifdef ICON
80 	Pixmap icon_pixmap,icon_mask;
81 #endif
82 
c_refresh(void)83 void c_refresh(void)
84 {
85 	XFlush(display);
86 }
87 
88 
89 /* initialize console */
c_init(int w,int h)90 void c_init(int w,int h)
91 {
92 	XColor dummy;
93 	XSizeHints size_hints;
94 
95 #ifdef ICON
96 	XWMHints wm_hints;
97 #endif
98 	int a;
99 	char *fontname=x_font_name?x_font_name:DEFAULT_FONT_NAME;
100 
101 	w=w;h=h;
102 
103 	if (!x_display_name) x_display_name = getenv("DISPLAY");
104 
105 	/* initiate connection with the X server */
106         display=XOpenDisplay(x_display_name);
107         if (!display){fprintf(stderr,"Error: Can't open display %s\n",x_display_name);exit(1);}
108 
109 	x_screen=DefaultScreen(display);
110 
111 	display_height=DisplayHeight(display,x_screen);
112         display_width=DisplayWidth(display,x_screen);
113 
114 	/* load font */
115 	x_font=XLoadQueryFont(display,fontname);
116 	if (!x_font){fprintf(stderr,"Error: Can't load font \"%s\".\n",fontname);XCloseDisplay(display);exit(1);}
117 	FONT_X_SIZE=x_font->max_bounds.width;
118 	FONT_Y_SIZE=x_font->max_bounds.ascent+x_font->max_bounds.descent;
119 
120 	x_delete_window_atom=XInternAtom(display,"WM_DELETE_WINDOW", False);
121 	x_wm_protocols_atom=XInternAtom(display,"WM_PROTOCOLS", False);
122 
123 	/* create window and set properties */
124         window=XCreateSimpleWindow(display,RootWindow(display,x_screen),0,0,x_width*FONT_X_SIZE,x_height*FONT_Y_SIZE,BORDER_WIDTH,BlackPixel(display,x_screen),BlackPixel(display,x_screen));
125         if (!window){fprintf(stderr,"Error: Can't create window.\n");XCloseDisplay(display);exit(1);}
126         XStoreName(display,window,"0verkill");
127 
128 #ifdef TRI_D
129 	if (TRI_D_ON)
130 	{
131 	        window2=XCreateSimpleWindow(display,RootWindow(display,x_screen),0,0,x_width*FONT_X_SIZE,x_height*FONT_Y_SIZE,BORDER_WIDTH,BlackPixel(display,x_screen),BlackPixel(display,x_screen));
132         	if (!window2){fprintf(stderr,"Error: Can't create window.\n");XCloseDisplay(display);exit(1);}
133 	        XStoreName(display,window2,"0verkill 3D");
134 	}
135 #endif
136 
137 	size_hints.min_width=X_MIN_WIDTH*FONT_X_SIZE;
138 	size_hints.min_height=X_MIN_HEIGHT*FONT_Y_SIZE;
139 	size_hints.width_inc=FONT_X_SIZE;
140 	size_hints.height_inc=FONT_Y_SIZE;
141 	size_hints.flags=PMinSize|PResizeInc;
142 
143 	XSetNormalHints(display,window,&size_hints);
144 
145 #ifdef TRI_D
146 	if (TRI_D_ON)
147 		XSetNormalHints(display,window2,&size_hints);
148 #endif
149 
150 #ifdef ICON
151 	XCreatePixmapFromData(display,window,icon_xpm,&icon_pixmap,&icon_mask,0);
152 #ifdef TRI_D
153 	if (TRI_D_ON)
154 		XCreatePixmapFromData(display,window2,icon_xpm,&icon_pixmap,&icon_mask,0);
155 #endif
156 	wm_hints.flags=IconPixmapHint|IconMaskHint;
157 	wm_hints.icon_pixmap=icon_pixmap;
158 	wm_hints.icon_mask=icon_mask;
159 
160 	XSetWMHints(display,window,&wm_hints);
161 #ifdef TRI_D
162 	if (TRI_D_ON)
163 		XSetWMHints(display,window2,&wm_hints);
164 #endif
165 #endif
166 
167 	XSetWMProtocols(display,window,&x_delete_window_atom,1);
168         XSelectInput(display,window,ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
169 
170 #ifdef TRI_D
171 	if (TRI_D_ON)
172 	{
173 		XSetWMProtocols(display,window2,&x_delete_window_atom,1);
174         	XSelectInput(display,window2,ExposureMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
175 	}
176 #endif
177 
178 	/* create 16 graphic contexts - one for each color */
179 	gcv.font=x_font->fid;
180 	gcv.foreground=BlackPixel(display,x_screen);
181 	gcv.background=BlackPixel(display,x_screen);
182         gc=XCreateGC(display,window,GCFont+GCBackground,&gcv);
183 	for (a=0;a<16;a++)
184 		XAllocNamedColor(display,DefaultColormap(display,x_screen),x_color_name[a],x_color+a,&dummy);
185 	c_refresh();
186 
187 	/* map window */
188         XMapWindow(display,window);
189 
190 #ifdef TRI_D
191 	if (TRI_D_ON)
192 	        XMapWindow(display,window2);
193 #endif
194 
195 	c_refresh();
196 
197 	/* initialize keyboard */
198 	kbd_init();
199 
200 	console_ok=0;
201 }
202 
203 
204 /* close console */
c_shutdown(void)205 void c_shutdown(void)
206 {
207 	kbd_close();
208 	XDestroyWindow(display,window);
209 #ifdef TRI_D
210 	if (TRI_D_ON)
211 		XDestroyWindow(display,window2);
212 #endif
213 	XFreeFont(display,x_font);
214 #ifdef ICON
215 	XFreePixmap(display,icon_pixmap);
216 	XFreePixmap(display,icon_mask);
217 #endif
218 	XCloseDisplay(display);
219 	console_ok=1;
220 }
221 
222 
223 /* move cursor to [x,y] */
c_goto(int x,int y)224 void c_goto(int x,int y)
225 {
226 	x_current_x=x;
227 	x_current_y=y;
228 }
229 
230 
231 /* set foreground color */
c_setcolor(unsigned char a)232 void c_setcolor(unsigned char a)
233 {
234 	x_current_color=(a&15);
235 }
236 
237 
238 /* set foreground and background color */
c_setcolor_bg(unsigned char a,unsigned char b)239 void c_setcolor_bg(unsigned char a,unsigned char b)
240 {
241 	x_current_color=(a&15);
242 	x_current_bgcolor=(b&7);
243 }
244 
245 
246 /* set background color */
c_setbgcolor(unsigned char a)247 void c_setbgcolor(unsigned char a)
248 {
249 	x_current_bgcolor=a&7;
250 }
251 
252 
253 /* set highlight color and background */
c_sethlt_bg(unsigned char a,unsigned char b)254 void c_sethlt_bg(unsigned char a,unsigned char b)
255 {
256 	x_current_color=(x_current_color&7)|(!!a)<<3;
257 	x_current_bgcolor=b&7;
258 }
259 
260 
261 /* set highlight color */
c_sethlt(unsigned char a)262 void c_sethlt(unsigned char a)
263 {
264 	x_current_color=(x_current_color&7)|(!!a)<<3;
265 }
266 
267 
268 /* set 3 bit foreground color and background color */
c_setcolor_3b_bg(unsigned char a,unsigned char b)269 void c_setcolor_3b_bg(unsigned char a,unsigned char b)
270 {
271 	x_current_color=(x_current_color&8)|(a&7);
272 	x_current_bgcolor=b&7;
273 }
274 
275 
276 /* set 3 bit foreground color */
c_setcolor_3b(unsigned char a)277 void c_setcolor_3b(unsigned char a)
278 {
279 	x_current_color=(x_current_color&8)|(a&7);
280 }
281 
282 
283 /* print on the cursor position */
c_print(char * text)284 void c_print(char * text)
285 {
286 	int l=strlen(text);
287 
288 	XSetForeground(display,gc,(x_color[x_current_color]).pixel);
289 	XSetBackground(display,gc,(x_color[x_current_bgcolor]).pixel);
290 	XDrawImageString(
291 		display,
292 #ifdef TRI_D
293 		(TRI_D_ON&&tri_d)?window2:window,
294 #else
295 		window,
296 #endif
297 		gc,
298 		x_current_x*FONT_X_SIZE,
299 		(x_current_y+1)*FONT_Y_SIZE,
300 		text,
301 		l
302 	);
303 	x_current_x+=l;
304 }
305 
306 
307 /* print char on the cursor position */
c_putc(char c)308 void c_putc(char c)
309 {
310 	char s[2]={c,0};
311 	c_print(s);
312 }
313 
314 
315 /* clear the screen */
c_cls(void)316 void c_cls(void)
317 {
318 	XClearWindow(display,window);
319 #ifdef TRI_D
320 	if (TRI_D_ON)
321 		XClearWindow(display,window2);
322 #endif
323 }
324 
325 
326 /* clear rectangle on the screen */
327 /* presumtions: x2>=x1 && y2>=y1 */
c_clear(int x1,int y1,int x2,int y2)328 void c_clear(int x1,int y1,int x2,int y2)
329 {
330 	int w=x2-x1+1;
331 	int h=y2-y1+1;
332 
333 	XClearArea(display,window,x1*FONT_X_SIZE,y1*FONT_Y_SIZE,w*FONT_X_SIZE,h*FONT_Y_SIZE,False);
334 #ifdef TRI_D
335 	if (TRI_D_ON)
336 		XClearArea(display,window2,x1*FONT_X_SIZE,y1*FONT_Y_SIZE,w*FONT_X_SIZE,h*FONT_Y_SIZE,False);
337 #endif
338 }
339 
340 
c_update_kbd(void)341 void c_update_kbd(void)
342 {
343 	kbd_update();
344 }
345 
346 
c_pressed(int k)347 int c_pressed(int k)
348 {
349 	return kbd_is_pressed(k);
350 }
351 
352 
c_was_pressed(int k)353 int c_was_pressed(int k)
354 {
355 	return kbd_was_pressed(k);
356 }
357 
358 
c_wait_for_key(void)359 void c_wait_for_key(void)
360 {
361 	kbd_wait_for_key();
362 }
363 
364 
365 /* set cursor shape */
c_cursor(int type)366 void c_cursor(int type)
367 {
368 	type=type;
369 }
370 
371 
372 /* ring the bell */
c_bell(void)373 void c_bell(void)
374 {
375 	XBell(display,100);
376 }
377 
378 
379 /* get screen dimensions */
c_get_size(int * x,int * y)380 void c_get_size(int *x, int *y)
381 {
382 	(*x)=x_width;
383 	(*y)=x_height;
384 }
385