#include #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_WAIT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "libami.h" #include "drawinfo.h" #ifdef BSD_STYLE_GETTIMEOFDAY #define GETTIMEOFDAY(tp) gettimeofday(tp, NULL) #else #define GETTIMEOFDAY(tp) gettimeofday(tp) #endif #define FIXUPTV(tv) { \ while((tv).tv_usec<0) { (tv).tv_usec+=1000000; (tv).tv_sec--; } \ while((tv).tv_usec>=1000000) { (tv).tv_usec-=1000000; (tv).tv_sec++; } \ } #define BIN_PREFIX AMIWM_HOME"/" #define NFMT 2 char fmt[NFMT+2][80]; int fmtw[NFMT]; Display *dpy; char *progname; unsigned long color_scheme[2]; int scr, coloralloc, state=0; Window root, win, win2; Colormap cmap; GC gc; XFontStruct *font; int gh, gw, ascent; char *rcpath = BIN_PREFIX"requestchoice"; char *rcmsg = "Notice"; Pixmap disk_icon1, disk_icon2; struct ColorStore colorstore1, colorstore2; struct DrawInfo dri; Atom appiconmsg; char *currentdir = NULL; XContext dircontext; int my_in_fd, my_out_fd; void load_diskicon() { struct DiskObject *disk_do; disk_do = GetDefDiskObject(1/*WBDISK*/); if(disk_do == NULL) disk_do = GetDefDiskObject(2/*WBDRAWER*/); if(disk_do == NULL) disk_do = GetDefDiskObject(3/*WBTOOL*/); if(disk_do == NULL) { md_errormsg(md_root, "Failed to load disk icon"); md_exit(0); } disk_icon1 = md_image_to_pixmap(md_root, dri.dri_Pens[BACKGROUNDPEN], (struct Image *)disk_do->do_Gadget.GadgetRender, disk_do->do_Gadget.Width, disk_do->do_Gadget.Height, &colorstore1); disk_icon2 = md_image_to_pixmap(md_root, dri.dri_Pens[BACKGROUNDPEN], (struct Image *)disk_do->do_Gadget.SelectRender, disk_do->do_Gadget.Width, disk_do->do_Gadget.Height, &colorstore2); FreeDiskObject(disk_do); XSync(dpy, False); } 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, dircontext, &ret)) currentdir = (char*)ret; } void create_broker() { cx_broker(0, broker_cb); } void create_baseicons(char *dirs) { char *dir, *dup = malloc(strlen(dirs)+1); if(dup == NULL) return; strcpy(dup, dirs); for(dir=strtok(dup, ":"); dir; dir=strtok(NULL, ":")) { Window win = md_create_appicon(md_root, 0x80000000, 0x80000000, dir, disk_icon1, disk_icon2, None); XSaveContext(dpy, win, dircontext, (XPointer)dir); } free(dup); } void migrate(int amount) { Window r, p, *c = NULL; unsigned int i, nc; if(XQueryTree(dpy, root, &r, &p, &c, &nc)) { XWarpPointer(dpy, None, None, 0, 0, 0, 0, 0, amount); for(i=0; i=n? i-n+1:i)]; if((c>'@' && c<'[')||(c>'`' && c<'{')) c = (c&0xe0)|((((c&0x1f)+12)%26)+1); *dst++ = c; } *dst = '\0'; } void setup() { XWindowAttributes attr; XSetWindowAttributes nw; XGCValues gcv; XColor clr; int i; dircontext = XUniqueContext(); XGetWindowAttributes(dpy, root, &attr); cmap = attr.colormap; coloralloc = 0; color_scheme[0] = BlackPixel(dpy, scr); clr.flags = DoRed|DoGreen|DoBlue; clr.red = ~0; clr.green = 0; clr.blue = 0; if(XAllocColor(dpy, cmap, &clr)) { color_scheme[1] = clr.pixel; coloralloc = 1; } else color_scheme[1] = WhitePixel(dpy, scr); nw.background_pixel = color_scheme[0]; nw.border_pixel = color_scheme[1]; nw.backing_store = NotUseful; nw.save_under = False; nw.event_mask = ExposureMask|ButtonPressMask; nw.override_redirect = True; nw.colormap = cmap; nw.cursor = None; install_kw(fmt[0], "Fsbgs gzjbnhefrr Sonhvgyghbear .g b pCbeargfvfa hyrr."); win = XCreateWindow(dpy, root, 0, 0, gw = attr.width, gh = 84, 0, attr.depth, InputOutput, attr.visual, CWBackPixel|CWBorderPixel|CWBackingStore|CWSaveUnder| CWEventMask|CWOverrideRedirect|CWColormap|CWCursor, &nw); install_kw(fmt[1], "T0h0e0h0 0Z0r0q4v.g0n0g0v0bNaO 7#8"); win2 = XCreateWindow(dpy, root, 0, 0, 1, 1, 0, 0, InputOnly, attr.visual, CWOverrideRedirect, &nw); install_kw(fmt[2], "NYC!E!V!Y\n' F S:B-B)"); font = XLoadQueryFont(dpy, "-*-courier-bold-r-normal--14-*-*-*-*-*-iso8859-1"); if(font == NULL) font = XLoadQueryFont(dpy, "fixed"); install_kw(fmt[3], "Ubrqu ,w btxbr"); gcv.font = font->fid; gc = XCreateGC(dpy, win, GCFont, &gcv); for(i=0; i=0) close(my_in_fd); if(my_out_fd>=0 && my_out_fd != my_in_fd) close(my_out_fd); if(of>=0) { if(of!=1) dup2(of, 1); if(of!=2) dup2(of, 2); } execv(msg[0], msg); perror("execv"); _exit(1); } else if(pid<0) { perror("fork"); exit(1); } } void cleanup() { XFreeGC(dpy, gc); XFreeFont(dpy, font); XDestroyWindow(dpy, win); XDestroyWindow(dpy, win2); if(coloralloc) XFreeColors(dpy, cmap, color_scheme+1, 1, 0); } void post_cleanup() { char *clu[5]; int i; for(i=0; i<4; i++) clu[i]=fmt[i]; clu[4]=NULL; post(clu); } void redraw() { int i; if(state) XSetForeground(dpy, gc, color_scheme[1]); else XSetForeground(dpy, gc, color_scheme[0]); XFillRectangle(dpy, win, gc, 2, 2, 8, gh-4); XFillRectangle(dpy, win, gc, gw-10, 2, 8, gh-4); XFillRectangle(dpy, win, gc, 2, 2, gw-4, 8); XFillRectangle(dpy, win, gc, 2, gh-10, gw-4, 8); if(!state) XSetForeground(dpy, gc, color_scheme[1]); for(i=0; i>1, 22+i*26+ascent, fmt[i], strlen(fmt[i])); } int main(int argc, char *argv[]) { int x_fd, cnt=0; fd_set rfd_set; struct timeval nextt; char *basedir; progname = argv[0]; basedir = md_init(argc, argv); if(basedir == NULL) basedir = "/"; my_in_fd=strtol(argv[1], NULL, 0); my_out_fd=strtol(argv[2], NULL, 0); if(!(dpy = md_display())) { fprintf(stderr, "%s: cannot connect to X server %s\n", progname, XDisplayName(NULL)); exit(1); } scr = DefaultScreen(dpy); root = RootWindow(dpy, scr); x_fd = ConnectionNumber(dpy); setup(); load_diskicon(); create_broker(); create_baseicons(basedir); do md_process_queued_events(); while(currentdir == NULL && md_handle_input()>=0); activate(); XSync(dpy, False); GETTIMEOFDAY(&nextt); for(;;) { XEvent event; struct timeval t; while(QLength(dpy)>0) { XNextEvent(dpy, &event); switch(event.type) { case Expose: redraw(); break; case ButtonPress: cnt = 999; break; } } FD_ZERO(&rfd_set); FD_SET(x_fd, &rfd_set); GETTIMEOFDAY(&t); t.tv_sec = nextt.tv_sec - t.tv_sec; t.tv_usec = nextt.tv_usec - t.tv_usec; FIXUPTV(t); while(t.tv_sec<0) { state = !state; cnt++; redraw(); t.tv_usec += 800000; nextt.tv_usec += 800000; FIXUPTV(nextt); FIXUPTV(t); } XFlush(dpy); if(cnt>=16) break; if(select(x_fd+1, &rfd_set, NULL, NULL, &t)<0) { perror("select"); break; } if(FD_ISSET(x_fd, &rfd_set)) XPeekEvent(dpy, &event); } deactivate(); cleanup(); post_cleanup(); XCloseDisplay(dpy); md_exit(0); return 0; }