12 #include <X11/Xutil.h>
13 #include <X11/Xresource.h>
15 #include <X11/extensions/shape.h>
16 #include <X11/cursorfont.h>
19 #define SAFE_BORDER (4)
22 extern char *icon_xpm[];
23 extern void drawgfx(void);
25 long xcur,ycur,xmin,xmax,ymin,ymax;
26 int winx,winy,iniline,minimax=1;
33 unsigned long fgpen,bgpen;
40 XrmOptionDescRec opts[]={
41 {"-bg", ".background", XrmoptionSepArg,NULL}, /* 0! */
42 {"-background", ".background", XrmoptionSepArg,NULL}, /* 1! */
43 {"-bd", ".borderColor", XrmoptionSepArg,NULL}, /* 2! */
44 {"-bordercolor", ".borderColor", XrmoptionSepArg,NULL}, /* 3! */
45 {"-bw", ".borderWidth", XrmoptionSepArg,NULL}, /* 4! */
46 {"-borderwidth", ".borderWidth", XrmoptionSepArg,NULL}, /* 5! */
47 {"-display", ".display", XrmoptionSepArg,NULL}, /* 6! */
48 {"-fg", ".foreground", XrmoptionSepArg,NULL}, /* 7! */
49 {"-foreground", ".foreground", XrmoptionSepArg,NULL}, /* 8! */
50 {"-geometry", ".geometry", XrmoptionSepArg,NULL}, /* 9! */
51 {"-iconic", ".iconStartup", XrmoptionNoArg, "on"}, /* 10! */
52 {"-name", ".name", XrmoptionSepArg,NULL}, /* 11! */
53 {"-rv", ".reverseVideo",XrmoptionNoArg, "on"}, /* 12! */
54 {"-reverse", ".reverseVideo",XrmoptionNoArg, "on"}, /* 13! */
55 {"+rv", ".reverseVideo",XrmoptionNoArg, "on"}, /* 14! */
56 {"+reverse", ".reverseVideo",XrmoptionNoArg, "on"}, /* 15! */
57 {"-title", ".title", XrmoptionSepArg,NULL}, /* 16! */
58 {"-xrm", NULL, XrmoptionResArg,NULL}, /* 17! */
60 #define opts_num (sizeof(opts)/sizeof(*opts))
64 char fn[128]="/usr/lib/X11/app-defaults/",resnam[sizeof(fn)],rescls[sizeof(fn)];
68 void wl_line(long x,long y)
72 if (minimax) { xmin=xmax=x; ymin=ymax=y; }
74 xcur=rint(coefx*(x-xmin))+SAFE_BORDER;
75 ycur=winy-SAFE_BORDER-rint(coefy*(y-ymin));
80 if (x<xmin) xmin=x; if (x>xmax) xmax=x;
81 if (y<ymin) ymin=y; if (y>ymax) ymax=y;
85 XDrawLine(dp,win,gc,xcur,ycur,
86 xcur2=rint(coefx*(x-xmin))+SAFE_BORDER,ycur2=winy-SAFE_BORDER-rint(coefy*(y-ymin)));
87 xcur=xcur2; ycur=ycur2;
92 int stricmp(char *s1,char *s2)
96 while (*s1&&*s2) if ((i=(c1=toupper(*s1++))>(c2=toupper(*s2++))-(c1<c2))) return(i);
100 static char *res_string(int resn,const char *resc)
104 strncpy(&resnam[pnamelen],opts[resn].specifier,sizeof(resnam)-pnamelen);
105 strncpy(&rescls[classlen],resc ,sizeof(rescls)-classlen);
106 if (XrmGetResource(rdb,resnam,rescls,&s,&val)) {
107 if (!(s=malloc(val.size))) iofail();
108 return(strncpy(s,val.addr,val.size));
113 static int res_bool(char *s)
115 static char *yestr[4]={"1","on","yes","true"};
116 #define YESTRL (sizeof(yestr)/sizeof(*yestr))
118 if (s) for (i=0;i<YESTRL;i++)
119 if (!stricmp(s,yestr[i])) { free(s); return(1); }
124 static int res_int(char *s,int def)
128 def=strtol(s,&ers,0);
129 if (ers&&*ers) { fprintf(stderr,"strtol() error @\"%s\"\n",ers); iofail(); }
135 typedef enum { color_def_White,color_def_Black } color_def;
136 static unsigned long get_color(char *desc,color_def def)
138 XColor xcol_scr,xcol_ex;
139 if (!desc) return(def==color_def_White?WhitePixelOfScreen(scr):BlackPixelOfScreen(scr));
140 else if (!XAllocNamedColor(dp,cmap=DefaultColormapOfScreen(scr),desc,&xcol_scr,&xcol_ex))
141 { fprintf(stderr,"XAllocNamedColor(\"%s\")\n",desc); iofail(); }
142 return(xcol_scr.pixel);
148 iniline=1; drawgfx();
150 if (xmax==xmin) xmax++;
151 if (ymax==ymin) ymax++;
152 XUndefineCursor(dp,win);
153 XFreeCursor(dp,curs);
156 if (ev.xany.window==win) switch(ev.type) {
157 case ConfigureNotify:
158 winx=ev.xconfigure.width; winy=ev.xconfigure.height;
161 if (ev.xclient.format==32) if (ev.xclient.data.l[0]==atdel)
167 XClearArea(dp,win,ev.xexpose.x,ev.xexpose.y,ev.xexpose.width,ev.xexpose.height,False);
168 if (ev.xexpose.count) break;
170 coefx=(float)(winx-1-2*SAFE_BORDER)/(xmax-xmin);
171 coefy=(float)(winy-1-2*SAFE_BORDER)/(ymax-ymin);
172 iniline=1; drawgfx();
178 void wl_init(int *argcp,char **argv,const char *class)
184 XSetWindowAttributes wina;
196 if ((pname=rindex(*argv,'/'))) pname++;
198 pnamelen=strlen(pname);
200 strncpy(&fn[APPDEFNL],class,sizeof(fn)-APPDEFNL);
201 rdb=XrmGetFileDatabase(fn);
202 if (!(s=getenv("XUSERFILESEARCHPATH"))) s=getenv("XAPPLRESDIR");
203 if (s) if (!(ts=strlen(strncpy(fn,s,sizeof(fn))))) {
204 if (fn[ts-1]!='/') fn[ts++]='/';
205 strncpy(&fn[ts],class,sizeof(fn)-ts);
206 XrmCombineFileDatabase(fn,&rdb,True);
208 XrmParseCommand(&rdb,opts,opts_num,class,argcp,argv);
209 strncpy(resnam,pname,sizeof(resnam));
210 strncpy(rescls,class,sizeof(rescls));
211 classlen=strlen(class);
212 if ((s=res_string(11,".Name")))
213 pnamelen=strlen(pname=s);
214 if (!(dp=XOpenDisplay(disp=res_string(6,".Display"))))
215 { fprintf(stderr,"Display=\"%s\"\n",XDisplayName(disp)); iofail(); }
216 if (!(s=getenv("HOME"))) s="~";
217 ts=strlen(strncpy(fn,s,sizeof(fn)));
218 strncpy(&fn[ts],"/.Xdefaults-",sizeof(fn)-ts); ts+=12;
219 if (!(s=getenv("XENVIRONMENT"))) {
220 if (gethostname(&fn[ts],sizeof(fn)-ts)) iofail();
223 XrmCombineFileDatabase(s,&rdb,False);
224 if ((s=XScreenResourceString(scr=ScreenOfDisplay(dp,scrnum=DefaultScreen(dp)))))
225 XrmCombineDatabase(XrmGetStringDatabase(s),&rdb,False);
226 if ((s=XResourceManagerString(dp)))
227 XrmCombineDatabase(XrmGetStringDatabase(s),&rdb,False);
230 XrmCombineFileDatabase(fn,&rdb,False);
232 bw=res_int(res_string(4,".BorderWidth"),0);
233 bgpen=get_color(res_string(0,".Background" ),color_def_White);
234 fgpen=get_color(res_string(7,".Foreground" ),color_def_Black);
235 if (res_bool(res_string(12,".ReverseVideo")))
236 { bdpen=bgpen; bgpen=fgpen; fgpen=bdpen; }
237 bdpen=get_color(res_string(2,".BorderColor"),color_def_Black);
238 if (!(sizh=XAllocSizeHints())) iofail();
239 xs=WidthOfScreen(scr)/2; ys=HeightOfScreen(scr)/2;
240 sprintf(fn,"%dx%d+%d+%d",xs,ys,xs/2,ys/2);
241 sizh->flags=(i=XWMGeometry(dp,scrnum,res_string(9,".Geometry"),fn,bw,sizh,
242 &sizh->x,&sizh->y,&winx,&winy,&sizh->win_gravity)
243 &(XValue|YValue)?USPosition:PPosition)|(i&(WidthValue|HeightValue)?USSize:PSize)
244 |PMinSize|PWinGravity;
245 sizh->min_height=sizh->min_width=2*SAFE_BORDER+SIZE_MIN;
246 if (!(win=XCreateSimpleWindow(dp,rootw=RootWindowOfScreen(scr),
247 sizh->x,sizh->y,sizh->width=winx,sizh->height=winy,bw,bdpen,bgpen))) iofail();
248 icon.attr.valuemask=0;
249 if ((i=XpmCreatePixmapFromData(dp,win,icon_xpm,&icon.data,&icon.mask,&icon.attr)))
250 { fprintf(stderr,"XpmCreatePixmapFromData() error #%d\n",i); iofail(); }
251 if (!(icon.siz=XAllocIconSize())) iofail();
252 icon.siz->max_width =icon.siz->min_width =icon.attr.width;
253 icon.siz->max_height=icon.siz->min_height=icon.attr.height;
254 icon.siz->height_inc=icon.siz->width_inc=0;
255 XSetIconSizes(dp,win,icon.siz,1);
257 if (!(icon.win=XCreateSimpleWindow(dp,rootw,0,0,
258 icon.attr.width,icon.attr.height,0,bdpen,bgpen))) iofail();
259 XpmFreeAttributes(&icon.attr);
260 XSetWindowBackgroundPixmap(dp,icon.win,icon.data);
261 XFreePixmap(dp,icon.data);
263 XShapeCombineMask(dp,icon.win,ShapeBounding,0,0,icon.mask,ShapeSet);
264 XFreePixmap(dp,icon.mask);
266 XClearWindow(dp,icon.win);
267 if (!(wmh=XAllocWMHints())) iofail();
268 wmh->flags=StateHint|IconWindowHint;
269 wmh->initial_state=res_bool(res_string(10,".IconStartup"))?IconicState:NormalState;
270 wmh->icon_window=icon.win;
271 if (!(clsh=XAllocClassHint())) iofail();
272 clsh->res_name=pname;
273 clsh->res_class=(char *)class;
274 if (!(s=res_string(16,".Title"))) s=(char *)class;
275 XmbSetWMProperties(dp,win,s,class,argv,*argcp,sizh,wmh,clsh);
276 XFree(sizh); XFree(wmh); XFree(clsh);
277 wina.backing_store=WhenMapped;
278 wina.event_mask=ButtonPressMask|KeyPressMask|StructureNotifyMask|ExposureMask;
279 wina.cursor=curs=XCreateFontCursor(dp,XC_watch);
280 XChangeWindowAttributes(dp,win,CWBackingStore|CWEventMask|CWCursor,&wina);
281 atdel=XInternAtom(dp,"WM_DELETE_WINDOW",False);
282 XSetWMProtocols(dp,win,&atdel,1);
285 gc=DefaultGCOfScreen(scr);