/* * Copyright (c) 1998 Guylhem Aznar * Copyright (c) 1991 David A. Curry * Copyright (c) 1996 Michael J. Hammel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * xpostit.c - Post-It Notes for the X Window System. * * You can get David A. Curry's original public domain version on : * ftp://ftp.ers.ibm.com/pub/davy/xpostit3.3.2.tar.gz * */ #include #include #include #include #include #include #include #include #include "xpostit.h" #include "version.h" /* * Command line options and the resources they set. */ static XrmOptionDescRec options[] = { {"-bs", ".bufSize", XrmoptionSepArg, NULL}, {"-dir", ".noteDir", XrmoptionSepArg, NULL}, {"-interval", ".interval", XrmoptionSepArg, NULL}, {"-sb", ".scrollBar", XrmoptionNoArg, "true"}, {"-sv", ".saveNotes", XrmoptionNoArg, "true"}, {"-c", ".compatibility", XrmoptionNoArg, "true"}, {"-nw", ".nameWidth", XrmoptionSepArg, NULL}, {"-ns", ".noSave", XrmoptionNoArg, "true"}, {"-na", ".noAlarm", XrmoptionNoArg, "true"}, {"-help", ".help", XrmoptionNoArg, "true"}, {"-h", ".help", XrmoptionNoArg, "true"}, {"-version", ".version", XrmoptionNoArg, "true"}, {"-V", ".version", XrmoptionNoArg, "true"}, {"-?", ".help", XrmoptionNoArg, "true"}, {"-ao", ".anchorOffset", XrmoptionSepArg, NULL}, {"-tmpdir", ".tmpDir", XrmoptionSepArg, NULL}, {"-printcmd", ".printCmd", XrmoptionSepArg, NULL}, {"-calendarcmd", ".calendarCmd", XrmoptionSepArg, NULL}, {"-emailcmd", ".emailCmd", XrmoptionSepArg, NULL}, {"-homedir", ".homeDir", XrmoptionSepArg, NULL}, }; /* * Fallback resources. */ static String fallback_resources[] = { #include "app_defaults.h" NULL }; /* * Resources we maintain besides those maintained by the toolkit. */ static XtResource resources[] = { #define offset(field) XtOffset(AppResPtr,field) {"bufSize", "BufSize", XtRInt, sizeof(int), offset(buf_size), XtRImmediate, (caddr_t) DefaultBufSize}, {"noteDir", "NoteDir", XtRString, sizeof(String), offset(note_dir), XtRString, DefaultNoteDir}, {"interval", "Interval", XtRInt, sizeof(int), offset(interval), XtRImmediate, (caddr_t) DefaultInterval}, {"saveNotes", "SaveNotes", XtRBoolean, sizeof(Boolean), offset(save_notes), XtRImmediate, (caddr_t) False}, {"scrollBar", "Scroll", XtRBoolean, sizeof(Boolean), offset(scroll_bar), XtRImmediate, (caddr_t) False}, {"compatibility", "Compatibility", XtRBoolean, sizeof(Boolean), offset(compatibility), XtRImmediate, (caddr_t) False}, {"nameWidth", "NameWidth", XtRInt, sizeof(int), offset(name_width), XtRImmediate, (caddr_t) DefaultNameWidth}, {"noSave", "NoSave", XtRBoolean, sizeof(Boolean), offset(nosave), XtRImmediate, (caddr_t) False}, {"noAlarm", "NoAlarm", XtRBoolean, sizeof(Boolean), offset(noalarm), XtRImmediate, (caddr_t) False}, {"help", "Help", XtRBoolean, sizeof(Boolean), offset(help), XtRImmediate, (caddr_t) False}, {"version", "Version", XtRBoolean, sizeof(Boolean), offset(version), XtRImmediate, (caddr_t) False}, {"anchorOffset", "AnchorOffset", XtRInt, sizeof(int), offset(anchor_offset), XtRImmediate, (caddr_t) DefaultAnchorOffset}, {"tmpDir", "TmpDir", XtRString, sizeof(String), offset(tmp_dir), XtRString, (caddr_t) DefaultTmpDir}, {"printCmd", "PrintCmd", XtRString, sizeof(String), offset(print_cmd), XtRString, (caddr_t) DefaultPrintCmd}, {"calendarCmd", "CalendarCmd", XtRString, sizeof(String), offset(calendar_cmd), XtRString, (caddr_t) DefaultCalendarCmd}, {"emailCmd", "EmailCmd", XtRString, sizeof(String), offset(email_cmd), XtRString, (caddr_t) DefaultEmailCmd}, {"homeDir", "HomeDir", XtRString, sizeof(String), offset(home_dir), XtRString, (caddr_t) DefaultHomeDir}, #undef offset }; static Atom wm_delete_window, wm_save_yourself, wm_protocols, wm_command; static void WMProtocolsHandler(); AppRes app_res; /* xpostit application resources */ Widget toplevel; /* top level application shell widget */ int screen; /* screen of the display */ Display *display; /* pointer to the display we're on */ XtAppContext appcontext; /* application context */ int curr_screenx, curr_screeny; /* size of current screen */ XtIntervalId timer; /* used for auto-save feature */ XtIntervalId alarm_timer; /* used for alarms feature */ unsigned long timer_interval; /* auto-save interval */ unsigned long alarm_interval; /* alarm check interval */ void main(argc, argv) char **argv; int argc; { char *appname; Atom protos[2]; Boolean setsigs = False; /* * Ignore signals for now, but record whether they were * already ignored or not so we can catch them later if * need be. */ if ((signal(SIGQUIT, SIG_IGN) != SIG_IGN) && (signal(SIGINT, SIG_IGN) != SIG_IGN)) setsigs = True; /* * Get application name. */ if ((appname = rindex(*argv, '/')) == NULL) appname = *argv; else appname++; /* * Initialize the toolkit and create an application shell. */ toplevel = XtAppInitialize(&appcontext, PostItNoteClass, options, XtNumber(options), &argc, argv, fallback_resources, NULL, 0); display = XtDisplay(toplevel); screen = DefaultScreen(display); curr_screenx = DisplayHeight(display, screen); curr_screeny = DisplayWidth(display, screen); /* * If we need to handle keyboard signals, do it now. */ if (setsigs) { signal(SIGQUIT, ByeBye); signal(SIGINT, ByeBye); } /* * Always handle these. */ signal(SIGTERM, ByeBye); signal(SIGHUP, ByeBye); /* * Send X errors to the exit routine. */ XSetErrorHandler((XErrorHandler) ByeBye); /* * Now get any resources we're interested in. */ XtGetApplicationResources(toplevel, &app_res, resources, XtNumber(resources), (ArgList) argv, (Cardinal) argc); /* * if the user requested help, provide it */ if (app_res.help) { printf(USAGE); exit(0); } /* * if the user requested the version, provide it */ if (app_res.version) { printf("aspostit %s Copyright (c) 1998 Guylhem Aznar\n", AS_VERSION); printf("xpostit+ v%s\n", VERSION); printf("Copyright 1994-1996 Michael J. Hammel\n\n"); exit(0); } /* * Construct the path to the directory notes are * stored in. */ SetNoteDir(); /* * Construct the path to the temporary directory ... */ SetTempDir(); /* * Create the plaid, menu, and list widgets. */ CreatePlaidWidget(); CreateMenuWidget(); /* * Let the top level shell know about the menus. */ XawSimpleMenuAddGlobalActions(appcontext); XtRealizeWidget(menuwidget); /* * Realize the top level and flush the server, which will * let the user position the plaid window and map it. */ XtRealizeWidget(toplevel); /* * Set some properties for the window manager. */ wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); wm_save_yourself = XInternAtom(display, "WM_SAVE_YOURSELF", False); protos[0] = wm_delete_window; protos[1] = wm_save_yourself; XSetWMProtocols(display, XtWindow(toplevel), protos, 2); XtAddEventHandler(toplevel, 0, True, WMProtocolsHandler, NULL); XtVaSetValues(toplevel, XtNwindowGroup, XtWindow(toplevel), NULL); /* Flush */ XFlush(display); /* * Load the notes the user has saved, and create widgets * for them. */ LoadSavedNotes(); /* * Start the autosave timer, unless requested not to */ if (!app_res.nosave) { timer_interval = app_res.interval * 60 * 1000; timer = XtAppAddTimeOut( XtWidgetToApplicationContext(toplevel), timer_interval, AutoSave, NULL); } /* * Start the alarm timer (once a minute) */ if (!app_res.noalarm) { alarm_interval = 60 * 1000; alarm_timer = XtAppAddTimeOut( XtWidgetToApplicationContext(toplevel), alarm_interval, AlarmCheck, NULL); } /* * Never returns. */ XtAppMainLoop(appcontext); } /* * WMProtocolsHandler - top level WM protocol handler. WM_DELETE_WINDOW * is quit xpostit, WM_SAVE_YOURSELF is save all notes. */ static void WMProtocolsHandler(w, client_data, event, continue_to_dispatch) Boolean *continue_to_dispatch; XtPointer client_data; XEvent *event; Widget w; { XClientMessageEvent *c_event = (XClientMessageEvent *) event; if (event->type != ClientMessage || c_event->message_type != wm_protocols) return; if (c_event->data.l[0] == wm_delete_window) { ByeBye(); } else if (c_event->data.l[0] == wm_save_yourself) { if (app_res.save_notes) SaveAllNotes(); /* * Let session manager know we've saved ourself by doing * a zero-length append on the WM_COMMAND property. */ XChangeProperty(XtDisplay(w), XtWindow(w), wm_command, XA_STRING, 8, PropModeAppend, (unsigned char *) "", 0); } }