1 /*
2 **
3 **	X11 Jewel By David Cooper and Jose Guterman 05/92
4 **
5 */
6 
7 #ifdef VMS
8 #include <decw$include/Xlib.h>
9 #include <decw$include/Xutil.h>
10 #include <decw$include/Xos.h>
11 #else
12 #include <X11/Xlib.h>
13 #include <X11/Xutil.h>
14 #include <X11/Xos.h>
15 #endif
16 
17 #ifndef VMS
18 #   include <sys/param.h>
19 #endif
20 #ifndef HZ
21 #	define HZ 60
22 #endif
23 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #ifndef SYSV
27 #include <string.h>
28 #else
29 #include <strings.h>
30 #endif
31 #include <errno.h>
32 
33 #include "general.h"
34 #include "xw.h"
35 
36 /* include bitmaps */
37 
38 #include "bitmaps/icon.xbm"
39 #include "bitmaps/smicon.xbm"
40 
41 /* important stuff */
42 
43 Window iw_window;
44 int iw_width=60;
45 int iw_height=60;
46 
47 Display *xw_display;
48 int     xw_screen;
49 Window  xw_window;
50 GC      xw_gc;
51 int     xw_main;
52 int     xw_screen_width;
53 int     xw_screen_height;
54 int     xw_fg;
55 int     xw_bg;
56 
57 /* local routines */
58 
xw_fatal(s,line,file)59 void xw_fatal(s,line,file)
60 char *s;
61 int line;
62 char *file;
63 	{
64 	fprintf(stderr,"FATAL ERROR:%s\nIn:%s, Line:%d\n",s,file,line);
65 	exit(1);
66 	}
67 
68 
69 /********************************************************/
70 
xw_alloc_color(cname)71 Pixel xw_alloc_color(cname)
72 char *cname;
73 	{
74 	XColor dev_color, act_color;
75 	int res;
76 
77 	/* a little BW addition from rjc@cogsci.edinburgh.ac.uk */
78 	if (DefaultDepth(xw_display, xw_screen)==1)
79 		{
80 		if (!strcmp(cname,"grey"))
81 			return BlackPixel(xw_display, xw_screen);
82 		if (!strcmp(cname,"black"))
83 			return BlackPixel(xw_display, xw_screen);
84 
85 		return WhitePixel(xw_display, xw_screen);
86 		}
87 
88 	res = XAllocNamedColor(xw_display,
89 			DefaultColormap(xw_display, xw_screen),
90 			cname, &dev_color, &act_color);
91 	if (!res)
92 		{
93 		char blah[128];
94 		sprintf(blah,"Unable to allocate color:%s.",cname);
95 		xw_fatal(blah,__LINE__,__FILE__);
96 		}
97 	return (dev_color.pixel);
98 	}
99 
100 
101 /********************************************************/
102 
xw_sync_sleep(ms)103 void xw_sync_sleep(ms)
104 unsigned long ms;
105 	{
106 	struct timeval st, et;
107 	long SyncTime;
108 
109 	/*printf("sync ms:%ld\n",ms);*/
110 
111 	gettimeofday(&st,NULL);
112 	XSync(xw_display, False);
113 	gettimeofday(&et,NULL);
114 	/*printf("et-st.sec:%ld,usec:%ld\n",et.tv_sec-st.tv_sec,
115 		et.tv_usec-st.tv_usec);*/
116 	SyncTime=( ((et.tv_sec-st.tv_sec)*1000) +
117 		((et.tv_usec-st.tv_usec)/1000) );
118 	if ((ms) > ((1000/HZ)+SyncTime))
119 		{
120 		ms_sleep(ms-SyncTime);
121 		}
122 	/* printf("slept (ms-Synctime):%ld (ms):%ld\n", (long)(ms-SyncTime), ms);
123 	gettimeofday(&et,NULL);
124 	printf("#2:et-st.sec:%ld,usec:%ld\n",et.tv_sec-st.tv_sec,
125 		et.tv_usec-st.tv_usec);*/
126 	}
127 
128 
129 BOOL timer_set=FALSE;
130 BOOL timer_reset=FALSE;
131 unsigned long timer_ms;
132 struct timeval timer;
133 struct timeval curtime;
134 
xw_set_timer(time_ms)135 void xw_set_timer(time_ms)
136 unsigned long time_ms;
137 	{
138 	timer_set=FALSE;
139 	timer_reset=TRUE;
140 	timer_ms=time_ms;
141 	if (time_ms <= (1000/HZ)) /* HZ should be in param.h */
142 		{
143 		timer_ms=(1000/HZ);
144 		}
145 	}
146 
147 
148 /********************************************************/
149 
xw_main_loop()150 void xw_main_loop()
151 	{
152 	XEvent xev;
153 #ifndef VMS
154 #   ifdef USE_SELECT
155 	size_t nfds=(XConnectionNumber(xw_display) + 1);
156 	fd_set readfds, writefds, exceptfds;
157 	struct timeval timeout_BSD;
158 
159 	FD_SET(XConnectionNumber(xw_display),&readfds);
160 	FD_SET(XConnectionNumber(xw_display),&exceptfds);
161 #   else
162 	struct pollfd fds[1];
163 
164 	fds[0].fd=XConnectionNumber(xw_display);
165 	fds[0].events=(POLLIN|POLLPRI);
166 #   endif
167 #endif
168 
169 	xw_main = 1;
170 	while (xw_main)
171 		{
172 		int ret, timeout, pending;
173 		if (timer_set)
174 			{
175 			gettimeofday(&curtime,NULL);
176 			timeout=( ((timer.tv_sec - curtime.tv_sec) * 1000) +
177 						((timer.tv_usec - curtime.tv_usec) / 1000) );
178 			if (timeout <= (1000/HZ)) /* HZ should be in param.h */
179 				{
180 				xw_timeout();
181 				continue;
182 				}
183 			}
184 		else
185 			{ timeout=(-1); }
186 		if (timer_reset)
187 			{
188 			gettimeofday(&curtime,NULL);
189 			timer.tv_sec= curtime.tv_sec+(timer_ms/1000);
190 			timer.tv_usec=curtime.tv_usec+((timer_ms%1000)*1000);
191 			if (timer.tv_usec > 1000000)
192 				{
193 				timer.tv_usec -= 1000000;
194 				timer.tv_sec += 1;
195 				}
196 			timer_set=TRUE;
197 			timer_reset=FALSE;
198 			timeout=timer_ms;
199 			}
200 
201 	/* ret = 0 -> timeout						    */
202 	/* ret < 0 -> error						    */
203 	/* ret > 0 -> event						    */
204 #if defined(VMS)
205 	ret=0;
206 	while ( (timeout > 0) && (ret == 0) )
207 		{
208 		gettimeofday(&curtime,NULL);
209 		timeout=( ((timer.tv_sec - curtime.tv_sec) * 1000) +
210 			((timer.tv_usec - curtime.tv_usec) / 1000) );
211 		ret=XPending(xw_display);
212 		}
213 	if (timeout <= (1000/HZ)) /* HZ should be in param.h */
214 		{
215 		ret=0;
216 		}
217 #else
218 #if defined(USE_SELECT)
219 		if (timeout > 0)
220 			{
221 			timeout_BSD.tv_usec=(timeout%1000)*1000;
222 			timeout_BSD.tv_sec=(timeout/1000);
223 			ret = select(nfds,&readfds,NULL,&exceptfds,&timeout_BSD);
224 			}
225 		else
226 			{ ret = select(nfds,&readfds,NULL,&exceptfds,NULL); }
227 		FD_SET(XConnectionNumber(xw_display),&readfds);
228 		FD_SET(XConnectionNumber(xw_display),&exceptfds);
229 #else
230 		while( ( (ret=poll(fds, 1L, timeout)) < 0) &&
231 				((errno==EINTR) || (errno=EAGAIN)) )
232 #endif
233 #endif
234 
235 		if (ret < 0)
236 			{
237 			perror("xw poll");
238 			/*xw_fatal("CANNOT POLL.",__LINE__,__FILE__);*/
239 			}
240 		if (ret==0)
241 			{
242 			timer_set=FALSE;
243 			xw_timeout();
244 			}
245 		pending=XPending(xw_display);
246 /*		printf("PENDING:%d\n",pending);*/
247 		for (;pending > 0;pending--)
248 			{
249 			XNextEvent(xw_display, &xev);
250 			switch (xev.type)
251 				{
252 				case Expose:
253 					xw_expose_event((XExposeEvent *) &xev);
254 					break;
255 				case FocusIn:
256 				case FocusOut:
257 					xw_focus_event((XFocusChangeEvent *) &xev);
258 					break;
259 				case LeaveNotify:
260 					xw_leave_event((XLeaveWindowEvent *) &xev);
261 				case KeyRelease:
262 				case KeyPress:
263 					xw_key_event((XKeyEvent *) &xev);
264 					break;
265 				case ButtonRelease:
266 				case ButtonPress:
267 					xw_but_event((XButtonEvent *) &xev);
268 					break;
269 				case UnmapNotify:
270 				case MapNotify:
271 					xw_map_event((XMapEvent *) &xev);
272 					break;
273 				case ConfigureNotify:
274 					{
275 					XConfigureEvent *xcev=(XConfigureEvent *)&xev;
276 					/*printf("config:w:%d,h:%d\n", xcev->width, xcev->height);*/
277 					if (xcev->window == iw_window)
278 						{
279 						iw_width=xcev->width;
280 						iw_height=xcev->height;
281 						}
282 					}
283 					break;
284 				}
285 			}
286 		}
287 	}
288 
289 
290 /********************************************************/
291 
xw_exit_main()292 void xw_exit_main()
293 	{
294 	xw_main = 0;
295 	}
296 
297 
298 /********************************************************/
299 Pixmap Icon;
300 Pixmap SmIcon;
301 
302 #ifdef DECWM
303 #ifdef VMS
304 #include <decw$include/decwmhints.h>
305 #else
306 #include <X11/DECWmHints.h>
307 #endif
308 
decwm_init()309 BOOL decwm_init()
310 	{
311 	/* setup for dec window manager */
312 	DECWmHintsRec dwmhints;
313 	Atom wmatom;
314 
315 	/* if decwm hints atom exists -> wm is running */
316 	wmatom=XInternAtom(xw_display, "DEC_WM_HINTS", True);
317 
318 	if (wmatom != None)
319 		{
320 		dwmhints.value_mask=DECWmIconifyPixmapMask;
321 		dwmhints.iconify_pixmap=SmIcon;
322 		XChangeProperty(xw_display, xw_window, wmatom, wmatom, 32,
323 			PropModeReplace, &dwmhints, sizeof(dwmhints)/4);
324 		return(TRUE);
325 		}
326 	else
327 		{ return(FALSE); }
328 	}
329 #endif
330 
331 #ifndef MAX
332 #define MAX(a,b) ((a>b)?a:b)
333 #endif
334 
xw_init(argc,argv,w,h)335 void xw_init(argc, argv, w, h )
336 int  argc;
337 char **argv;
338 int  w, h;
339 	{
340 	XIconSize *icon_sizes;
341 	int size_count;
342 	BOOL big_icon=FALSE;
343 	XSizeHints hints;
344 	XWMHints wmhints;
345 	XGCValues gcv;
346 	unsigned long gcvm;
347 	char *Disp=NULL;
348 	char *AppName;
349 	int i;
350 
351 	/* look for display in args */
352 	for (i=1;i<(argc-1);i++)
353 		{
354 		int len;
355 		char *dispstr="-display";
356 		len=MAX(strlen(dispstr),strlen(argv[i]));
357 		if (len<4) { continue; }
358 		if (strncmp(argv[i],dispstr,len)==0)
359 			{
360 			Disp=argv[i+1];
361 			break;
362 			}
363 		}
364 
365 	xw_display = XOpenDisplay(Disp);
366 	if (!xw_display)
367 		{
368 		printf("Unable to connect to display:%s, exiting.\n",Disp);
369 		exit(-1);
370 		}
371 
372 	if (XGetIconSizes(xw_display, RootWindow(xw_display,xw_screen),
373 			&icon_sizes, &size_count))
374 		{
375 		big_icon=FALSE;
376 		for (;size_count>0; size_count--)
377 			{
378 			if (icon_sizes->max_width >= icon_width)
379 			    { big_icon=TRUE; }
380 			/*
381 			printf("minw:%d,minh:%d,maxw:%d,maxh:%d,winc:%d,hinc:%d\n",
382 			    icon_sizes->min_width, icon_sizes->min_height,
383 			    icon_sizes->max_width, icon_sizes->max_height,
384 			    icon_sizes->width_inc, icon_sizes->height_inc);
385 			*/
386 			icon_sizes++;
387 			}
388 		}
389 	else
390 		{ big_icon=TRUE; }
391 
392 	/* look for appname in args */
393 #ifdef VMS
394 	AppName=strrchr(argv[0],']');
395 #else
396 	AppName=strrchr(argv[0],'/');
397 #endif
398 	if (!AppName)
399 		{ AppName=argv[0]; }
400 	else
401 		{ AppName++; /* skip trailing seperator */}
402 	*AppName=toupper(*AppName);
403 
404 	/* lets get to it */
405 	xw_screen_width = w;
406 	xw_screen_height = h;
407 	hints.width = xw_screen_width;
408 	hints.height = xw_screen_height;
409 	hints.flags = PSize;
410 
411 	xw_screen = DefaultScreen(xw_display);
412 	xw_fg = WhitePixel(xw_display,xw_screen);
413 	xw_bg = BlackPixel(xw_display,xw_screen);
414 	gcv.graphics_exposures = False;
415 	gcv.foreground = xw_fg;
416 	gcv.background = xw_bg;
417 /*	gcv.font = XLoadFont(xw_display, "8x13");*/
418 	gcvm = (GCGraphicsExposures | GCForeground | GCBackground /*| GCFont*/);
419 
420 	xw_window = XCreateSimpleWindow(xw_display,
421 			RootWindow(xw_display, xw_screen), 0, 0, hints.width,
422 			hints.height, 2, xw_fg, xw_bg);
423 
424 	XSetStandardProperties(xw_display, xw_window, AppName, AppName,
425 			None, argv, argc, &hints);
426 
427 	Icon=XCreateBitmapFromData(xw_display, xw_window, icon_bits,
428 		icon_width, icon_height);
429 	SmIcon=XCreateBitmapFromData(xw_display, xw_window, smicon_bits,
430 		smicon_width, smicon_height);
431 	if (big_icon)
432 		{ wmhints.icon_pixmap=Icon; }
433 	else
434 		{ wmhints.icon_pixmap=SmIcon; }
435 	wmhints.flags=IconPixmapHint;
436 
437 #ifdef ICON_WINDOW
438 	wmhints.flags|=IconWindowHint;
439 	iw_window=
440 	wmhints.icon_window=XCreateSimpleWindow(xw_display,
441 			RootWindow(xw_display, xw_screen), 0, 0, iw_width,
442 			iw_height, 2, xw_fg, xw_bg);
443 	XSelectInput(xw_display, iw_window, StructureNotifyMask | ExposureMask);
444 #endif
445 
446 	wmhints.flags|=InputHint;
447 	wmhints.input=True;
448 
449 #ifdef DECWM
450 	if (!decwm_init())
451 #endif
452 		{ XSetWMHints(xw_display, xw_window, &wmhints); }
453 
454 	XSelectInput(xw_display, xw_window,
455 			 ExposureMask | KeyPressMask | ButtonPressMask |
456 			 LeaveWindowMask | FocusChangeMask |
457 			 StructureNotifyMask );
458 
459 	xw_gc = XCreateGC(xw_display, xw_window, gcvm, &gcv);
460 
461 	}
462 
463 
464 
xw_start()465 void xw_start()
466 	{
467 	XMapWindow(xw_display, xw_window);
468 	XFlush(xw_display);
469 	}
470 
471