1 /*
2 XBlockOut a 3D Tetris
3
4 Copyright (C) 1992,1993,1994,2001 Thierry EXCOFFIER
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 Contact: Thierry.EXCOFFIER@liris.univ-lyon1.fr
21 */
22 #include "bl.h"
23 #include "icone.h"
24 #include <stdio.h>
25 #include <X11/Xatom.h>
26 #include <X11/Xutil.h>
27
28 #if HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #ifdef HAVE_MALLOC_H
32 #include "malloc.h"
33 #endif
34 #if HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #if HAVE_STRING_H
39 #include <string.h>
40 #else
41 #include <strings.h>
42 #endif
43
restorecolor(Display * d,int n,Colormap c1,Colormap c2)44 void restorecolor(Display *d, int n, Colormap c1, Colormap c2)
45 {
46 XColor *c ;
47 unsigned int i ;
48 unsigned long plane_mask ;
49 unsigned long *pixel ;
50
51 c = (XColor *) malloc( n*sizeof(XColor) ) ;
52 pixel = (unsigned long*) malloc( n*sizeof(unsigned long) ) ;
53
54 XAllocColorCells(d,c1,False,&plane_mask,0,pixel,n) ;
55
56 for(i=0;i<n;i++)
57 if ( pixel[i] != (unsigned long)i )
58 {
59 fprintf(stderr,"Future Problems... pixel[%ld]=%d\n", pixel[i],i);
60 break ;
61 }
62
63 for(i=0;i<n;i++) c[i].pixel = i ;
64
65 XQueryColors(d,c2,c,n) ;
66
67 for(i=0;i<n;i++) c[i].flags = DoRed|DoGreen|DoBlue ;
68
69 XStoreColors(d,c1,c,n) ;
70
71 free( (void*) c) ;
72 free( (void*) pixel) ;
73 }
74
75
76
initwin(struct opt * opt,struct x * x)77 void initwin(struct opt *opt, struct x *x)
78 {
79 XSetWindowAttributes wa ;
80 XSizeHints sh ;
81 XTextProperty tp ;
82 char buf[LINE_LENGTH] ;
83
84 x->icone = XCreateBitmapFromData(x->display,x->root,
85 icone_bits,icone_width,icone_height) ;
86
87 if ( opt->buffering==1 || opt->buffering==3 || opt->buffering==4 )
88 {
89 if ( x->map_entries >= (opt->buffering!=3?16:32) &&
90 ( x->visual->class==PseudoColor || x->visual->class==GrayScale )
91 )
92 {
93 opt->newmap = 1 ;
94 }
95 else
96 {
97 fprintf(stderr,"Can't make single buffering because :\n");
98 fprintf(stderr," Your display hasn't %d colors (only %ld)\n",
99 (opt->buffering!=3 ? 16: 32), x->map_entries);
100 fprintf(stderr," OR Colors cannot be changed (truecolor)\n");
101 fprintf(stderr,"\nTry to use the option '-visual 1'\n") ;
102 exit(1) ;
103 }
104 }
105
106 if ( opt->newmap )
107 {
108 if ( opt->verbose ) fprintf(stderr,"START newcolormap\n") ;
109 x->color1 = XCopyColormapAndFree(x->display,x->colormap) ;
110 if ( opt->verbose ) fprintf(stderr," Create OK\n") ;
111 restorecolor(x->display,(int)x->map_entries,
112 x->color1,x->colormap) ;
113 if ( opt->verbose ) fprintf(stderr," Colors OK\n") ;
114 if (opt->buffering==3)
115 {
116 x->color2 = XCopyColormapAndFree(x->display,x->colormap) ;
117 restorecolor(x->display,(int)x->map_entries,
118 x->color2,x->colormap) ;
119 x->colormap = x->color1 ;
120 x->black_pixel = x->map_entries - 4*(opt->use_bw?2:8) ;
121 x->white_pixel = x->black_pixel + (opt->use_bw?2:8)-1 ;
122 }
123 else { x->colormap = x->color1 ;
124 x->black_pixel = x->map_entries - 2*(opt->use_bw?2:8) ;
125 x->white_pixel = x->black_pixel + (opt->use_bw?2:8)-1 ;
126 }
127 if ( opt->verbose ) fprintf(stderr,"END newcolormap\n") ;
128 }
129
130 if ( opt->verbose )
131 {
132 fprintf(stderr,"display=%p\n",x->display);
133 fprintf(stderr,"screen=%d\n",x->screen);
134 fprintf(stderr,"root=%lu\n",x->root);
135 fprintf(stderr,"depth=%d\n",x->depth);
136 fprintf(stderr,"colormap=%lu\n",x->colormap);
137 fprintf(stderr,"DISPLAY open OK\n");
138 }
139
140 x->posx = 0 ;
141 x->posy = 0 ;
142
143 if ( opt->geometry[0]!='\0' )
144 {
145 MyXParseGeometry(x->display,x->screen,opt->geometry,&x->posx,&x->posy,
146 (unsigned int*)&x->dimx,(unsigned int*)&x->dimy) ;
147 }
148
149 wa.event_mask = KeyPressMask|KeyReleaseMask|ExposureMask|StructureNotifyMask
150 |FocusChangeMask ;
151 wa.background_pixel = x->black_pixel ;
152
153 x->window = XCreateWindow(
154 x->display,
155 x->root,
156 x->posx,x->posy,
157 (unsigned int)x->dimx,(unsigned int)x->dimy,
158 0,
159 x->depth,
160 InputOutput,
161 x->visual,
162 CWEventMask|CWBackPixel,
163 &wa);
164
165 XSetWindowColormap(x->display,x->window,x->colormap) ;
166
167 gethostname(buf,LINE_LENGTH) ;
168 tp.value = (unsigned char*)buf ;
169 tp.encoding = XA_STRING ;
170 tp.format = 8 ;
171 tp.nitems = strlen((char*)tp.value) ;
172 XSetWMClientMachine(x->display,x->window,&tp) ;
173
174 sh.flags = PResizeInc|PBaseSize ;
175 if ( opt->geometry[0]!='\0' ) sh.flags |= PPosition ;
176
177 sh.width_inc = 2 ; /* Size must always be ODD in X and Y */
178 sh.height_inc = 2 ;
179 sh.base_width = 3 ;
180 sh.base_height = 3 ;
181 sh.x = x->posx ;
182 sh.y = x->posy ;
183 XSetWMNormalHints( x->display,x->window,&sh ) ;
184
185
186 x->back = 0 ;
187 x->work = 0 ;
188 XMapWindow( x->display,x->window) ;
189 }
190
191 /* Create the argument string, to set window properties */
192 /* This function is call when a change arise */
193
194 #define ADDARG(X) { sprintf(pc,"%s",X) ; argv[i++] = pc ; pc += strlen(pc)+1 ; }
195
setargs(struct bl * bl)196 void setargs(struct bl *bl)
197 {
198 char *argv[LINE_LENGTH] ;
199 char tt[10*LINE_LENGTH] ; /* Text of the parameters */
200 char tmp[LINE_LENGTH] ;
201 char *pc ;
202 int i ;
203 Window gar ;
204 int x,y ;
205 unsigned int nbc ;
206 unsigned int dx,dy,gar2,gar3 ;
207 XTextProperty tp,tp2 ;
208 XWMHints wh ;
209 Window w,root,father,*childrens[1] ;
210
211 i = 0 ;
212 pc = tt ;
213
214 ADDARG(bl->progname) ;
215
216 if ( bl->x.window )
217 {
218 XQueryTree(bl->x.display,bl->x.window,&root,&father,childrens,&nbc) ;
219 XGetGeometry(bl->x.display,bl->x.window,&gar,&x,&y,&dx,&dy,&gar2,&gar3) ;
220 XTranslateCoordinates(bl->x.display,father,bl->x.root,0,0,&x,&y,&w) ;
221 ADDARG("-geometry") ;
222 sprintf(tmp,"%dx%d+%d+%d",dx,dy,x,y) ;
223 ADDARG(tmp) ;
224 }
225
226 if ( bl->menu.window )
227 {
228 XQueryTree(bl->x.display,bl->menu.window,&root,&father,childrens,&nbc) ;
229 XGetGeometry(bl->x.display,bl->menu.window,&gar,&x,&y,&dx,&dy,&gar2,&gar3) ;
230 XTranslateCoordinates(bl->x.display,father,bl->x.root,0,0,&x,&y,&w) ;
231 ADDARG("-menugeometry") ;
232 sprintf(tmp,"%dx%d+%d+%d",dx,dy,x,y) ;
233 ADDARG(tmp) ;
234 }
235
236 if ( bl->x.wscore )
237 {
238 XQueryTree(bl->x.display,bl->x.wscore,&root,&father,childrens,&nbc) ;
239 XGetGeometry(bl->x.display,bl->x.wscore,&gar,&x,&y,&dx,&dy,&gar2,&gar3) ;
240 XTranslateCoordinates(bl->x.display,father,bl->x.root,0,0,&x,&y,&w) ;
241 ADDARG("-scoregeometry") ;
242 sprintf(tmp,"%dx%d+%d+%d",dx,dy,x,y) ;
243 ADDARG(tmp) ;
244 }
245
246 if ( bl->menu.zoo )
247 {
248 XQueryTree(bl->x.display,bl->menu.zoo,&root,&father,childrens,&nbc) ;
249 XGetGeometry(bl->x.display,bl->menu.zoo,&gar,&x,&y,&dx,&dy,&gar2,&gar3) ;
250 XTranslateCoordinates(bl->x.display,father,bl->x.root,0,0,&x,&y,&w) ;
251 ADDARG("-zoogeometry") ;
252 sprintf(tmp,"%dx%d+%d+%d",dx,dy,x,y) ;
253 ADDARG(tmp) ;
254 }
255
256 if ( bl->opt.smooth ) ADDARG("-smooth") ;
257 if ( bl->menu.showzoo ) ADDARG("-zoo") ;
258 if ( bl->menu.showscore ) ADDARG("-score") ;
259 if ( bl->opt.newmap ) ADDARG("-colormap") ;
260 if ( bl->opt.presskey ) ADDARG("-presskey") ;
261 if ( bl->opt.use_bw ) ADDARG("-bw") ;
262 if ( bl->opt.clearline ) ADDARG("-clearline") ;
263 if ( bl->opt.mode==TRAINING ) ADDARG("-training") ;
264 if ( bl->bloc.nextpiece ) ADDARG("-shownext") ;
265
266 ADDARG("-draw") ; sprintf(tmp,"%d",bl->opt.drawmode) ; ADDARG(tmp) ;
267 ADDARG("-linewidth") ; sprintf(tmp,"%d",bl->opt.linewidth) ; ADDARG(tmp) ;
268 ADDARG("-buffer") ; sprintf(tmp,"%d",bl->opt.buffering) ; ADDARG(tmp) ;
269 ADDARG("-volume") ; sprintf(tmp,"%d",bl->opt.volume) ; ADDARG(tmp) ;
270 ADDARG("-land") ; sprintf(tmp,"%d",bl->opt.land) ; ADDARG(tmp) ;
271 ADDARG("-x") ; sprintf(tmp,"%d",bl->opt.wx) ; ADDARG(tmp) ;
272 ADDARG("-y") ; sprintf(tmp,"%d",bl->opt.wy) ; ADDARG(tmp) ;
273 ADDARG("-z") ; sprintf(tmp,"%d",bl->opt.wz) ; ADDARG(tmp) ;
274 ADDARG("-level") ; sprintf(tmp,"%d",bl->opt.level) ; ADDARG(tmp) ;
275 ADDARG("-buttonheight");sprintf(tmp,"%d",bl->opt.button_height);ADDARG(tmp) ;
276 ADDARG("-keyboard") ; sprintf(tmp,"%d",bl->opt.keyboard) ; ADDARG(tmp) ;
277 ADDARG("-color") ; sprintf(tmp,"%d",bl->opt.backcolor) ; ADDARG(tmp) ;
278 ADDARG("-bloctype") ; sprintf(tmp,"%d",bl->bloc.typepiece) ; ADDARG(tmp) ;
279 ADDARG("-time_to_demo");sprintf(tmp,"%d",bl->opt.time_to_demo); ADDARG(tmp) ;
280 ADDARG("-eyedistance"); sprintf(tmp,"%g",bl->opt.eye_distance); ADDARG(tmp) ;
281 if ( bl->opt.keyboard==0 )
282 {
283 ADDARG("-keytable") ;
284 sprintf(tmp,"%s",bl->opt.userkey) ;
285 ADDARG(tmp) ;
286 }
287 ADDARG("-font") ; ADDARG(bl->opt.thefont) ;
288 ADDARG("-bigfont") ; ADDARG(bl->opt.thefont2) ;
289
290 sprintf(tmp,"XBlockOut %s",XBLVERSION) ;
291 tp.value = (unsigned char*)tmp ;
292 tp.encoding = XA_STRING ;
293 tp.format = 8 ;
294 tp.nitems = strlen((char*)tp.value) ;
295
296 tp2.value = (unsigned char*)"XBlockOut" ;
297 tp2.encoding = XA_STRING ;
298 tp2.format = 8 ;
299 tp2.nitems = strlen((char*)tp2.value) ;
300
301 wh.flags = IconPixmapHint ;
302 wh.icon_pixmap = bl->x.icone ;
303
304 XSetWMProperties(bl->x.display,bl->x.window,&tp,&tp2,
305 argv,i,
306 NULL,&wh,NULL ) ;
307 /*
308 { int j ; for(j=0;j<i;j++) printf("%s ",argv[j]) ; printf("\n") ; }
309 */
310 }
311
312 /* Compute window position, WHY THIS FUNCTION IS NOT IN XLIB? */
313 /* I have found it (too late) thanks to Brian V. SMITH */
314
MyXParseGeometry(Display * d,int s,char * c,int * x,int * y,unsigned int * dx,unsigned int * dy)315 void MyXParseGeometry(Display *d, int s, char *c, int *x, int *y, unsigned int *dx, unsigned int *dy)
316 {
317 *x = 0 ;
318 *y = 0 ;
319 *dy = 0 ;
320
321 *dx = atoi(c) ;
322 while( *c && *c!='x' ) c++ ;
323 if ( *c==0 ) return ;
324 c++ ;
325 *dy = atoi(c) ;
326 while( *c && *c!='+' && *c!='-' ) c++ ;
327 if ( *c==0 ) return ;
328 if ( *c=='+' ) *x = atoi(c+1) ;
329 else *x = DisplayWidth(d,s) - atoi(c+1) - *dx ;
330 c++ ;
331 if ( *c==0 ) return ;
332 if ( *c=='-' || *c=='+' ) c++ ;
333 while( *c && *c!='+' && *c!='-' ) c++ ;
334 if ( *c==0 ) return ;
335 if ( *c=='+' ) *y = atoi(c+1) ;
336 else *y = DisplayHeight(d,s) - atoi(c+1) - *dy ;
337 }
338