xclock.c revision 00ea61e8
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 _X_NORETURN
104Syntax(const char *call)
105{
106    fprintf (stderr, "Usage: %s %s", call,
107	    "[-analog] [-bw <pixels>] [-digital] [-brief]\n"
108	    "       [-utime] [-strftime <fmt-str>]\n"
109	    "       [-fg <color>] [-bg <color>] [-hd <color>]\n"
110	    "       [-hl <color>] [-bd <color>]\n"
111	    "       [-fn <font_name>] [-help] [-padding <pixels>]\n"
112	    "       [-rv] [-update <seconds>] [-display displayname]\n"
113#ifdef XRENDER
114	    "       [-[no]render] [-face <face name>] [-sharp]\n"
115#endif
116	    "       [-geometry geom] [-twelve] [-twentyfour]\n\n");
117    exit(1);
118}
119
120static void _X_NORETURN
121die(Widget w, XtPointer client_data, XtPointer call_data)
122{
123    XCloseDisplay(XtDisplayOfObject(w));
124    exit(0);
125}
126
127static void
128quit(Widget w, XEvent *event, String *params, Cardinal *num_params)
129{
130    Arg arg;
131
132    if (event->type == ClientMessage &&
133	(Atom)event->xclient.data.l[0] != wm_delete_window) {
134#ifdef XKB
135	XkbStdBell(XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError);
136#else
137	XBell (XtDisplay(w), 0);
138#endif
139    } else {
140	/* resign from the session */
141	XtSetArg(arg, XtNjoinSession, False);
142	XtSetValues(w, &arg, ONE);
143	die(w, NULL, NULL);
144    }
145}
146
147static void
148save(Widget w, XtPointer client_data, XtPointer call_data)
149{
150    XtCheckpointToken token = (XtCheckpointToken) call_data;
151    /* we have nothing to save */
152    token->save_success = True;
153}
154
155int
156main(int argc, char *argv[])
157{
158    Widget toplevel;
159    Arg arg;
160    Pixmap icon_pixmap = None;
161    XtAppContext app_con;
162
163#ifndef NO_I18N
164    char *locale_name = setlocale(LC_ALL,"");
165    XtSetLanguageProc ( NULL, NULL, NULL );
166
167    if(!locale_name || 0 == strcmp(locale_name,"C")) {
168	no_locale = True;
169    }
170    else {
171	no_locale = False;
172    }
173#endif
174
175    toplevel = XtOpenApplication(&app_con, "XClock",
176				 options, XtNumber(options), &argc, argv, NULL,
177				 sessionShellWidgetClass, NULL, ZERO);
178    if (argc != 1) Syntax(argv[0]);
179    XtAddCallback(toplevel, XtNdieCallback, die, NULL);
180    XtAddCallback(toplevel, XtNsaveCallback, save, NULL);
181    XtAppAddActions (app_con, xclock_actions, XtNumber(xclock_actions));
182
183    /*
184     * This is a hack so that wm_delete_window will do something useful
185     * in this single-window application.
186     */
187    XtOverrideTranslations(toplevel,
188		    XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
189
190    XtSetArg(arg, XtNiconPixmap, &icon_pixmap);
191    XtGetValues(toplevel, &arg, ONE);
192
193    if (icon_pixmap == None) {
194	arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel),
195				       XtScreen(toplevel)->root,
196				       (char *)clock_bits, clock_width, clock_height);
197	XtSetValues (toplevel, &arg, ONE);
198    }
199
200    XtSetArg(arg, XtNiconMask, &icon_pixmap);
201    XtGetValues(toplevel, &arg, ONE);
202    if (icon_pixmap == None) {
203	arg.value = (XtArgVal)XCreateBitmapFromData(XtDisplay(toplevel),
204				       XtScreen(toplevel)->root,
205				       (char *)clock_mask_bits, clock_mask_width,
206				       clock_mask_height);
207	XtSetValues (toplevel, &arg, ONE);
208    }
209
210    XtCreateManagedWidget ("clock", clockWidgetClass, toplevel, NULL, ZERO);
211    XtRealizeWidget (toplevel);
212    wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW",
213				    False);
214    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
215			    &wm_delete_window, 1);
216
217#ifdef HAVE_GETPID
218    {
219	unsigned long pid = (unsigned long)getpid();
220	XChangeProperty(XtDisplay(toplevel), XtWindow(toplevel),
221			XInternAtom(XtDisplay(toplevel), "_NET_WM_PID", False),
222			XA_CARDINAL, 32, PropModeReplace,
223			(unsigned char *) &pid, 1);
224    }
225#endif
226
227    XtAppMainLoop (app_con);
228    exit(0);
229}
230