magicpoint-1.10a.tar.gz (MirPorts)
[alioth/magicpoint.git] / x11.c
1 /*
2  * Copyright (C) 1997 and 1998 WIDE Project.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the project nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * $Id: x11.c,v 1.29 2003/05/19 07:29:45 nishida Exp $
30  */
31
32 #include "mgp.h"
33
34 /* covered by gcconf */
35 GC gcfore;
36 GC gcpen;
37 GC gcred;
38 GC gcgreen;
39 GC gcyellow;
40
41 /* not covered by gcconf */
42 GC gc_pl;
43 GC gc_plrev;
44 GC gc_pta;
45 GC gc_ptk;
46
47 /* for caching */
48 GC gc_cache;
49
50 long xeventmask = EVENT_DEFAULT | EVENT_RAKUGAKI;
51
52 static u_long zero = 0;
53
54 static struct gcconf {
55         GC *gc;
56         int func;
57         u_long *fore;
58         u_long *back;
59         char *color;
60 } gcconf[]  = {
61         { &gcfore,      GXcopy, &fore_color[0], &zero },
62         { &gcpen,       GXcopy, NULL, NULL, "red" },
63         { &gcred,       GXcopy, NULL, NULL, "red" },
64         { &gcgreen,     GXcopy, NULL, NULL, "green" },
65         { &gcyellow,    GXcopy, NULL, NULL, "yellow" },
66         { NULL },
67 };
68
69 static XWindowAttributes xa;
70
71 int window_x;
72 int window_y;
73
74 Visual *
75 get_visual(display, screen, depthp)
76         Display *display;
77         int screen;
78         u_int *depthp;
79 {
80         XVisualInfo *best, *vinfo, vinfo_template;
81         Visual *ret;
82         int vinfo_mask, i, ninfo;
83
84         vinfo_template.screen = screen;
85         vinfo_mask = VisualScreenMask;
86
87         vinfo = XGetVisualInfo(display, vinfo_mask, &vinfo_template, &ninfo);
88         best = NULL;
89         for (i = 0; i < ninfo; i++) {
90                 switch (vinfo[i].class) {
91                 case TrueColor:
92                         if (vinfo[i].depth < 15)
93                                 break;
94                         if (best == NULL ||
95                             best->class != TrueColor ||
96                             best->depth < vinfo[i].depth)
97                                 best = &vinfo[i];
98                         break;
99                 case PseudoColor:
100                         if (best == NULL)
101                                 best = &vinfo[i];
102                         break;
103                 }
104         }
105         if (best) {
106                 ret = best->visual;
107                 *depthp = best->depth;
108         } else {
109                 ret = DefaultVisual(display, screen);
110                 *depthp = DefaultDepth(display, screen);
111         }
112         XFree(vinfo);
113         return ret;
114 }
115
116 void
117 init_win1(geometry)
118         char *geometry;
119 {
120         int xloc, yloc;
121         int xsiz, ysiz;
122         int mode;
123         u_int i;
124
125         if ((display = XOpenDisplay(NULL)) == NULL) {
126                 fprintf(stderr, "Can't open display\n");
127                 exit(-1);
128         }
129         screen = DefaultScreen(display);
130         visual = get_visual(display, screen, &depth);
131         depth_mask = 1;
132         for (i = depth; i; i--)
133                 depth_mask *= 2;
134         depth_mask--;
135         /* depth_mask is the max value of pixel */
136
137         XGetWindowAttributes(display, DefaultRootWindow(display), &xa);
138
139         /* determine geometry to use. */
140         window_width = window_height = -1;
141         window_x = window_y = -1;
142         if (geometry) {
143                 mode = XParseGeometry(geometry, &xloc, &yloc,
144                         &xsiz, &ysiz);
145                 if (mode == 0) {
146                         fprintf(stderr, "bad geometry string %s\n",
147                                 geometry);
148                         exit(-1);
149                 }
150                 if (!(mode & WidthValue))
151                         xsiz = -1;
152                 if (!(mode & HeightValue))
153                         ysiz = -1;
154                 if (!(mode & XValue))
155                         xloc = -1;
156                 if (!(mode & YValue))
157                         yloc = -1;
158         } else {
159                 xsiz = ysiz = -1;
160                 xloc = yloc = -1;
161                 mode = 0;
162         }
163
164         if (xsiz < 0) {
165                 window_width = ((mgp_flag & FL_OVER) && !(mgp_flag & FL_NODECORATION))
166                         ? (int)(xa.width * 96 / 100)
167                         : xa.width;
168         } else
169                 window_width = xsiz;
170         if (ysiz < 0) {
171                 window_height = ((mgp_flag & FL_OVER) && !(mgp_flag & FL_NODECORATION))
172                         ? (int)(xa.height * 96 / 100)
173                         : xa.height;
174         } else
175                 window_height = ysiz;
176
177         if (0 <= xloc) {
178                 window_x = (mode & XNegative)
179                         ? xa.width - window_width - xloc
180                         : xloc;
181         }
182         if (0 <= yloc) {
183                 window_y = (mode & YNegative)
184                         ? xa.height - window_height - yloc
185                         : yloc;
186         }
187 #if 0
188         if (window_x < 0)
189                 window_x = 0;   /*XXX*/
190         if (window_y < 0)
191                 window_y = 0;   /*XXX*/
192 #endif
193         if (visual != DefaultVisual(display, screen))
194                 colormap = XCreateColormap(display, RootWindow(display, screen), visual, AllocNone);
195         else {
196                 colormap = DefaultColormap(display, screen);
197                 if (mgp_flag & FL_PRIVATE)
198                         colormap = XCopyColormapAndFree(display, colormap);
199         }
200
201         char_size[0] = window_height * DEFAULT_CHARSIZE / 100;
202         (void)get_color(DEFAULT_FORE, &fore_color[0]);
203         ctrl_color[0] = fore_color[0];
204
205         (void)get_color(back_clname, &back_color[0]);
206 }
207
208 void
209 init_win2()
210 {
211         XSetWindowAttributes xsa;
212         XSizeHints hints;
213         u_long mask;
214         struct gcconf *pc;
215         u_long color;
216         XClassHint res = { "MagicPoint", "MagicPoint" };
217         int     i;
218
219         xsa.border_pixel = fore_color[0];
220         xsa.background_pixel = back_color[0];
221         xsa.backing_store = Always;
222         xsa.colormap = colormap;
223         mask = CWBorderPixel | CWBackPixel | CWBackingStore | CWColormap;
224         if (!(mgp_flag & FL_OVER)) {
225                 xsa.override_redirect = True;
226                 mask |= CWOverrideRedirect;
227         }
228         window = XCreateWindow(display, RootWindow(display, screen),
229                 (window_x < 0) ? 0 : window_x,
230                 (window_y < 0) ? 0 : window_y,
231                 (window_width < 0) ? 0 : window_width,
232                 (window_height < 0) ? 0 : window_height,
233                 0, depth, InputOutput, visual, mask, &xsa);
234         XStoreName(display, window, "MagicPoint");
235         XSetIconName(display, window, "MagicPoint");
236         XSetClassHint(display, window, &res);
237         pixmap = XCreatePixmap(display, window, xa.width, xa.height, depth);
238         maskpix = XCreatePixmap(display, window, xa.width, xa.height, depth);
239         cachewin = XCreatePixmap(display, window, xa.width, xa.height, depth);
240         cachetmp = XCreatePixmap(display, window, xa.width, xa.height, depth);
241         gc_cache = XCreateGC(display, window, 0, 0);
242
243         for (pc = &gcconf[0]; pc->gc; pc++) {
244                 *pc->gc = XCreateGC(display, window, 0, 0);
245                 XSetFunction(display, *pc->gc, pc->func);
246                 if (pc->fore)
247                         XSetForeground(display, *pc->gc, *pc->fore);
248                 if (pc->back)
249                         XSetBackground(display, *pc->gc, *pc->back);
250                 if (pc->color) {
251                         (void)get_color(pc->color, &color);
252                         XSetForeground(display, *pc->gc, color);
253                 }
254         }
255
256         if (mgp_flag & FL_OVER){
257                 if (0 <= window_x && 0 <= window_y) {
258                         hints.x = window_x;
259                         hints.y = window_y;
260                         hints.flags = USPosition;
261                         XSetNormalHints(display, window, &hints);
262                 }
263         }
264         if (mgp_flag & FL_NODECORATION) 
265                 XSetTransientForHint(display, window, window);
266
267         XMapRaised(display, window);
268
269 #if 0
270 #if 0
271         if (!(mgp_flag & FL_OVER))
272 #else
273         if (0 <= window_x && 0 <= window_y)
274 #endif
275                 XMoveWindow(display, window, window_x, window_y);
276
277         XFlush(display);
278 #endif
279
280         gc_pl = XCreateGC(display, window, 0, 0);
281         gc_plrev = XCreateGC(display, window, 0, 0);
282         gc_pta = XCreateGC(display, window, 0, 0);
283         gc_ptk = XCreateGC(display, window, 0, 0);
284         plfs = XLoadQueryFont(display, PAGELIST_FONT);
285         plkfs = XLoadQueryFont(display, PAGELIST_KFONT);
286         if (plfs) {
287                 XSetFont(display, gc_pl, plfs->fid);
288                 XSetFont(display, gc_plrev, plfs->fid);
289                 XSetFont(display, gc_pta, plfs->fid);
290         } else 
291                 fprintf(stderr, 
292                 "cannot find %s font. please modify PAGELIST_FONT to display page guide.\n", 
293                                 PAGELIST_FONT); 
294
295         if (plkfs)
296                 XSetFont(display, gc_ptk, plkfs->fid);
297         else 
298                 fprintf(stderr, "cannot find %s font.\n", PAGELIST_KFONT); 
299
300         XSetFunction(display, gc_pl, GXcopy);
301         XSetFunction(display, gc_plrev, GXcopy);
302         XSetFunction(display, gc_pta, GXcopy);
303         XSetFunction(display, gc_ptk, GXcopy);
304         XSetForeground(display, gc_pl, BlackPixel(display, screen));
305         XSetBackground(display, gc_pl, WhitePixel(display, screen));
306         XSetForeground(display, gc_plrev, WhitePixel(display, screen));
307         XSetBackground(display, gc_plrev, BlackPixel(display, screen));
308         if (plfs) {
309                 pl_fh = (plfs->max_bounds.ascent + plfs->max_bounds.descent) * 1.2;
310                 pl_fw = plfs->max_bounds.rbearing + plfs->max_bounds.lbearing;
311                 if (!plkfs) plkfs = plfs;
312         }
313 }
314
315 void
316 init_win3()
317 {
318         Window dummy;
319         int revert;
320
321         XSelectInput(display, window, xeventmask);
322
323         if (!(mgp_flag & FL_OVER)) {
324                 XGetInputFocus(display, &dummy, &revert);
325                 XSetInputFocus(display, window, RevertToParent, CurrentTime);
326                 if (XGrabKeyboard(display, window, True, 
327                         GrabModeAsync, GrabModeAsync, CurrentTime)
328                                 != GrabSuccess) {
329                         fprintf(stderr, "XGrabKeyboard failed. sorry \n");
330                         exit(-1);
331                 }
332                 if (XGrabPointer(display, window, True, ButtonPressMask,
333                         GrabModeAsync, GrabModeAsync, window, None, CurrentTime)
334                                 != GrabSuccess) {
335                         fprintf(stderr, "XGrabPointer failed. sorry \n");
336                         exit(-1);
337                 }
338         }
339
340 }
341
342 void
343 finish_win()
344 {
345         XUngrabKeyboard(display, CurrentTime);  
346         XUngrabPointer(display, CurrentTime);   
347         XCloseDisplay(display); 
348 }
349
350 int
351 get_color(colorname, value)
352         char *colorname;
353         u_long *value;
354 {
355         XColor c0, c1;
356
357         screen = DefaultScreen(display);
358 /*XXX*/
359         if (strcasecmp(colorname, "darkblue") == 0)
360                 colorname = "#00008b";
361         if (XAllocNamedColor(display, colormap, colorname, &c1, &c0) == 0)
362                 return -1;
363         if (value)
364                 *value = c1.pixel;
365         return 0;
366 }
367
368 struct g_color *
369 name2gcolor(colorname)
370         char *colorname;
371 {
372         XColor c0, c1;
373         struct g_color *color;
374
375         color = (struct g_color *)malloc(sizeof(struct g_color));
376
377         if (XLookupColor(display, colormap, colorname, &c1, &c0)) {
378                 color->r = (c1.red >> 8) & 0xff;
379                 color->g = (c1.green >> 8) & 0xff;
380                 color->b = (c1.blue >> 8) & 0xff;
381         } else {
382                 fprintf(stderr,"color '%s' unknown. ignored.\n", colorname);
383         }           
384
385         return color;
386 }
387
388 void
389 free_alloc_colors(clr) 
390 struct  alloc_color *clr;
391 {   
392 #ifndef COLOR_BUGFIX
393         if (!(mgp_flag & FL_PRIVATE)) return;
394 #endif
395         if (clr->num){
396                 XFreeColors(display, colormap, clr->colors, clr->num, 0);
397                 free(clr->colors);
398                 clr->colors = NULL;
399                 clr->num = 0;
400         }
401 }
402
403 void
404 regist_alloc_colors(clr, colors, num)
405 struct  alloc_color *clr;
406 u_long  *colors;
407 int     num;
408 {
409         u_int   i;
410  
411 #ifndef COLOR_BUGFIX
412         if (!(mgp_flag & FL_PRIVATE)) return;
413 #endif
414         if (!clr->num)
415                 clr->colors = (long *)malloc(sizeof(u_long) * num);
416         else
417                 clr->colors = (long *)realloc(clr->colors,
418                                                 sizeof(u_long) * (clr->num + num));
419         for (i = 0; i < num; i++)
420                 clr->colors[clr->num +i] = (u_long)*(colors +i);
421         clr->num += num;
422 }
423
424 void
425 reset_cache_pixmap()
426 {
427         int     i;
428
429         XFreePixmap(display, cachewin);
430         XFreePixmap(display, cachetmp);
431         cachewin = XCreatePixmap(display, window, xa.width, xa.height, depth);
432         cachetmp = XCreatePixmap(display, window, xa.width, xa.height, depth);
433 }