1 /* $Xorg: dsimple.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $ */
2 /*
3
4 Copyright 1993, 1998 The Open Group
5
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
10 documentation.
11
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name of The Open Group shall
24 not be used in advertising or otherwise to promote the sale, use or
25 other dealings in this Software without prior written authorization
26 from The Open Group.
27
28 */
29 /* $XFree86: xc/programs/xlsfonts/dsimple.c,v 3.6 2001/12/14 20:02:09 dawes Exp $ */
30
31 #include <X11/Xos.h>
32 #include <X11/Xlib.h>
33 #include <X11/Xutil.h>
34 #include <X11/cursorfont.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38 /*
39 * Other_stuff.h: Definitions of routines in other_stuff.
40 *
41 * Written by Mark Lillibridge. Last updated 7/1/87
42 */
43
44 #include "dsimple.h"
45
46 /*
47 * Just_display: A group of routines designed to make the writting of simple
48 * X11 applications which open a display but do not open
49 * any windows much faster and easier. Unless a routine says
50 * otherwise, it may be assumed to require program_name, dpy,
51 * and screen already defined on entry.
52 *
53 * Written by Mark Lillibridge. Last updated 7/1/87
54 */
55
56
57 /* This stuff is defined in the calling program by just_display.h */
58 char *program_name = "unknown_program";
59 Display *dpy;
60 int screen;
61
62 /*
63 * Malloc: like malloc but handles out of memory using Fatal_Error.
64 */
Malloc(size_t size)65 char *Malloc(size_t size)
66 {
67 char *data;
68
69 if (!(data = malloc(size)))
70 Fatal_Error("Out of memory!");
71
72 return(data);
73 }
74
75
76 /*
77 * Realloc: like Malloc except for realloc, handles NULL using Malloc.
78 */
Realloc(void * ptr,size_t size)79 char *Realloc(void *ptr,size_t size)
80 {
81 void *new_ptr;
82
83 if (!ptr)
84 return(Malloc(size));
85
86 if (!(new_ptr = realloc(ptr, size)))
87 Fatal_Error("Out of memory!");
88
89 return(new_ptr);
90 }
91
92
93 /*
94 * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
95 * If found, remove it from command line. Don't go past a lone -.
96 */
Get_Display_Name(int * pargc,char ** argv)97 char *Get_Display_Name(int *pargc, char **argv)
98 {
99 int argc = *pargc;
100 char **pargv = argv+1;
101 char *displayname = NULL;
102 int i;
103
104 for (i = 1; i < argc; i++) {
105 char *arg = argv[i];
106
107 if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
108 if (++i >= argc) usage ();
109
110 displayname = argv[i];
111 *pargc -= 2;
112 continue;
113 }
114 if (!strcmp(arg,"-")) {
115 while (i<argc)
116 *pargv++ = argv[i++];
117 break;
118 }
119 *pargv++ = arg;
120 }
121
122 *pargv = NULL;
123 return (displayname);
124 }
125
126
127 /*
128 * Open_Display: Routine to open a display with correct error handling.
129 * Does not require dpy or screen defined on entry.
130 */
Open_Display(display_name)131 Display *Open_Display(display_name)
132 char *display_name;
133 {
134 Display *d;
135
136 d = XOpenDisplay(display_name);
137 if (d == NULL) {
138 fprintf (stderr, "%s: unable to open display '%s'\n",
139 program_name, XDisplayName (display_name));
140 usage ();
141 /* doesn't return */
142 }
143
144 return(d);
145 }
146
147
148 /*
149 * Setup_Display_And_Screen: This routine opens up the correct display (i.e.,
150 * it calls Get_Display_Name) and then stores a
151 * pointer to it in dpy. The default screen
152 * for this display is then stored in screen.
153 * Does not require dpy or screen defined.
154 */
Setup_Display_And_Screen(int * argc,char ** argv)155 void Setup_Display_And_Screen(int *argc, char **argv)
156 {
157 dpy = Open_Display (Get_Display_Name(argc, argv));
158 screen = DefaultScreen(dpy);
159 }
160
161
162 /*
163 * Open_Font: This routine opens a font with error handling.
164 */
Open_Font(name)165 XFontStruct *Open_Font(name)
166 char *name;
167 {
168 XFontStruct *font;
169
170 if (!(font=XLoadQueryFont(dpy, name)))
171 Fatal_Error("Unable to open font %s!", name);
172
173 return(font);
174 }
175
176
177 /*
178 * Beep: Routine to beep the display.
179 */
Beep()180 void Beep()
181 {
182 XBell(dpy, 50);
183 }
184
185 /*
186 * Select_Window_Args: a rountine to provide a common interface for
187 * applications that need to allow the user to select one
188 * window on the screen for special consideration.
189 * This routine implements the following command line
190 * arguments:
191 *
192 * -root Selects the root window.
193 * -id <id> Selects window with id <id>. <id> may
194 * be either in decimal or hex.
195 * -name <name> Selects the window with name <name>.
196 *
197 * Call as Select_Window_Args(&argc, argv) in main before
198 * parsing any of your program's command line arguments.
199 * Select_Window_Args will remove its arguments so that
200 * your program does not have to worry about them.
201 * The window returned is the window selected or 0 if
202 * none of the above arguments was present. If 0 is
203 * returned, Select_Window should probably be called after
204 * all command line arguments, and other setup is done.
205 * For examples of usage, see xwininfo, xwd, or xprop.
206 */
Select_Window_Args(rargc,argv)207 Window Select_Window_Args(rargc, argv)
208 int *rargc;
209 char **argv;
210 #define ARGC (*rargc)
211 {
212 int nargc=1;
213 int argc;
214 char **nargv;
215 Window w=0;
216
217 nargv = argv+1; argc = ARGC;
218 #define OPTION argv[0]
219 #define NXTOPTP ++argv, --argc>0
220 #define NXTOPT if (++argv, --argc==0) usage()
221 #define COPYOPT nargv++[0]=OPTION, nargc++
222
223 while (NXTOPTP) {
224 if (!strcmp(OPTION, "-")) {
225 COPYOPT;
226 while (NXTOPTP)
227 COPYOPT;
228 break;
229 }
230 if (!strcmp(OPTION, "-root")) {
231 w=RootWindow(dpy, screen);
232 continue;
233 }
234 if (!strcmp(OPTION, "-name")) {
235 NXTOPT;
236 w = Window_With_Name(dpy, RootWindow(dpy, screen),
237 OPTION);
238 if (!w)
239 Fatal_Error("No window with name %s exists!",OPTION);
240 continue;
241 }
242 if (!strcmp(OPTION, "-id")) {
243 NXTOPT;
244 w=0;
245 sscanf(OPTION, "0x%lx", &w);
246 if (!w)
247 sscanf(OPTION, "%lu", &w);
248 if (!w)
249 Fatal_Error("Invalid window id format: %s.", OPTION);
250 continue;
251 }
252 COPYOPT;
253 }
254 ARGC = nargc;
255
256 return(w);
257 }
258
259 /*
260 * Other_stuff: A group of routines which do common X11 tasks.
261 *
262 * Written by Mark Lillibridge. Last updated 7/1/87
263 */
264
265 /*
266 * Resolve_Color: This routine takes a color name and returns the pixel #
267 * that when used in the window w will be of color name.
268 * (WARNING: The colormap of w MAY be modified! )
269 * If colors are run out of, only the first n colors will be
270 * as correct as the hardware can make them where n depends
271 * on the display. This routine does not require wind to
272 * be defined.
273 */
Resolve_Color(w,name)274 unsigned long Resolve_Color(w, name)
275 Window w;
276 char *name;
277 {
278 XColor c;
279 Colormap colormap;
280 XWindowAttributes wind_info;
281
282 /*
283 * The following is a hack to insure machines without a rgb table
284 * handle at least white & black right.
285 */
286 if (!strcmp(name, "white"))
287 name="#ffffffffffff";
288 if (!strcmp(name, "black"))
289 name="#000000000000";
290
291 XGetWindowAttributes(dpy, w, &wind_info);
292 colormap = wind_info.colormap;
293
294 if (!XParseColor(dpy, colormap, name, &c))
295 Fatal_Error("Bad color format '%s'.", name);
296
297 if (!XAllocColor(dpy, colormap, &c))
298 Fatal_Error("XAllocColor failed!");
299
300 return(c.pixel);
301 }
302
303
304 /*
305 * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap. The colors come
306 * from the foreground and background colors of the gc.
307 * Width and height are required solely for efficiency.
308 * If needed, they can be obtained via. XGetGeometry.
309 */
Bitmap_To_Pixmap(dpy,d,gc,bitmap,width,height)310 Pixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height)
311 Display *dpy;
312 Drawable d;
313 GC gc;
314 Pixmap bitmap;
315 int width, height;
316 {
317 Pixmap pix;
318 int x;
319 unsigned int i, depth;
320 Drawable root;
321
322 if (!XGetGeometry(dpy, d, &root, &x, &x, &i, &i, &i, &depth))
323 return(0);
324
325 pix = XCreatePixmap(dpy, d, width, height, (int)depth);
326
327 XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1);
328
329 return(pix);
330 }
331
332
333 /*
334 * blip: a debugging routine. Prints Blip! on stderr with flushing.
335 */
blip()336 void blip()
337 {
338 fflush(stdout);
339 fprintf(stderr, "blip!\n");
340 fflush(stderr);
341 }
342
343
344 /*
345 * Routine to let user select a window using the mouse
346 */
347
Select_Window(dpy)348 Window Select_Window(dpy)
349 Display *dpy;
350 {
351 int status;
352 Cursor cursor;
353 XEvent event;
354 Window target_win = None, root = RootWindow(dpy,screen);
355 int buttons = 0;
356
357 /* Make the target cursor */
358 cursor = XCreateFontCursor(dpy, XC_crosshair);
359
360 /* Grab the pointer using target cursor, letting it room all over */
361 status = XGrabPointer(dpy, root, False,
362 ButtonPressMask|ButtonReleaseMask, GrabModeSync,
363 GrabModeAsync, root, cursor, CurrentTime);
364 if (status != GrabSuccess) Fatal_Error("Can't grab the mouse.");
365
366 /* Let the user select a window... */
367 while ((target_win == None) || (buttons != 0)) {
368 /* allow one more event */
369 XAllowEvents(dpy, SyncPointer, CurrentTime);
370 XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
371 switch (event.type) {
372 case ButtonPress:
373 if (target_win == None) {
374 target_win = event.xbutton.subwindow; /* window selected */
375 if (target_win == None) target_win = root;
376 }
377 buttons++;
378 break;
379 case ButtonRelease:
380 if (buttons > 0) /* there may have been some down before we started */
381 buttons--;
382 break;
383 }
384 }
385
386 XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
387
388 return(target_win);
389 }
390
391
392 /*
393 * Window_With_Name: routine to locate a window with a given name on a display.
394 * If no window with the given name is found, 0 is returned.
395 * If more than one window has the given name, the first
396 * one found will be returned. Only top and its subwindows
397 * are looked at. Normally, top should be the RootWindow.
398 */
Window_With_Name(dpy,top,name)399 Window Window_With_Name(dpy, top, name)
400 Display *dpy;
401 Window top;
402 char *name;
403 {
404 Window *children, dummy;
405 unsigned int nchildren;
406 unsigned int i;
407 Window w=0;
408 char *window_name;
409
410 if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
411 return(top);
412
413 if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
414 return(0);
415
416 for (i=0; i<nchildren; i++) {
417 w = Window_With_Name(dpy, children[i], name);
418 if (w)
419 break;
420 }
421 if (children) XFree ((char *)children);
422 return(w);
423 }
424
425 /*
426 * Standard fatal error routine - call like printf but maximum of 7 arguments.
427 * Does not require dpy or screen defined.
428 */
Fatal_Error(char * msg,...)429 void Fatal_Error(char *msg, ...)
430 {
431 va_list args;
432 fflush(stdout);
433 fflush(stderr);
434 fprintf(stderr, "%s: error: ", program_name);
435 va_start(args, msg);
436 vfprintf(stderr, msg, args);
437 va_end(args);
438 fprintf(stderr, "\n");
439 exit(2);
440 }
441