1 /*
2 * Copyright (c) 1998 Guylhem Aznar <guylhem@oeil.qc.ca>
3 * Copyright (c) 1991 David A. Curry <davy@itstd.sri.com>
4 * Copyright (c) 1996 Michael J. Hammel <mjhammel@csn.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * xpostit.c - Post-It Notes for the X Window System.
21 *
22 * You can get David A. Curry's original public domain version on :
23 * ftp://ftp.ers.ibm.com/pub/davy/xpostit3.3.2.tar.gz
24 *
25 */
26
27 #include <X11/StringDefs.h>
28 #include <X11/Intrinsic.h>
29 #include <X11/Shell.h>
30 #include <X11/Xatom.h>
31 #include <X11/Xos.h>
32 #include <X11/Xaw/SimpleMenu.h>
33 #include <signal.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36
37 #include "xpostit.h"
38 #include "version.h"
39
40 /*
41 * Command line options and the resources they set.
42 */
43 static XrmOptionDescRec options[] =
44 {
45 {"-bs", ".bufSize", XrmoptionSepArg, NULL},
46 {"-dir", ".noteDir", XrmoptionSepArg, NULL},
47 {"-interval", ".interval", XrmoptionSepArg, NULL},
48 {"-sb", ".scrollBar", XrmoptionNoArg, "true"},
49 {"-sv", ".saveNotes", XrmoptionNoArg, "true"},
50 {"-c", ".compatibility", XrmoptionNoArg, "true"},
51 {"-nw", ".nameWidth", XrmoptionSepArg, NULL},
52 {"-ns", ".noSave", XrmoptionNoArg, "true"},
53 {"-na", ".noAlarm", XrmoptionNoArg, "true"},
54 {"-help", ".help", XrmoptionNoArg, "true"},
55 {"-h", ".help", XrmoptionNoArg, "true"},
56 {"-version", ".version", XrmoptionNoArg, "true"},
57 {"-V", ".version", XrmoptionNoArg, "true"},
58 {"-?", ".help", XrmoptionNoArg, "true"},
59 {"-ao", ".anchorOffset", XrmoptionSepArg, NULL},
60 {"-tmpdir", ".tmpDir", XrmoptionSepArg, NULL},
61 {"-printcmd", ".printCmd", XrmoptionSepArg, NULL},
62 {"-calendarcmd", ".calendarCmd", XrmoptionSepArg, NULL},
63 {"-emailcmd", ".emailCmd", XrmoptionSepArg, NULL},
64 {"-homedir", ".homeDir", XrmoptionSepArg, NULL},
65 };
66
67 /*
68 * Fallback resources.
69 */
70 static String fallback_resources[] =
71 {
72 #include "app_defaults.h"
73 NULL
74 };
75
76 /*
77 * Resources we maintain besides those maintained by the toolkit.
78 */
79 static XtResource resources[] =
80 {
81 #define offset(field) XtOffset(AppResPtr,field)
82 {"bufSize", "BufSize", XtRInt, sizeof(int),
83 offset(buf_size), XtRImmediate, (caddr_t) DefaultBufSize},
84 {"noteDir", "NoteDir", XtRString, sizeof(String),
85 offset(note_dir), XtRString, DefaultNoteDir},
86 {"interval", "Interval", XtRInt, sizeof(int),
87 offset(interval), XtRImmediate, (caddr_t) DefaultInterval},
88 {"saveNotes", "SaveNotes", XtRBoolean, sizeof(Boolean),
89 offset(save_notes), XtRImmediate, (caddr_t) False},
90 {"scrollBar", "Scroll", XtRBoolean, sizeof(Boolean),
91 offset(scroll_bar), XtRImmediate, (caddr_t) False},
92 {"compatibility", "Compatibility", XtRBoolean, sizeof(Boolean),
93 offset(compatibility), XtRImmediate, (caddr_t) False},
94 {"nameWidth", "NameWidth", XtRInt, sizeof(int),
95 offset(name_width), XtRImmediate, (caddr_t) DefaultNameWidth},
96 {"noSave", "NoSave", XtRBoolean, sizeof(Boolean),
97 offset(nosave), XtRImmediate, (caddr_t) False},
98 {"noAlarm", "NoAlarm", XtRBoolean, sizeof(Boolean),
99 offset(noalarm), XtRImmediate, (caddr_t) False},
100 {"help", "Help", XtRBoolean, sizeof(Boolean),
101 offset(help), XtRImmediate, (caddr_t) False},
102 {"version", "Version", XtRBoolean, sizeof(Boolean),
103 offset(version), XtRImmediate, (caddr_t) False},
104 {"anchorOffset", "AnchorOffset", XtRInt, sizeof(int),
105 offset(anchor_offset), XtRImmediate, (caddr_t) DefaultAnchorOffset},
106 {"tmpDir", "TmpDir", XtRString, sizeof(String),
107 offset(tmp_dir), XtRString, (caddr_t) DefaultTmpDir},
108 {"printCmd", "PrintCmd", XtRString, sizeof(String),
109 offset(print_cmd), XtRString, (caddr_t) DefaultPrintCmd},
110 {"calendarCmd", "CalendarCmd", XtRString, sizeof(String),
111 offset(calendar_cmd), XtRString, (caddr_t) DefaultCalendarCmd},
112 {"emailCmd", "EmailCmd", XtRString, sizeof(String),
113 offset(email_cmd), XtRString, (caddr_t) DefaultEmailCmd},
114 {"homeDir", "HomeDir", XtRString, sizeof(String),
115 offset(home_dir), XtRString, (caddr_t) DefaultHomeDir},
116 #undef offset
117 };
118
119 static Atom wm_delete_window, wm_save_yourself, wm_protocols, wm_command;
120 static void WMProtocolsHandler();
121
122 AppRes app_res; /* xpostit application resources */
123 Widget toplevel; /* top level application shell widget */
124 int screen; /* screen of the display */
125 Display *display; /* pointer to the display we're on */
126 XtAppContext appcontext; /* application context */
127 int curr_screenx, curr_screeny; /* size of current screen */
128 XtIntervalId timer; /* used for auto-save feature */
129 XtIntervalId alarm_timer; /* used for alarms feature */
130
131 unsigned long timer_interval; /* auto-save interval */
132 unsigned long alarm_interval; /* alarm check interval */
133
main(argc,argv)134 int main(argc, argv)
135 char **argv;
136 int argc;
137 {
138 char *appname;
139 Atom protos[2];
140 Boolean setsigs = False;
141
142 /*
143 * Ignore signals for now, but record whether they were
144 * already ignored or not so we can catch them later if
145 * need be.
146 */
147 if ((signal(SIGQUIT, SIG_IGN) != SIG_IGN) &&
148 (signal(SIGINT, SIG_IGN) != SIG_IGN))
149 setsigs = True;
150
151 /*
152 * Get application name.
153 */
154 if ((appname = rindex(*argv, '/')) == NULL)
155 appname = *argv;
156 else
157 appname++;
158
159 /*
160 * Initialize the toolkit and create an application shell.
161 */
162 toplevel = XtAppInitialize(&appcontext, PostItNoteClass, options,
163 XtNumber(options), &argc, argv, fallback_resources,
164 NULL, 0);
165
166 display = XtDisplay(toplevel);
167
168 screen = DefaultScreen(display);
169 curr_screenx = DisplayHeight(display, screen);
170 curr_screeny = DisplayWidth(display, screen);
171
172 /*
173 * If we need to handle keyboard signals, do it now.
174 */
175 if (setsigs) {
176 signal(SIGQUIT, ByeBye);
177 signal(SIGINT, ByeBye);
178 }
179 /*
180 * Always handle these.
181 */
182 signal(SIGTERM, ByeBye);
183 signal(SIGHUP, ByeBye);
184
185 /*
186 * Send X errors to the exit routine.
187 */
188 XSetErrorHandler((XErrorHandler) ByeBye);
189
190 /*
191 * Now get any resources we're interested in.
192 */
193 XtGetApplicationResources(toplevel, &app_res, resources,
194 XtNumber(resources), (ArgList) argv, (Cardinal) argc);
195
196 /*
197 * if the user requested help, provide it
198 */
199 if (app_res.help) {
200 printf(USAGE);
201 exit(0);
202 }
203 /*
204 * if the user requested the version, provide it
205 */
206 if (app_res.version) {
207 printf("aspostit %s Copyright (c) 1998 Guylhem Aznar\n", AS_VERSION);
208 printf("xpostit+ v%s\n", VERSION);
209 printf("Copyright 1994-1996 Michael J. Hammel\n\n");
210 exit(0);
211 }
212 /*
213 * Construct the path to the directory notes are
214 * stored in.
215 */
216 SetNoteDir();
217
218 /*
219 * Construct the path to the temporary directory ...
220 */
221 SetTempDir();
222
223 /*
224 * Create the plaid, menu, and list widgets.
225 */
226 CreatePlaidWidget();
227 CreateMenuWidget();
228
229 /*
230 * Let the top level shell know about the menus.
231 */
232 XawSimpleMenuAddGlobalActions(appcontext);
233 XtRealizeWidget(menuwidget);
234
235 /*
236 * Realize the top level and flush the server, which will
237 * let the user position the plaid window and map it.
238 */
239 XtRealizeWidget(toplevel);
240
241 /*
242 * Set some properties for the window manager.
243 */
244 wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
245 wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
246 wm_save_yourself = XInternAtom(display, "WM_SAVE_YOURSELF", False);
247
248 protos[0] = wm_delete_window;
249 protos[1] = wm_save_yourself;
250 XSetWMProtocols(display, XtWindow(toplevel), protos, 2);
251 XtAddEventHandler(toplevel, 0, True, WMProtocolsHandler, NULL);
252 XtVaSetValues(toplevel, XtNwindowGroup, XtWindow(toplevel), NULL);
253
254 /* Flush */
255 XFlush(display);
256
257 /*
258 * Load the notes the user has saved, and create widgets
259 * for them.
260 */
261 LoadSavedNotes();
262
263 /*
264 * Start the autosave timer, unless requested not to
265 */
266 if (!app_res.nosave) {
267 timer_interval = app_res.interval * 60 * 1000;
268 timer = XtAppAddTimeOut(
269 XtWidgetToApplicationContext(toplevel),
270 timer_interval,
271 AutoSave,
272 NULL);
273 }
274 /*
275 * Start the alarm timer (once a minute)
276 */
277 if (!app_res.noalarm) {
278 alarm_interval = 60 * 1000;
279 alarm_timer = XtAppAddTimeOut(
280 XtWidgetToApplicationContext(toplevel),
281 alarm_interval,
282 AlarmCheck,
283 NULL);
284 }
285 /*
286 * Never returns.
287 */
288 XtAppMainLoop(appcontext);
289 }
290
291
292 /*
293 * WMProtocolsHandler - top level WM protocol handler. WM_DELETE_WINDOW
294 * is quit xpostit, WM_SAVE_YOURSELF is save all notes.
295 */
WMProtocolsHandler(w,client_data,event,continue_to_dispatch)296 static void WMProtocolsHandler(w, client_data, event, continue_to_dispatch)
297 Boolean *continue_to_dispatch;
298 XtPointer client_data;
299 XEvent *event;
300 Widget w;
301 {
302 XClientMessageEvent *c_event = (XClientMessageEvent *) event;
303
304 if (event->type != ClientMessage ||
305 c_event->message_type != wm_protocols)
306 return;
307
308 if (c_event->data.l[0] == wm_delete_window) {
309 ByeBye();
310 } else if (c_event->data.l[0] == wm_save_yourself) {
311 if (app_res.save_notes)
312 SaveAllNotes();
313 /*
314 * Let session manager know we've saved ourself by doing
315 * a zero-length append on the WM_COMMAND property.
316 */
317 XChangeProperty(XtDisplay(w), XtWindow(w), wm_command,
318 XA_STRING, 8, PropModeAppend, (unsigned char *) "", 0);
319 }
320 }
321