1 /*
2   XBlockOut a 3D Tetris
3 
4   Copyright (C) 1992,1993,1994,1997,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 "opt.h"
23 #include "x.h"
24 #include <X11/keysym.h>
25 #include <X11/Xutil.h>
26 #include <stdio.h>
27 
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #if HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 
35 #if HAVE_STRING_H
36 #include <string.h>
37 #else
38 #include <strings.h>
39 #endif
40 
41 
SymCode(Display * d,char * key)42 void SymCode(Display *d, char *key)
43 {
44   int i,j,min,max ;
45   KeySym *map ;
46   int nbmod,nb ;
47 
48   XDisplayKeycodes(d,&min,&max) ;
49   nb = max-min+1 ;
50   map = XGetKeyboardMapping(d,min,nb,&nbmod) ;
51   for(i=0;i<256;i++) key[i] = 0 ;
52   for(i=0;i<nb;i++)
53     {
54       key[i+min] = 0 ;
55       for(j=0;j<nbmod;j++)
56 	{
57 	  if ( map[i*nbmod+j]>= XK_KP_0 && map[i*nbmod+j]<= XK_KP_9 )
58 	    key[i+min] = map[i*nbmod+j] - XK_KP_0 + '0' ;
59 	  else
60 	    switch ( map[i*nbmod+j] )
61 	      {
62 	      case XK_Left : key[i+min] = '4' ; break ;
63 	      case XK_Right: key[i+min] = '6' ; break ;
64 	      case XK_Up   : key[i+min] = '8' ; break ;
65 	      case XK_Down : key[i+min] = '2' ; break ;
66 	      }
67 	}
68     }
69 }
70 
initdisp(struct opt * opt,struct x * x)71 void initdisp(struct opt *opt, struct x *x)
72 {
73   int i ;
74   char *name ;
75 
76   if ( opt->displayname[0]!='\0' )
77     x->display = XOpenDisplay(opt->displayname) ;
78   if ( x->display==0 )
79     {
80       name = getenv("DISPLAY") ;
81       if ( name==0 )
82 	{
83 	  fprintf(stderr,"Xbl is an X11 game\n") ;
84 	  fprintf(stderr,"And your DISPLAY variable doesn't exist\n") ;
85 	  fprintf(stderr,"Goodbye\n") ;
86 	  exit(1) ;
87 	}
88       STRCPY_SAFE(opt->displayname,name) ;
89       x->display = XOpenDisplay(opt->displayname) ;
90     }
91   if ( x->display==0 )
92     {
93       fprintf(stderr,"Cannot open display\n");
94       exit(1) ;
95     }
96   x->screen = DefaultScreen( x->display ) ;
97   i = strlen(opt->displayname) ;
98   if ( opt->displayname[i-2]=='.' )
99     {
100       x->screen = opt->displayname[i-1] - '0' ;
101     }
102   if ( x->screen>=ScreenCount(x->display) )
103     {
104       /* This case is impossible XOpenDisplay change the string */
105       fprintf(stderr,"You give an invalide screen number\n") ;
106       exit(1) ;
107     }
108   x->root        = RootWindow( x->display,x->screen ) ;
109   x->depth       = DefaultDepth(x->display,x->screen);
110 }
111 
initdisp2(struct opt * opt,struct x * x)112 void initdisp2(struct opt *opt, struct x *x)
113 {
114   XVisualInfo viproto;                /* fill in for getting info */
115   XVisualInfo *vip;                   /* retured info */
116   int nbv ;
117   int i ;
118 
119   x->visual      = DefaultVisual(x->display,x->screen) ;
120   x->colormap    = DefaultColormap( x->display, x->screen) ;
121 
122   if ( opt->verbose )
123     {
124       fprintf(stderr,"DEFAULT Colormap %ld visual %p\n",x->colormap, x->visual) ;
125     }
126   /*-----------------------------------------*/
127   /* Find the PseudoColor with maximum depth */
128   /* It's obviously not a good method        */
129   /*-----------------------------------------*/
130   if ( opt->visual )
131     {
132       int new_visual ;
133 
134       viproto.screen = x->screen ;
135       viproto.class  = PseudoColor ;
136       vip = XGetVisualInfo (x->display, VisualScreenMask|VisualClassMask, &viproto, &nbv);
137 
138 
139       if ( opt->verbose )
140 	fprintf(stderr,"Number of Visual --------------> %d\n",nbv) ;
141 
142       new_visual = 0 ;
143 
144       for(i=0;i<nbv;i++)
145 	{
146 	  if ( opt->verbose )
147 	    fprintf(stderr,"PSEUDOCOLOR %d entries\n",
148 		    vip[i].visual->map_entries) ;
149 	  if ( x->visual->class != PseudoColor ||
150 	       vip[i].visual->map_entries > x->visual->map_entries
151 	       )
152 	    {
153 	      if ( opt->verbose )
154 		{
155 		  fprintf(stderr,"I USE IT VisualID %ld!!!!!\n",
156 			  vip[i].visual->visualid) ;
157 		}
158 	      x->visual = vip[i].visual ;
159 	      new_visual = 1 ;
160 	      if ( x->visual->map_entries>=128 ) break ; /* No more useful */
161 	    }
162 	}
163 
164       if ( new_visual )
165 	{
166 	  x->colormap = XCreateColormap( x->display, x->root, x->visual, AllocNone) ;
167 	  if ( opt->verbose )
168 	    {
169 	      fprintf(stderr,"Colormap %ld created\n",x->colormap) ;
170 	    }
171 	}
172 
173     }
174 
175 
176   /*-----------------------------------------*/
177   /*-----------------------------------------*/
178 
179   x->map_entries = x->visual->map_entries ;
180   if ( x->map_entries&1 ) x->map_entries = (x->map_entries+1)/2 ;
181 
182   x->white_pixel = XWhitePixel(x->display,x->screen) ;
183   x->black_pixel = XBlackPixel(x->display,x->screen) ;
184 
185   if ( opt->buffering==-1)
186     {
187       if (x->visual->class==PseudoColor || x->visual->class==GrayScale)
188 	{
189 	  if ( opt->use_bw )
190 	    {
191 	      if ( x->map_entries>=4 )
192 		if ( x->map_entries>=8 )
193 		  opt->buffering=3 ;
194 		else opt->buffering=1 ;
195 	      else opt->buffering=2 ;
196 	    }
197 	  else {
198 	    if ( x->map_entries>=16 )
199 	      if ( x->map_entries>=32 )
200 		opt->buffering=3 ;
201 	      else opt->buffering=1 ;
202 	    else opt->buffering=2 ;
203 	  }
204 	}
205       else opt->buffering = 2 ;
206       if ( opt->verbose )
207 	fprintf(stderr,"I choose buffering=%d\n",opt->buffering) ;
208     }
209   SymCode(x->display,x->codes) ;
210 }
211