oclock.c revision e32e2dab
1/*
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <X11/Intrinsic.h>
32#include <X11/Xatom.h>
33#include <X11/StringDefs.h>
34#include <X11/Shell.h>
35#include <X11/Xmu/Editres.h>
36#include "Clock.h"
37#include <stdio.h>
38#include <stdlib.h>
39
40#ifdef XKB
41#include <X11/extensions/XKBbells.h>
42#endif
43
44#include "oclock.bit"
45#include "oclmask.bit"
46
47static void die ( Widget w, XtPointer client_data, XtPointer call_data );
48static void save ( Widget w, XtPointer client_data, XtPointer call_data );
49static void usage ( int exitval );
50static void quit ( Widget w, XEvent *event, String *params,
51		   Cardinal *num_params );
52
53
54static XtActionsRec actions[] = {
55    {"quit",	quit}
56};
57
58static Atom wm_delete_window;
59
60static void die(Widget w, XtPointer client_data, XtPointer call_data)
61{
62    XCloseDisplay(XtDisplay(w));
63    exit(0);
64}
65
66static void save(Widget w, XtPointer client_data, XtPointer call_data)
67{
68    return;	/* stateless */
69}
70
71/* Exit with message describing command line format */
72
73static void usage(int exitval)
74{
75    fprintf(stderr,
76"usage: oclock\n"
77"       [-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n"
78"       [-display [{host}]:[{vs}]]\n"
79"       [-fg {color}] [-bg {color}] [-bd {color}] [-bw {pixels}]\n"
80"       [-minute {color}] [-hour {color}] [-jewel {color}]\n"
81"       [-backing {backing-store}] [-shape] [-noshape] [-transparent]\n"
82"       [-help] [-version]\n"
83        );
84    exit(exitval);
85}
86
87/* Command line options table.  Only resources are entered here...there is a
88   pass over the remaining options after XtParseCommand is let loose. */
89
90static XrmOptionDescRec options[] = {
91{"-fg",		"*Foreground",		XrmoptionSepArg,	NULL},
92{"-bg",		"*Background",		XrmoptionSepArg,	NULL},
93{"-foreground",	"*Foreground",		XrmoptionSepArg,	NULL},
94{"-background",	"*Background",		XrmoptionSepArg,	NULL},
95{"-minute",	"*clock.minute",	XrmoptionSepArg,	NULL},
96{"-hour",	"*clock.hour",		XrmoptionSepArg,	NULL},
97{"-jewel",	"*clock.jewel",		XrmoptionSepArg,	NULL},
98{"-backing",	"*clock.backingStore",	XrmoptionSepArg,	NULL},
99{"-shape",	"*clock.shapeWindow",	XrmoptionNoArg,		"TRUE"},
100{"-noshape",	"*clock.shapeWindow",	XrmoptionNoArg,		"FALSE"},
101{"-transparent","*clock.transparent",	XrmoptionNoArg,		"TRUE"},
102};
103
104int
105main(int argc, char *argv[])
106{
107    XtAppContext xtcontext;
108    Widget toplevel;
109    Arg arg[2];
110    int	i;
111
112    /* Handle args that don't require opening a display */
113    for (int n = 1; n < argc; n++) {
114	const char *argn = argv[n];
115	/* accept single or double dash for -help & -version */
116	if (argn[0] == '-' && argn[1] == '-') {
117	    argn++;
118	}
119	if (strcmp(argn, "-help") == 0) {
120	    usage(0);
121	}
122	if (strcmp(argn, "-version") == 0) {
123	    puts(PACKAGE_STRING);
124	    exit(0);
125	}
126    }
127
128    toplevel = XtOpenApplication(&xtcontext, "Clock",
129				 options, XtNumber(options), &argc, argv, NULL,
130				 sessionShellWidgetClass, NULL, 0);
131    if (argc != 1) {
132	fputs("Unknown argument(s):", stderr);
133	for (int n = 1; n < argc; n++) {
134	    fprintf(stderr, " %s", argv[n]);
135	}
136	fputs("\n\n", stderr);
137	usage(1);
138    }
139    XtAddCallback(toplevel, XtNsaveCallback, save, NULL);
140    XtAddCallback(toplevel, XtNdieCallback, die, NULL);
141
142    XtAppAddActions
143	(xtcontext, actions, XtNumber(actions));
144    XtOverrideTranslations
145	(toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
146
147    i = 0;
148    XtSetArg (arg[i], XtNiconPixmap,
149	      XCreateBitmapFromData (XtDisplay(toplevel),
150				     XtScreen(toplevel)->root,
151				     (const char *)oclock_bits,
152				     oclock_width, oclock_height));
153    i++;
154    XtSetArg (arg[i], XtNiconMask,
155	      XCreateBitmapFromData (XtDisplay(toplevel),
156				     XtScreen(toplevel)->root,
157				     (const char *)oclmask_bits,
158				     oclmask_width, oclmask_height));
159    i++;
160    XtSetValues (toplevel, arg, i);
161
162    (void) XtCreateManagedWidget("clock", clockWidgetClass, toplevel, NULL, 0);
163    XtRealizeWidget (toplevel);
164
165    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
166				   False);
167    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
168                            &wm_delete_window, 1);
169
170    XtAddEventHandler(toplevel, (EventMask) 0, TRUE,
171		      _XEditResCheckMessages, NULL);
172
173    XtAppMainLoop(xtcontext);
174    exit(0);
175}
176
177static void quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
178{
179    Arg arg;
180
181    if (event->type == ClientMessage &&
182	(Atom)event->xclient.data.l[0] != wm_delete_window) {
183#ifdef XKB
184	XkbStdBell(XtDisplay(w), XtWindow(w), 0, XkbBI_BadValue);
185#else
186	XBell(XtDisplay(w), 0);
187#endif
188    } else {
189	XtSetArg(arg, XtNjoinSession, False);
190	XtSetValues(w, &arg, (Cardinal)1);
191	die(w, NULL, NULL);
192    }
193}
194