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