#include #include #include #include #include #include #include "libami.h" #include "drawinfo.h" char *progname; Display *dpy; XContext launchercontext; struct DrawInfo dri; Atom appiconmsg; char *icondir; struct launcher { struct ColorStore colorstore1, colorstore2; char cmdline[1]; }; #ifdef AMIGAOS void spawn(const char *cmd) { char *line=malloc(strlen(cmd)+12); if(line) { sprintf(line, "RUN <>NIL: %s", cmd); system(line); free(line); } } #else void spawn(const char *cmd) { #ifdef HAVE_ALLOCA char *line=alloca(strlen(cmd)+4); #else char *line=malloc(strlen(cmd)+4); if(line) { #endif sprintf(line, "%s &", cmd); #ifdef __ultrix { int pid, status; if ((pid = fork ()) == 0) { (void) setsid(); execl ("/bin/sh", "sh", "-c", line, 0); } else waitpid (pid, &status, 0); } #else system(line); #endif #ifndef HAVE_ALLOCA free(line); } #endif } #endif static void broker_cb(XEvent *evt, unsigned long mask) { XPointer ret; if(evt->type != ClientMessage || evt->xclient.message_type != appiconmsg) return; if(!XFindContext(dpy, evt->xclient.window, launchercontext, &ret)) { struct launcher *l = (struct launcher*)ret; spawn(l->cmdline); } } static void create_broker() { cx_broker(0, broker_cb); } static void create_launcher(char *label, char *icon, char *cmdline) { struct DiskObject *icon_do = NULL; Pixmap icon_icon1, icon_icon2; Window win; struct launcher *l = malloc(sizeof(struct launcher)+strlen(cmdline)); if (l == NULL) { fprintf(stderr, "%s: out of memory!\n", progname); exit(1); } memset(l, 0, sizeof(*l)); strcpy(l->cmdline, cmdline); if (icon != NULL && *icon != 0) { #ifdef AMIGAOS char fn[256]; strncpy(fn, icondir, sizeof(fn)-1); fn[sizeof(fn)-1]='\0'; AddPart(fn,icon,sizeof(fn)); #else int rl=strlen(icon)+strlen(icondir)+2; #ifdef HAVE_ALLOCA char *fn=alloca(rl); #else char fn[1024]; #endif sprintf(fn, "%s/%s", icondir, icon); #endif fn[strlen(fn)-5]=0; icon_do = GetDiskObject(fn); } if(icon_do == NULL) icon_do = GetDefDiskObject(3/*WBTOOL*/); if(icon_do == NULL) { md_errormsg(md_root, "Failed to load icon"); md_exit(0); } icon_icon1 = md_image_to_pixmap(md_root, dri.dri_Pens[BACKGROUNDPEN], (struct Image *)icon_do->do_Gadget.GadgetRender, icon_do->do_Gadget.Width, icon_do->do_Gadget.Height, &l->colorstore1); icon_icon2 = md_image_to_pixmap(md_root, dri.dri_Pens[BACKGROUNDPEN], (struct Image *)icon_do->do_Gadget.SelectRender, icon_do->do_Gadget.Width, icon_do->do_Gadget.Height, &l->colorstore2); FreeDiskObject(icon_do); XSync(dpy, False); win = md_create_appicon(md_root, 0x80000000, 0x80000000, label, icon_icon1, icon_icon2, None); XSaveContext(dpy, win, launchercontext, (XPointer)l); } static int skip_ws(char *arg, int len) { int n = 0; while(len > 0 && isspace(*(unsigned char *)arg)) { n++; arg++; --len; } return n; } static int get_string(char *arg, int len, int lineno) { int n; if (len < 1 || *arg != '(') { fprintf(stderr, "%s: missing '(' on line %d\n", progname, lineno); return 0; } for (n=1; n= len) { fprintf(stderr, "%s: missing ')' on line %d\n", progname, lineno); return 0; } return n+1; } static char *create_string(char *arg, int l) { char *p = malloc(l+1); if (!p) { fprintf(stderr, "%s: out of memory!\n", progname); exit(1); } if(l>0) memcpy(p, arg, l); p[l] = 0; return p; } static void create_appicons_line(char *arg, int len, int lineno) { int l; char *label, *icon, *cmdline; if (*arg == '#') return; l = skip_ws(arg, len); arg += l; len -= l; if (!len) return; l = get_string(arg, len, lineno); if (!l) return; label = create_string(arg+1, l-2); arg += l; len -= l; l = skip_ws(arg, len); arg += l; len -= l; l = get_string(arg, len, lineno); if (!l) { free(label); return; } icon = create_string(arg+1, l-2); arg += l; len -= l; l = skip_ws(arg, len); arg += l; len -= l; l = get_string(arg, len, lineno); if (!l) { free(icon); free(label); return; } cmdline = create_string(arg+1, l-2); arg += l; len -= l; l = skip_ws(arg, len); arg += l; len -= l; if (len) fprintf(stderr, "%s: junk at end of line %d\n", progname, lineno); create_launcher(label, icon, cmdline); free(cmdline); free(icon); free(label); } static void create_appicons(char *arg) { char *p; int l = 1; while((p = strchr(arg, '\n'))) { create_appicons_line(arg, p-arg, l++); arg = p+1; } create_appicons_line(arg, strlen(arg), l); } static void setup() { XWindowAttributes attr; launchercontext = XUniqueContext(); XGetWindowAttributes(dpy, md_root, &attr); init_dri(&dri, dpy, md_root, attr.colormap, False); appiconmsg = XInternAtom(dpy, "AMIWM_APPICONMSG", False); icondir = get_current_icondir(); if(!icondir) icondir=""; } int main(int argc, char *argv[]) { char *arg=md_init(argc, argv); progname=argv[0]; if(!(dpy = md_display())) { fprintf(stderr, "%s: cannot connect to X server %s\n", progname, XDisplayName(NULL)); exit(1); } if(arg) { setup(); create_broker(); create_appicons(arg); md_main_loop(); } return 0; }