xclock.c revision c2b339b4
1/* $Xorg: xclock.c,v 1.4 2001/02/09 02:05:39 xorgcvs Exp $ */
2/* $XdotOrg: $ */
3
4/*
5 * xclock --  Hacked from Tony Della Fera's much hacked clock program.
6 *
7 * "-strftime" option added by George Belotsky, Open Light Software Inc.
8 */
9
10/*
11Copyright 1989, 1998  The Open Group
12
13Permission to use, copy, modify, distribute, and sell this software and its
14documentation for any purpose is hereby granted without fee, provided that
15the above copyright notice appear in all copies and that both that
16copyright notice and this permission notice appear in supporting
17documentation.
18
19The above copyright notice and this permission notice shall be included in
20all copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29Except as contained in this notice, the name of The Open Group shall not be
30used in advertising or otherwise to promote the sale, use or other dealings
31in this Software without prior written authorization from The Open Group.
32 */
33/* $XFree86: xclock.c,v 1.16 2002/10/21 13:33:08 alanh Exp $ */
34
35
36#ifdef HAVE_CONFIG_H
37# include "config.h"
38#endif
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <X11/Xatom.h>
43#include <X11/Intrinsic.h>
44#include <X11/StringDefs.h>
45#include <X11/Shell.h>
46#include "Clock.h"
47#include <X11/Xaw/Cardinals.h>
48#include "clock.bit"
49#include "clmask.bit"
50
51#ifdef XKB
52#include <X11/extensions/XKBbells.h>
53#endif
54
55#ifndef NO_I18N
56#include <locale.h> /* for setlocale() */
57Boolean no_locale = True; /* if True, use old behavior */
58#endif
59
60#ifdef HAVE_GETPID
61# include <unistd.h>
62#endif
63
64/* Command line options table.  Only resources are entered here...there is a
65   pass over the remaining options after XtParseCommand is let loose. */
66
67static XrmOptionDescRec options[] = {
68{"-chime",	"*clock.chime",		XrmoptionNoArg,		"TRUE"},
69{"-hd",		"*clock.hands",		XrmoptionSepArg,	NULL},
70{"-hands",	"*clock.hands",		XrmoptionSepArg,	NULL},
71{"-hl",		"*clock.highlight",	XrmoptionSepArg,	NULL},
72{"-highlight",	"*clock.highlight",	XrmoptionSepArg,	NULL},
73{"-update",	"*clock.update",	XrmoptionSepArg,	NULL},
74{"-padding",	"*clock.padding",	XrmoptionSepArg,	NULL},
75{"-d",		"*clock.analog",	XrmoptionNoArg,		"FALSE"},
76{"-digital",	"*clock.analog",	XrmoptionNoArg,		"FALSE"},
77{"-analog",	"*clock.analog",	XrmoptionNoArg,		"TRUE"},
78{"-twelve",	"*clock.twentyfour",	XrmoptionNoArg,		"FALSE"},
79{"-twentyfour",	"*clock.twentyfour",	XrmoptionNoArg,		"TRUE"},
80{"-brief",	"*clock.brief",		XrmoptionNoArg,		"TRUE"},
81{"-utime",	"*clock.utime",		XrmoptionNoArg,		"TRUE"},
82{"-strftime",	"*clock.strftime",	XrmoptionSepArg,	NULL},
83#ifdef XRENDER
84{"-face",	"*clock.face",		XrmoptionSepArg,	NULL},
85{"-render",	"*clock.render",	XrmoptionNoArg,		"TRUE"},
86{"-norender",	"*clock.render",	XrmoptionNoArg,		"FALSE"},
87{"-sharp",	"*clock.sharp",		XrmoptionNoArg,		"TRUE"},
88#endif
89};
90
91static void quit ( Widget w, XEvent *event, String *params,
92		   Cardinal *num_params );
93
94static XtActionsRec xclock_actions[] = {
95    { "quit",	quit },
96};
97
98static Atom wm_delete_window;
99
100/*
101 * Report the syntax for calling xclock.
102 */
103static void
104Syntax(char *call)
105{
106	(void) printf ("Usage: %s [-analog] [-bw <pixels>] [-digital] [-brief]\n", call);
107	(void) printf ("       [-utime] [-strftime <fmt-str>]\n");
108	(void) printf ("       [-fg <color>] [-bg <color>] [-hd <color>]\n");
109	(void) printf ("       [-hl <color>] [-bd <color>]\n");
110	(void) printf ("       [-fn <font_name>] [-help] [-padding <pixels>]\n");
111	(void) printf ("       [-rv] [-update <seconds>] [-display displayname]\n");
112#ifdef XRENDER
113	(void) printf ("       [-[no]render] [-face <face name>] [-sharp]\n");
114#endif
115	(void) printf ("       [-geometry geom] [-twelve] [-twentyfour]\n\n");
116	exit(1);
117}
118
119static void
120die(Widget w, XtPointer client_data, XtPointer call_data)
121{
122    XCloseDisplay(XtDisplayOfObject(w));
123    exit(0);
124}
125
126static void
127quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
128{
129    Arg arg;
130
131    if (event->type == ClientMessage &&
132	event->xclient.data.l[0] != wm_delete_window) {
133#ifdef XKB
134	XkbStdBell(XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError);
135#else
136	XBell (XtDisplay(w), 0);
137#endif
138    } else {
139	/* resign from the session */
140	XtSetArg(arg, XtNjoinSession, False);
141	XtSetValues(w, &arg, ONE);
142	die(w, NULL, NULL);
143    }
144}
145
146static void
147save(Widget w, XtPointer client_data, XtPointer call_data)
148{
149    XtCheckpointToken token = (XtCheckpointToken) call_data;
150    /* we have nothing to save */
151    token->save_success = True;
152}
153
154int
155main(int argc, char *argv[])
156{
157    Widget toplevel;
158    Arg arg;
159    Pixmap icon_pixmap = None;
160    XtAppContext app_con;
161
162#ifndef NO_I18N
163    char *locale_name = setlocale(LC_ALL,"");
164    XtSetLanguageProc ( NULL, NULL, NULL );
165
166    if(!locale_name || 0 == strcmp(locale_name,"C")) {
167	no_locale = True;
168    }
169    else {
170	no_locale = False;
171    }
172#endif
173
174    toplevel = XtOpenApplication(&app_con, "XClock",
175				 options, XtNumber(options), &argc, argv, NULL,
176				 sessionShellWidgetClass, NULL, ZERO);
177    if (argc != 1) Syntax(argv[0]);
178    XtAddCallback(toplevel, XtNdieCallback, die, NULL);
179    XtAddCallback(toplevel, XtNsaveCallback, save, NULL);
180    XtAppAddActions (app_con, xclock_actions, XtNumber(xclock_actions));
181
182    /*
183     * This is a hack so that wm_delete_window will do something useful
184     * in this single-window application.
185     */
186    XtOverrideTranslations(toplevel,
187		    XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
188
189    XtSetArg(arg, XtNiconPixmap, &icon_pixmap);
190    XtGetValues(toplevel, &arg, ONE);
191
192    if (icon_pixmap == None) {
193	arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel),
194				       XtScreen(toplevel)->root,
195				       (char *)clock_bits, clock_width, clock_height);
196	XtSetValues (toplevel, &arg, ONE);
197    }
198
199    XtSetArg(arg, XtNiconMask, &icon_pixmap);
200    XtGetValues(toplevel, &arg, ONE);
201    if (icon_pixmap == None) {
202	arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel),
203				       XtScreen(toplevel)->root,
204				       (char *)clock_mask_bits, clock_mask_width,
205				       clock_mask_height);
206	XtSetValues (toplevel, &arg, ONE);
207    }
208
209    XtCreateManagedWidget ("clock", clockWidgetClass, toplevel, NULL, ZERO);
210    XtRealizeWidget (toplevel);
211    wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW",
212				    False);
213    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
214			    &wm_delete_window, 1);
215
216#ifdef HAVE_GETPID
217    {
218	pid_t pid = getpid();
219	XChangeProperty(XtDisplay(toplevel), XtWindow(toplevel),
220			XInternAtom(XtDisplay(toplevel), "_NET_WM_PID", False),
221			XA_CARDINAL, 32, PropModeReplace,
222			(unsigned char *) &pid, 1);
223    }
224#endif
225
226    XtAppMainLoop (app_con);
227    exit(0);
228}
229