1 /*****
2  *       Xnee's Not an Event Emulator
3  *
4  * Xnee enables recording and replaying of X protocol data
5  *
6  *  Copyright (C) 1999, 2000, 2001, 2002, 2003,
7  *                2004, 2008, 2009, 2010, 2011  Henrik Sandklef
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 3
12  * of the License, or any later version.
13  *
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Boston,
23  * MA  02110-1301, USA.
24  ****/
25 
26 
27 #include <stdio.h>
28 #include <string.h>
29 
30 #include "libxnee/xnee.h"
31 #include "libxnee/xnee_error.h"
32 #include "libxnee/xnee_display.h"
33 #include "libxnee/print_varargs.h"
34 #include "libxnee/xnee_resolution.h"
35 #include "libxnee/xnee_display.h"
36 #include "libxnee/xnee_xinput.h"
37 
38 /**************************************************************
39  *                                                            *
40  * xnee_setup_display                                         *
41  *                                                            *
42  *                                                            *
43  **************************************************************/
44 int
xnee_setup_display(xnee_data * xd)45 xnee_setup_display (xnee_data *xd)
46 {
47   int ret;
48 
49   xnee_verbose((xd, "-- xnee_setup_display - data display\n"));
50   if (xd->data!=NULL)
51     {
52       /*
53       xnee_verbose((xd, "-- xnee_setup_display - close data display\n"));
54       XFlush(xd->data);
55       XCloseDisplay(xd->data);*/
56     }
57   else
58     {
59       xnee_verbose((xd, "-- xnee_setup_display - open data display\n"));
60       xd->data     = xnee_open_display (xd);
61     }
62   if (xd->data==NULL)
63     {
64       return XNEE_NOT_OPEN_DISPLAY;
65     }
66 
67 
68 
69   xnee_verbose((xd, "-- xnee_setup_display - control display\n"));
70   if (xd->control!=NULL)
71     {
72       XCloseDisplay(xd->control);
73     }
74   xd->control  = xnee_open_display (xd);
75   if (xd->control==NULL)
76     {
77       return XNEE_NOT_OPEN_DISPLAY;
78     }
79 
80 
81 
82   xnee_verbose((xd, "-- xnee_setup_display - fake display\n"));
83   if (xd->fake!=NULL)
84     {
85       XCloseDisplay(xd->fake);
86     }
87   xd->fake     = xnee_open_display (xd);
88   if (xd->fake==NULL)
89     {
90       return XNEE_NOT_OPEN_DISPLAY;
91     }
92 
93   xnee_verbose((xd, "-- xnee_setup_display - modifier map\n"));
94 
95   xnee_verbose((xd, "Freeing modifier mapping memory %p ", (void*)xd->map));
96   XFreeModifiermap(xd->map);
97 
98   xnee_verbose((xd," building modifier map on %p\n", (void*)xd->fake));
99   xd->map = XGetModifierMapping(xd->fake);
100 
101 
102   xnee_verbose((xd, "display data    %p\n" , (void*) xd->data));
103   xnee_verbose((xd, "display control %p\n" , (void*) xd->control));
104   xnee_verbose((xd, "display fake    %p\n" , (void*) xd->fake));
105 
106   xnee_verbose((xd, "-- xnee_setup_display - resolution\n"));
107   /*
108    * resolution */
109   ret = xnee_set_default_rec_resolution (xd);
110 
111   if ( ret != XNEE_OK )
112     {
113       return XNEE_NOT_OPEN_DISPLAY;
114     }
115 
116 
117 #ifdef  XNEE_XINPUT_SUPPORT
118   ret = xnee_get_xinput_event_base(xd->control);
119   if ( ret > 0 )
120     {
121       xd->xi_data.xinput_event_base = ret;
122 
123       ret = xnee_init_xinput_devices(xd);
124       if (ret != XNEE_OK )
125 	{
126 	  fprintf(stderr, "Failed finding X Input extension devices\n");
127 	  xd->xi_data.xinput_event_base = -1;
128 	}
129     }
130 #endif /* XNEE_XINPUT_SUPPORT */
131 
132 
133   /* return XNEE_OK on success, 1  indicats error opening the displays */
134   if ( ( xd->data != NULL ) && (xd->control != NULL) && (xd->fake != NULL) )
135     {
136       xnee_verbose((xd, "-- xnee_setup_display - return OK\n"));
137       return XNEE_OK;
138     }
139   else
140     {
141       xnee_verbose((xd, "-- xnee_setup_display - return 1 ... which is bad\n"));
142       return 1;
143     }
144 
145 
146 
147 
148 }
149 
150 
151 
152 
153 
154 
155 /**************************************************************
156  *                                                            *
157  * xnee_set_default_display                                   *
158  *                                                            *
159  *                                                            *
160  **************************************************************/
161 void
xnee_set_default_display(xnee_data * xd)162 xnee_set_default_display (xnee_data *xd)
163 {
164   char *tmp;
165   tmp = getenv ((const char*)"DISPLAY");
166   if ( tmp != NULL )
167     {
168       xd->display = strdup(tmp);
169     }
170   else
171     {
172       xd->display = NULL;
173     }
174   return ;
175 }
176 
177 
178 
179 /**************************************************************
180  *                                                            *
181  * xnee_open_display                                          *
182  *                                                            *
183  *                                                            *
184  **************************************************************/
185 Display *
xnee_open_display(xnee_data * xd)186 xnee_open_display(xnee_data* xd)
187 {
188   Display *dpy ;
189 
190 /*@null@*/
191   const char *tmp;
192 
193   tmp = (const char*) ((xd->display!=NULL)?
194 		       (xd->display):
195 		       NULL_STRING);
196 
197   if ( (tmp!=NULL) && (strlen(tmp)==0) )
198     {
199       tmp=NULL;
200     }
201 
202   xnee_verbose((xd,  "Open display %s \n",
203 		tmp?tmp:"" ));
204 
205   dpy = XOpenDisplay (tmp);
206   xnee_verbose((xd,  "Open display %s \n",
207 		tmp?tmp:"" ));
208 
209   if (!dpy)
210     {
211       (void) xnee_print_error ("%s: unable to open display \"%s\"\n",
212 			       PACKAGE,
213 			       XDisplayName(tmp));
214       return dpy;
215     }
216 
217   xnee_verbose((xd, "Display %s = %p\n",
218 		tmp?tmp:"", (void*) dpy));
219   return dpy;
220 }
221 
222 
223 
224 
225 
226 /**************************************************************
227  *                                                            *
228  * xnee_add_display_list                                      *
229  *                                                            *
230  *                                                            *
231  **************************************************************/
232 int
xnee_add_display_list(xnee_data * xd,char * disp)233 xnee_add_display_list ( xnee_data* xd, char * disp)
234 {
235   char buf[256];
236   size_t next;
237   int ret=0;
238   int disp_len;
239 
240 
241   if (disp==NULL)
242     {
243       return XNEE_WRONG_PARAMS;
244     }
245 
246   disp_len = strlen(disp);
247 
248 
249   xnee_verbose((xd, "xnee_add_display (xd, %s, )\n", disp));
250 
251   while ( (1!=0) ) {
252 
253     next=strcspn (disp, ",");
254     if (next==0) break;
255     strncpy(buf,disp,next);
256     buf[next]='\0';
257     disp+=next+1;
258     disp_len=disp_len - next - 1;
259     ret=xnee_add_display_str (buf,xd);
260     xnee_verbose((xd,  " ------------------------- are we doing fine??? ret=%d\n", ret));
261 
262     if (ret!=0)
263       {
264 	xnee_verbose((xd, "Could not add all display for distribution ... returning\n"));
265 	return (ret);
266       }
267 
268     if (disp_len <= 0)
269       {
270 	xnee_verbose((xd, "disp_len = %d\n", disp_len));
271 	break;
272       }
273 
274   }
275   xnee_verbose((xd, "xnee_add_display_str ... finished\n"));
276   return XNEE_OK;
277 }
278 
279 
280 
281 
282 
283 /**************************************************************
284  *                                                            *
285  * xnee_add_display_str                                       *
286  *                                                            *
287  *                                                            *
288  **************************************************************/
289 int
xnee_add_display_str(char * disp_str,xnee_data * xd)290 xnee_add_display_str (char * disp_str, xnee_data* xd)
291 {
292   Display *dpy;
293   int xtest_event_basep = 0;
294   int xtest_error_basep = 0;
295   int xtest_version_major = 0;
296   int xtest_version_minor = 0;
297   xnee_distr *xdist;
298 
299   xnee_verbose((xd, "Adding Display \"%s\" to distribution list\n", disp_str));
300 
301   xdist = xd->distr_list;
302   if (xd->distr_list_size==0)
303     {
304       xdist = NULL;
305     }
306 
307   xnee_distr *tmp = xd->distr_list;
308   xd->distr_list = (xnee_distr *) realloc (xd->distr_list,
309 					   (xd->distr_list_size+1)*sizeof (xnee_distr));
310 
311   if (xd->distr_list==NULL)
312     {
313       /*@ignore@*/
314       xd->distr_list = tmp;
315       /*@end@*/
316       tmp = NULL;
317       return XNEE_MEMORY_FAULT;
318     }
319 
320 
321   xnee_verbose((xd, "Adding Display  - opening display\n"));
322   dpy = XOpenDisplay (disp_str);
323   if (dpy==NULL)
324     {
325       xnee_print_error ("Could not open display %s\n", disp_str);
326       return ( XNEE_NOT_OPEN_DISPLAY );
327     }
328   xnee_verbose((xd, "Adding Display  - opening display gave us %p\n", (void*) dpy));
329 
330   xnee_verbose((xd, "Adding Display  - trying to grab control\n"));
331   /*@ignore@*/
332   XTestGrabControl (dpy, True);
333   /*@end@*/
334 
335   if (!dpy)
336     {
337       (void) xnee_print_error ("Unable to open display \"%s\"\n",
338 			       disp_str);
339       return (XNEE_NOT_OPEN_DISPLAY);
340     }
341   xnee_verbose((xd, "Adding Display  - does the display/host have XTest\n"));
342   if( XTestQueryExtension(dpy,
343 			  &xtest_event_basep,
344 			  &xtest_error_basep,
345 			  &xtest_version_major,
346 			  &xtest_version_minor) == 0)
347     {
348       xnee_print_error ("XTest extension missing on display %s \n", disp_str);
349       return (XNEE_NO_TEST_EXT);
350     }
351   xnee_verbose ((xd, "  XTest  Release on \"%s\"         %d.%d\n",
352 		disp_str,
353 		xtest_version_major,
354 		xtest_version_minor));
355 
356   xnee_verbose ((xd, " -- resolution to 0\n"));
357 
358   if  ( (xd!=NULL) &&
359 	(xd->distr_list != NULL ) )
360     {
361       xd->distr_list[xd->distr_list_size].is_used=0;
362 
363       xd->distr_list[xd->distr_list_size].res.x_res=DisplayWidth  (dpy, 0);
364       xd->distr_list[xd->distr_list_size].res.y_res=DisplayHeight (dpy, 0);
365       xd->distr_list[xd->distr_list_size].dpy=dpy;
366 
367 
368       xnee_verbose ((xd, "cheking if resolution differs\n"));
369       if (xnee_res_cmp(&xd->distr_list[xd->distr_list_size].res,
370 		       &xd->res_info.record)==0)
371 	{
372 	  xnee_verbose ((xd, " -- resolution differs\n"));
373 	  xd->distr_list[xd->distr_list_size].is_used=1;
374 	}
375       xd->distr_list_size++;
376     }
377   else
378     {
379       return (XNEE_MEMORY_FAULT);
380     }
381 
382   return (XNEE_OK);
383 }
384 
385 
386 
387 
388 /**************************************************************
389  *                                                            *
390  * xnee_add_display                                           *
391  *                                                            *
392  *                                                            *
393  **************************************************************/
394 int
xnee_add_display(Display * dpy,xnee_data * xd)395 xnee_add_display (Display *dpy, xnee_data* xd)
396 {
397   int xtest_event_basep   = 0;
398   int xtest_error_basep   = 0;
399   int xtest_version_major = 0;
400   int xtest_version_minor = 0;
401 
402   xnee_verbose((xd, "Adding Display \"%p\" to distribution list\n", (void*) dpy));
403   if (xd->distr_list_size==0)
404     {
405       xd->distr_list = (xnee_distr *) calloc (1,sizeof (Display));
406     }
407   else
408     {
409       xnee_distr *tmp = xd->distr_list;
410       xd->distr_list = (xnee_distr *) realloc (xd->distr_list,
411 					       xd->distr_list_size);
412       if (xd->distr_list==NULL)
413 	{
414 	  /*@ignore@*/
415 	  xd->distr_list = tmp;
416 	  /*@end@*/
417 	  tmp = NULL;
418 	  return XNEE_MEMORY_FAULT;
419 	}
420     }
421   /*@ignore@*/
422   XTestGrabControl (dpy, True);
423   /*@end@*/
424 
425   if( XTestQueryExtension(dpy,
426 			  &xtest_event_basep,
427 			  &xtest_error_basep,
428 			  &xtest_version_major,
429 			  &xtest_version_minor) == 0)
430     {
431        xnee_print_error ("XTest extension missing on display %p \n", (void*)dpy);
432        return (XNEE_NO_TEST_EXT);
433     }
434   xnee_verbose ((xd, "  XTest  Release on \"%p\"         %d.%d\n",
435 		 (void*)dpy,
436 		 xtest_version_major,
437 		 xtest_version_minor));
438 
439   if ( (xd != NULL) && (xd->distr_list != NULL) )
440     {
441       xd->distr_list[xd->distr_list_size].dpy=dpy;
442       xd->distr_list_size++;
443     }
444   else
445     {
446       return (XNEE_MEMORY_FAULT);
447     }
448   return (XNEE_OK);
449 }
450 
451