1 /*
2 * XDU - X Window System Interface.
3 *
4 * We hide all of the X hieroglyphics inside of this module.
5 *
6 * Phillip C. Dykstra
7 * <phil@arl.mil>
8 * 4 Sep 1991.
9 *
10 * Copyright (c) Phillip C. Dykstra 1991, 1993, 1994
11 * The X Consortium, and any party obtaining a copy of these files from
12 * the X Consortium, directly or indirectly, is granted, free of charge, a
13 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
14 * nonexclusive right and license to deal in this software and
15 * documentation files (the "Software"), including without limitation the
16 * rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons who receive
18 * copies from any such party to do so. This license includes without
19 * limitation a license to do the foregoing actions under any patents of
20 * the party supplying this software to the X Consortium.
21 */
22 #include <X11/Intrinsic.h>
23 #include <X11/StringDefs.h>
24 #include <X11/Shell.h>
25
26 #include <X11/Xaw/AsciiText.h>
27 #include <X11/Xaw/AsciiSrc.h>
28 #include <X11/Xaw/Form.h>
29 #include <X11/Xaw/Label.h>
30
31 #include <stdio.h>
32
33 #ifndef X_NOT_STDC_ENV
34 #include <stdlib.h> /* for exit() */
35 #endif
36
37 /* IMPORTS: routines that this module vectors out to */
38 extern int press();
39 extern int reset();
40 extern int repaint();
41 extern int reorder();
42 extern int setorder();
43 extern int nodeinfo();
44 extern int helpinfo();
45 extern int ncols;
46
47 /* EXPORTS: routines that this module exports outside */
48 extern int xsetup();
49 extern int xmainloop();
50 extern int xclear();
51 extern int xrepaint();
52 extern int xrepaint_noclear();
53 extern int xdrawrect();
54
55 /* internal routines */
56 static void help_popup();
57 static void help_popdown();
58
59 static String fallback_resources[] = {
60 "*window.width: 600",
61 "*window.height: 480",
62 "*help.width: 500",
63 "*help.height: 330",
64 "*order: first",
65 NULL
66 };
67
68 /* Application Resources */
69 typedef struct {
70 Pixel foreground;
71 Pixel background;
72 XFontStruct *font;
73 int ncol;
74 Boolean showsize;
75 char *order;
76 } res_data, *res_data_ptr;
77 static res_data res;
78
79 static XtResource application_resources[] = {
80 { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
81 XtOffset(res_data_ptr,foreground), XtRString, XtDefaultForeground},
82 { XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
83 XtOffset(res_data_ptr,background), XtRString, XtDefaultBackground},
84 { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
85 XtOffset(res_data_ptr,font), XtRString, XtDefaultFont },
86 { "ncol", "Ncol", XtRInt, sizeof(int),
87 XtOffset(res_data_ptr,ncol), XtRString, "5"},
88 { "showsize", "ShowSize", XtRBoolean, sizeof(Boolean),
89 XtOffset(res_data_ptr,showsize), XtRString, "True"},
90 { "order", "Order", XtRString, sizeof(String),
91 XtOffset(res_data_ptr,order), XtRString, "first"}
92 };
93
94 /* Command Line Options */
95 static XrmOptionDescRec options[] = {
96 {"-c", "*ncol", XrmoptionSepArg, NULL},
97 {"+s", "*showsize", XrmoptionNoArg, "True"},
98 {"-s", "*showsize", XrmoptionNoArg, "False"},
99 {"-n", "*order", XrmoptionNoArg, "size"},
100 {"-rn", "*order", XrmoptionNoArg, "rsize"},
101 {"-a", "*order", XrmoptionNoArg, "alpha"},
102 {"-ra", "*order", XrmoptionNoArg, "ralpha"}
103 };
104
105 /* action routines */
106 static void a_goto();
107 static void a_reset();
108 static void a_quit();
109 static void a_reorder();
110 static void a_size();
111 static void a_ncol();
112 static void a_info();
113 static void a_help();
114 static void a_removehelp();
115
116 static XtActionsRec actionsTable[] = {
117 { "reset", a_reset },
118 { "goto", a_goto },
119 { "quit", a_quit },
120 { "reorder", a_reorder },
121 { "size", a_size },
122 { "ncol", a_ncol },
123 { "info", a_info },
124 { "help", a_help },
125 { "RemoveHelp", a_removehelp }
126 };
127
128 static char defaultTranslations[] = "\
129 <Key>Q: quit()\n\
130 <Key>Escape: quit()\n\
131 :<Key>/: reset()\n\
132 <Key>S: size()\n\
133 <Key>I: info()\n\
134 <Key>H: help()\n\
135 <Key>Help: help()\n\
136 :<Key>?: help()\n\
137 <Key>A: reorder(alpha)\n\
138 <Key>N: reorder(size)\n\
139 <Key>F: reorder(first)\n\
140 <Key>L: reorder(last)\n\
141 <Key>R: reorder(reverse)\n\
142 <Key>1: ncol(1)\n\
143 <Key>2: ncol(2)\n\
144 <Key>3: ncol(3)\n\
145 <Key>4: ncol(4)\n\
146 <Key>5: ncol(5)\n\
147 <Key>6: ncol(6)\n\
148 <Key>7: ncol(7)\n\
149 <Key>8: ncol(8)\n\
150 <Key>9: ncol(9)\n\
151 <Key>0: ncol(10)\n\
152 <Btn1Down>: goto()\n\
153 <Btn2Down>: reset()\n\
154 <Btn3Down>: quit()\n\
155 ";
156
157 /* action routines */
158
a_quit(w,event,params,num_params)159 static void a_quit(w, event, params, num_params)
160 Widget w;
161 XEvent *event;
162 String *params;
163 Cardinal *num_params;
164 {
165 XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
166 exit(0);
167 }
168
a_goto(w,event,params,num_params)169 static void a_goto(w, event, params, num_params)
170 Widget w;
171 XEvent *event;
172 String *params;
173 Cardinal *num_params;
174 {
175 press(event->xbutton.x, event->xbutton.y);
176 }
177
a_reset(w,event,params,num_params)178 static void a_reset(w, event, params, num_params)
179 Widget w;
180 XEvent *event;
181 String *params;
182 Cardinal *num_params;
183 {
184 reset();
185 }
186
a_reorder(w,event,params,num_params)187 static void a_reorder(w, event, params, num_params)
188 Widget w;
189 XEvent *event;
190 String *params;
191 Cardinal *num_params;
192 {
193 if (*num_params != 1) {
194 fprintf(stderr, "xdu: bad number of params to reorder action\n");
195 } else {
196 reorder(*params);
197 }
198 }
199
a_size(w,event,params,num_params)200 static void a_size(w, event, params, num_params)
201 Widget w;
202 XEvent *event;
203 String *params;
204 Cardinal *num_params;
205 {
206 if (res.showsize)
207 res.showsize = 0;
208 else
209 res.showsize = 1;
210 xrepaint();
211 }
212
a_ncol(w,event,params,num_params)213 static void a_ncol(w, event, params, num_params)
214 Widget w;
215 XEvent *event;
216 String *params;
217 Cardinal *num_params;
218 {
219 int n;
220
221 if (*num_params != 1) {
222 fprintf(stderr, "xdu: bad number of params to ncol action\n");
223 return;
224 }
225 n = atoi(*params);
226 if (n < 1 || n > 1000) {
227 fprintf(stderr, "xdu: bad value to ncol action\n");
228 return;
229 }
230 ncols = res.ncol = n;
231 xrepaint();
232 }
233
a_info(w,event,params,num_params)234 static void a_info(w, event, params, num_params)
235 Widget w;
236 XEvent *event;
237 String *params;
238 Cardinal *num_params;
239 {
240 nodeinfo();
241 }
242
a_help(w,event,params,num_params)243 static void a_help(w, event, params, num_params)
244 Widget w;
245 XEvent *event;
246 String *params;
247 Cardinal *num_params;
248 {
249 /*helpinfo();*/
250 help_popup();
251 }
252
a_removehelp(w,event,params,num_params)253 static void a_removehelp(w, event, params, num_params)
254 Widget w;
255 XEvent *event;
256 String *params;
257 Cardinal *num_params;
258 {
259 help_popdown();
260 }
261
262 /* callback routines */
263
c_resize(w,data,event,continue_to_dispatch)264 static void c_resize(w, data, event, continue_to_dispatch)
265 Widget w;
266 XtPointer data;
267 XEvent *event;
268 Boolean *continue_to_dispatch;
269 {
270 /*printf("Resize\n");*/
271 xrepaint();
272 }
273
c_repaint(w,data,event,continue_to_dispatch)274 static void c_repaint(w, data, event, continue_to_dispatch)
275 Widget w;
276 XtPointer data;
277 XEvent *event;
278 Boolean *continue_to_dispatch;
279 {
280 /*printf("Expose\n");*/
281 xrepaint_noclear();
282 }
283
284 /* X Window related variables */
285 static Cursor WorkingCursor;
286 static Display *dpy;
287 static int screen;
288 static Visual *vis;
289 static Window win;
290 static GC gc;
291 static GC cleargc;
292 static XtAppContext app_con;
293
294 Widget toplevel;
295
296 /* External Functions */
297
298 int
xsetup(argcp,argv)299 xsetup(argcp, argv)
300 int *argcp;
301 char **argv;
302 {
303 XtTranslations trans_table;
304 Widget w;
305 XGCValues gcv;
306 int n;
307 Arg args[5];
308
309 /* Create the top level Widget */
310 n = 0;
311 XtSetArg(args[n], XtNtitle, "XDU Disk Usage Display ('h' for help)\n"); n++;
312 toplevel = XtAppInitialize(&app_con, "XDu",
313 options, XtNumber(options),
314 argcp, argv,
315 fallback_resources, args, n);
316
317 XtGetApplicationResources(toplevel, (XtPointer)&res,
318 application_resources, XtNumber(application_resources),
319 NULL, 0 );
320
321 XtAppAddActions(app_con, actionsTable, XtNumber(actionsTable));
322 trans_table = XtParseTranslationTable(defaultTranslations);
323
324 /* Create a simple Label class widget to draw in */
325 n = 0;
326 XtSetArg(args[n], XtNlabel, ""); n++;
327 w = XtCreateManagedWidget("window", labelWidgetClass, toplevel,
328 args, n);
329
330 /* events */
331 XtAddEventHandler(w, ExposureMask, False, c_repaint, NULL);
332 XtAddEventHandler(w, StructureNotifyMask, False, c_resize, NULL);
333 XtAugmentTranslations(w, trans_table);
334
335 XtRealizeWidget(toplevel);
336
337 /* We need these for the raw Xlib calls */
338 win = XtWindow(w);
339 dpy = XtDisplay(w);
340 screen = DefaultScreen(dpy);
341 vis = DefaultVisual(dpy,screen);
342
343 gcv.foreground = res.foreground;
344 gcv.background = res.background;
345 gcv.font = res.font->fid;
346 gc = XCreateGC(dpy, win, (GCFont|GCForeground|GCBackground), &gcv);
347
348 setorder(res.order);
349 ncols = res.ncol;
350 }
351
xmainloop()352 xmainloop()
353 {
354 XtAppMainLoop(app_con);
355 return(0);
356 }
357
xclear()358 xclear()
359 {
360 XClearWindow(dpy, win);
361 }
362
xrepaint()363 xrepaint()
364 {
365 XWindowAttributes xwa;
366
367 XClearWindow(dpy, win);
368 XGetWindowAttributes(dpy, win, &xwa);
369 repaint(xwa.width, xwa.height);
370 }
371
xrepaint_noclear()372 xrepaint_noclear()
373 {
374 XWindowAttributes xwa;
375
376 XGetWindowAttributes(dpy, win, &xwa);
377 repaint(xwa.width, xwa.height);
378 }
379
xdrawrect(name,size,x,y,width,height)380 xdrawrect(name, size, x, y, width, height)
381 char *name;
382 int size;
383 int x, y, width, height;
384 {
385 int textx, texty;
386 char label[1024];
387 XCharStruct overall;
388 int ascent, descent, direction;
389 int cheight;
390
391 /*printf("draw(%d,%d,%d,%d)\n", x, y, width, height );*/
392 XDrawRectangle(dpy, win, gc, x, y, width, height);
393
394 if (res.showsize) {
395 sprintf(label,"%s (%d)", name, size);
396 name = label;
397 }
398
399 XTextExtents(res.font, name, strlen(name), &direction,
400 &ascent, &descent, &overall);
401 cheight = overall.ascent + overall.descent;
402 if (height < (cheight + 2))
403 return 0;
404
405 /* print label */
406 textx = x + 4;
407 texty = y + height/2.0 + (overall.ascent - overall.descent)/2.0 + 1.5;
408 XDrawString(dpy, win, gc, textx, texty, name, strlen(name));
409
410 return 0;
411 }
412
413 static Widget popup;
414
415 static void
help_popup()416 help_popup()
417 {
418 Widget form, text, src;
419 Arg args[15];
420 int n;
421 Atom wm_delete_window;
422 XtTranslations trans_table;
423
424 if (popup != NULL) {
425 XtPopup(popup, XtGrabNone);
426 return;
427 }
428
429 /* popup shell */
430 n = 0;
431 XtSetArg(args[n], XtNtitle, "XDU Help"); n++;
432 popup = XtCreatePopupShell("helpPopup", transientShellWidgetClass,
433 toplevel, args, n);
434
435 /* form container */
436 n = 0;
437 XtSetArg(args[n], XtNborderWidth, 0); n++;
438 XtSetArg(args[n], XtNdefaultDistance, 0); n++;
439 form = XtCreateManagedWidget("form", formWidgetClass,
440 popup, args, n);
441
442 /* text widget in form */
443 n = 0;
444 XtSetArg(args[n], XtNborderWidth, 0); n++;
445 XtSetArg(args[n], XtNresize, XawtextResizeBoth); n++;
446 /* fallback resources weren't working here on the Sun */
447 XtSetArg(args[n], XtNwidth, 500); n++;
448 XtSetArg(args[n], XtNheight, 330); n++;
449 text = XtCreateManagedWidget("help", asciiTextWidgetClass,
450 form, args, n);
451
452 /* create text source */
453 n = 0;
454 XtSetArg(args[n], XtNtype, XawAsciiString); n++;
455 XtSetArg(args[n], XtNeditType, XawtextRead); n++;
456 XtSetArg(args[n], XtNstring, "\
457 XDU Version 3.0 - Phil Dykstra <phil@arl.mil>\n\
458 \n\
459 Keyboard Commands\n\
460 a sort alphabetically\n\
461 n sort numerically (largest first)\n\
462 f sort first-in-first-out\n\
463 l sort last-in-first-out\n\
464 r reverse sort\n\
465 s toggle size display\n\
466 / goto the root\n\
467 i node info to standard out\n\
468 h this help message\n\
469 q quit (also Escape)\n\
470 0-9 set number of columns (0=10)\n\
471 \n\
472 Mouse Commands\n\
473 Left Goto node (goto parent if leftmost box)\n\
474 Middle Back to root\n\
475 Right Quit\n\
476 "); n++;
477 src = XtCreateWidget("textSource", asciiSrcObjectClass,
478 text, args, n);
479 /* set text source */
480 XawTextSetSource(text, src, 0);
481
482 XtRealizeWidget(popup);
483 XtPopup(popup, XtGrabNone);
484
485 trans_table = XtParseTranslationTable("<Key>Q: RemoveHelp()");
486 XtAugmentTranslations(form, trans_table);
487
488 /* Set up ICCCM delete window */
489 wm_delete_window = XInternAtom(XtDisplay(popup), "WM_DELETE_WINDOW", False);
490 XtOverrideTranslations(popup, XtParseTranslationTable("<Message>WM_PROTOCOLS: RemoveHelp()"));
491 XSetWMProtocols(XtDisplay(popup), XtWindow(popup), &wm_delete_window, 1);
492 }
493
494 static void
help_popdown()495 help_popdown()
496 {
497 XtPopdown(popup);
498 }
499