#include #include #include #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #ifdef USE_FONTSETS #include #include #endif #include "drawinfo.h" #ifdef AMIGAOS #include extern struct Library *XLibBase; #endif #define MAX_CMD_CHARS 256 #define VISIBLE_CMD_CHARS 35 #define BOT_SPACE 4 #define TEXT_SIDE 8 #define BUT_SIDE 12 #define TOP_SPACE 4 #define INT_SPACE 7 #define BUT_VSPACE 2 #define BUT_HSPACE 8 static const char ok_txt[]="Ok", cancel_txt[]="Cancel"; static const char enter_txt[]="Enter Command and its Arguments:"; static const char cmd_txt[]="Command:"; static int selected=0, depressed=0, stractive=1; static Window button[3]; static const char *buttxt[]={ NULL, ok_txt, cancel_txt }; char cmdline[MAX_CMD_CHARS+1]; int buf_len=0; int cur_pos=0; int left_pos=0; int cur_x=6; char *progname; Display *dpy; struct DrawInfo dri; Window root, mainwin, strwin; GC gc; int strgadw, strgadh, fh, mainw, mainh, butw; #ifdef USE_FONTSETS static XIM xim = (XIM) NULL; static XIC xic = (XIC) NULL; #endif int getchoice(Window w) { int i; for(i=1; i<3; i++) if(button[i]==w) return i; return 0; } void refresh_button(Window w, const char *txt, int idx) { int h=fh+2*BUT_VSPACE, l=strlen(txt); #ifdef USE_FONTSETS int tw=XmbTextEscapement(dri.dri_FontSet, txt, l); #else int tw=XTextWidth(dri.dri_Font, txt, l); #endif XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); #ifdef USE_FONTSETS XmbDrawString(dpy, w, dri.dri_FontSet, gc, (butw-tw)>>1, dri.dri_Ascent+BUT_VSPACE, txt, l); #else XDrawString(dpy, w, gc, (butw-tw)>>1, dri.dri_Ascent+BUT_VSPACE, txt, l); #endif XSetForeground(dpy, gc, dri.dri_Pens[(selected==idx && depressed)? SHADOWPEN:SHINEPEN]); XDrawLine(dpy, w, gc, 0, 0, butw-2, 0); XDrawLine(dpy, w, gc, 0, 0, 0, h-2); XSetForeground(dpy, gc, dri.dri_Pens[(selected==idx && depressed)? SHINEPEN:SHADOWPEN]); XDrawLine(dpy, w, gc, 1, h-1, butw-1, h-1); XDrawLine(dpy, w, gc, butw-1, 1, butw-1, h-1); XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); XDrawPoint(dpy, w, gc, butw-1, 0); XDrawPoint(dpy, w, gc, 0, h-1); } void refresh_main(void) { int w; XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); #ifdef USE_FONTSETS XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, TEXT_SIDE, TOP_SPACE+dri.dri_Ascent, enter_txt, strlen(enter_txt)); #else XDrawString(dpy, mainwin, gc, TEXT_SIDE, TOP_SPACE+dri.dri_Ascent, enter_txt, strlen(enter_txt)); #endif XSetForeground(dpy, gc, dri.dri_Pens[HIGHLIGHTTEXTPEN]); #ifdef USE_FONTSETS w=XmbTextEscapement(dri.dri_FontSet, cmd_txt, strlen(cmd_txt)); XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, cmd_txt, strlen(cmd_txt)); #else w=XTextWidth(dri.dri_Font, cmd_txt, strlen(cmd_txt)); XDrawString(dpy, mainwin, gc, mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, cmd_txt, strlen(cmd_txt)); #endif } void refresh_str_text(void) { int l, mx=6; XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); if(buf_len>left_pos) { #ifdef USE_FONTSETS int w, c; for(l=0; lstrgadw-6) break; mx=w; l+=c; } XmbDrawImageString(dpy, strwin, dri.dri_FontSet, gc, 6, 3+dri.dri_Ascent, cmdline+left_pos, l); #else mx+=XTextWidth(dri.dri_Font, cmdline+left_pos, l=buf_len-left_pos); while(mx>strgadw-6) mx-=XTextWidth(dri.dri_Font, cmdline+left_pos+--l, 1); XDrawImageString(dpy, strwin, gc, 6, 3+dri.dri_Ascent, cmdline+left_pos, l); #endif } XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); XFillRectangle(dpy, strwin, gc, mx, 3, strgadw-mx-6, fh); if(stractive) { if(cur_pos max_logical_extent.width, fh); #else XFillRectangle(dpy, strwin, gc, cur_x, 3, dri.dri_Font->max_bounds.width, fh); #endif } } } void refresh_str(void) { refresh_str_text(); XSetForeground(dpy, gc, dri.dri_Pens[SHINEPEN]); XDrawLine(dpy, strwin, gc, 0, strgadh-1, 0, 0); XDrawLine(dpy, strwin, gc, 0, 0, strgadw-2, 0); XDrawLine(dpy, strwin, gc, 3, strgadh-2, strgadw-4, strgadh-2); XDrawLine(dpy, strwin, gc, strgadw-4, strgadh-2, strgadw-4, 2); XDrawLine(dpy, strwin, gc, 1, 1, 1, strgadh-2); XDrawLine(dpy, strwin, gc, strgadw-3, 1, strgadw-3, strgadh-2); XSetForeground(dpy, gc, dri.dri_Pens[SHADOWPEN]); XDrawLine(dpy, strwin, gc, 1, strgadh-1, strgadw-1, strgadh-1); XDrawLine(dpy, strwin, gc, strgadw-1, strgadh-1, strgadw-1, 0); XDrawLine(dpy, strwin, gc, 3, strgadh-3, 3, 1); XDrawLine(dpy, strwin, gc, 3, 1, strgadw-4, 1); XDrawLine(dpy, strwin, gc, 2, 1, 2, strgadh-2); XDrawLine(dpy, strwin, gc, strgadw-2, 1, strgadw-2, strgadh-2); } void strkey(XKeyEvent *e) { void endchoice(void); #ifdef USE_FONTSETS Status stat; #else static XComposeStatus stat; #endif KeySym ks; char buf[256]; int x, i, n; #ifndef USE_FONTSETS n=XLookupString(e, buf, sizeof(buf), &ks, &stat); #else n=XmbLookupString(xic, e, buf, sizeof(buf), &ks, &stat); if(stat == XLookupKeySym || stat == XLookupBoth) #endif switch(ks) { case XK_Return: case XK_Linefeed: selected=1; endchoice(); break; case XK_Left: if(cur_pos) { #ifdef USE_FONTSETS int p=cur_pos; // int z; while(p>0) { --p; if(((int)mbrlen(cmdline+p, cur_pos-p, NULL))>0) { cur_pos=p; break; } } #else --cur_pos; #endif } break; case XK_Right: if(cur_pos0) cur_pos+=l; #else cur_pos++; #endif } break; case XK_Begin: cur_pos=0; break; case XK_End: cur_pos=buf_len; break; case XK_Delete: if(cur_pos0) { int l=1; #ifdef USE_FONTSETS int p=cur_pos; while(p>0) { --p; if(((int)mbrlen(cmdline+p, cur_pos-p, NULL))>0) { l=cur_pos-p; break; } } #endif buf_len-=l; for(x=(cur_pos-=l); xcur_pos; --x) cmdline[x]=cmdline[x-1]; cmdline[cur_pos++]=buf[i]; buf_len++; } if(ileft_pos) cur_x+=XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, cur_pos-left_pos); if(cur_posmax_logical_extent.width; #else if(cur_pos>left_pos) cur_x+=XTextWidth(dri.dri_Font, cmdline+left_pos, cur_pos-left_pos); if(cur_posmax_bounds.width; #endif if((x+=cur_x-(strgadw-6))>0) { cur_x-=x; while(x>0) { #ifdef USE_FONTSETS int l=mbrlen(cmdline+left_pos, buf_len-left_pos, NULL); x-=XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, l); left_pos += l; #else x-=XTextWidth(dri.dri_Font, cmdline+left_pos++, 1); #endif } cur_x+=x; } refresh_str_text(); } void strbutton(XButtonEvent *e) { int w, l=1; stractive=1; cur_pos=left_pos; cur_x=6; while(cur_xx && cur_pose->x) break; cur_x+=w; cur_pos+=l; } refresh_str(); } void toggle(int c) { XSetWindowBackground(dpy, button[c], dri.dri_Pens[(depressed&&c==selected)? FILLPEN:BACKGROUNDPEN]); XClearWindow(dpy, button[c]); refresh_button(button[c], buttxt[c], c); } void abortchoice() { if(depressed) { depressed=0; toggle(selected); } selected=0; } void endchoice() { int c=selected; abortchoice(); XCloseDisplay(dpy); if(c==1) system(cmdline); exit(0); } int main(int argc, char *argv[]) { XWindowAttributes attr; static XSizeHints size_hints; static XTextProperty txtprop1, txtprop2; Window ok, cancel; int w2, c; #ifdef USE_FONTSETS char *p; setlocale(LC_CTYPE, ""); #endif progname=argv[0]; if(!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "%s: cannot connect to X server %s\n", progname, XDisplayName(NULL)); exit(1); } root = RootWindow(dpy, DefaultScreen(dpy)); XGetWindowAttributes(dpy, root, &attr); init_dri(&dri, dpy, root, attr.colormap, False); #ifdef USE_FONTSETS strgadw=VISIBLE_CMD_CHARS*XExtentsOfFontSet(dri.dri_FontSet)-> max_logical_extent.width+12; #else strgadw=VISIBLE_CMD_CHARS*dri.dri_Font->max_bounds.width+12; #endif strgadh=(fh=dri.dri_Ascent+dri.dri_Descent)+6; #ifdef USE_FONTSETS butw=XmbTextEscapement(dri.dri_FontSet, ok_txt, strlen(ok_txt))+2*BUT_HSPACE; w2=XmbTextEscapement(dri.dri_FontSet, cancel_txt, strlen(cancel_txt))+2*BUT_HSPACE; #else butw=XTextWidth(dri.dri_Font, ok_txt, strlen(ok_txt))+2*BUT_HSPACE; w2=XTextWidth(dri.dri_Font, cancel_txt, strlen(cancel_txt))+2*BUT_HSPACE; #endif if(w2>butw) butw=w2; mainw=2*(BUT_SIDE+butw)+BUT_SIDE; #ifdef USE_FONTSETS w2=XmbTextEscapement(dri.dri_FontSet, enter_txt, strlen(enter_txt))+2*TEXT_SIDE; #else w2=XTextWidth(dri.dri_Font, enter_txt, strlen(enter_txt))+2*TEXT_SIDE; #endif if(w2>mainw) mainw=w2; #ifdef USE_FONTSETS w2=strgadw+XmbTextEscapement(dri.dri_FontSet, cmd_txt, strlen(cmd_txt))+ 2*TEXT_SIDE+2*BUT_SIDE+butw; #else w2=strgadw+XTextWidth(dri.dri_Font, cmd_txt, strlen(cmd_txt))+ 2*TEXT_SIDE+2*BUT_SIDE+butw; #endif if(w2>mainw) mainw=w2; mainh=3*fh+TOP_SPACE+BOT_SPACE+2*INT_SPACE+2*BUT_VSPACE; mainwin=XCreateSimpleWindow(dpy, root, 20, 20, mainw, mainh, 1, dri.dri_Pens[SHADOWPEN], dri.dri_Pens[BACKGROUNDPEN]); strwin=XCreateSimpleWindow(dpy, mainwin, mainw-BUT_SIDE-strgadw, TOP_SPACE+fh+INT_SPACE-3, strgadw, strgadh, 0, dri.dri_Pens[SHADOWPEN], dri.dri_Pens[BACKGROUNDPEN]); ok=XCreateSimpleWindow(dpy, mainwin, BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, butw, fh+2*BUT_VSPACE, 0, dri.dri_Pens[SHADOWPEN], dri.dri_Pens[BACKGROUNDPEN]); cancel=XCreateSimpleWindow(dpy, mainwin, mainw-butw-BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, butw, fh+2*BUT_VSPACE, 0, dri.dri_Pens[SHADOWPEN], dri.dri_Pens[BACKGROUNDPEN]); button[0]=None; button[1]=ok; button[2]=cancel; XSelectInput(dpy, mainwin, ExposureMask|KeyPressMask|ButtonPressMask); XSelectInput(dpy, strwin, ExposureMask|ButtonPressMask); XSelectInput(dpy, ok, ExposureMask|ButtonPressMask|ButtonReleaseMask| EnterWindowMask|LeaveWindowMask); XSelectInput(dpy, cancel, ExposureMask|ButtonPressMask|ButtonReleaseMask| EnterWindowMask|LeaveWindowMask); gc=XCreateGC(dpy, mainwin, 0, NULL); XSetBackground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); #ifndef USE_FONTSETS XSetFont(dpy, gc, dri.dri_Font->fid); #endif #ifdef USE_FONTSETS if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) xim = XOpenIM(dpy, NULL, NULL, NULL); if (!xim) fprintf(stderr, "Failed to open input method.\n"); else { xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, mainwin, XNFocusWindow, mainwin, NULL); if (!xic) fprintf(stderr, "Failed to create input context.\n"); } if (!xic) exit(1); #endif size_hints.flags = PResizeInc; txtprop1.value=(unsigned char *)"Execute a File"; txtprop2.value=(unsigned char *)"ExecuteCmd"; txtprop2.encoding=txtprop1.encoding=XA_STRING; txtprop2.format=txtprop1.format=8; txtprop1.nitems=strlen((char *)txtprop1.value); txtprop2.nitems=strlen((char *)txtprop2.value); XSetWMProperties(dpy, mainwin, &txtprop1, &txtprop2, argv, argc, &size_hints, NULL, NULL); XMapSubwindows(dpy, mainwin); XMapRaised(dpy, mainwin); for(;;) { XEvent event; XNextEvent(dpy, &event); #ifdef USE_FONTSETS if(!XFilterEvent(&event, mainwin)) #endif switch(event.type) { case Expose: if(!event.xexpose.count) { if(event.xexpose.window == mainwin) refresh_main(); else if(event.xexpose.window == strwin) refresh_str(); else if(event.xexpose.window == ok) refresh_button(ok, ok_txt, 1); else if(event.xexpose.window == cancel) refresh_button(cancel, cancel_txt, 2); } case LeaveNotify: if(depressed && event.xcrossing.window==button[selected]) { depressed=0; toggle(selected); } break; case EnterNotify: if((!depressed) && selected && event.xcrossing.window==button[selected]) { depressed=1; toggle(selected); } break; case ButtonPress: if(event.xbutton.button==Button1) { if(stractive && event.xbutton.window!=strwin) { stractive=0; refresh_str(); } if((c=getchoice(event.xbutton.window))) { abortchoice(); depressed=1; toggle(selected=c); } else if(event.xbutton.window==strwin) strbutton(&event.xbutton); } break; case ButtonRelease: if(event.xbutton.button==Button1 && selected) { if(depressed) endchoice(); else abortchoice(); } break; case KeyPress: if(stractive) strkey(&event.xkey); } } }