Files
amiwm-neo/executecmd.c
Adrian Chadd 48f15595a4 [executecmd] migrate executecmd to use the gadgets in libami
This removes the gadget specific code in executecmd and calls
the routines I've added in libami.
2022-04-09 17:34:43 -07:00

346 lines
8.4 KiB
C

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <errno.h>
#ifdef USE_FONTSETS
#include <locale.h>
#include <wchar.h>
#endif
#include "drawinfo.h"
#include "gadget_button.h"
#include "gadget_textinput.h"
#ifdef AMIGAOS
#include <pragmas/xlib_pragmas.h>
extern struct Library *XLibBase;
#endif
#define MAX_CMD_CHARS 256
#define VISIBLE_CMD_CHARS 35
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;
struct gadget_button *buttons[3];
struct gadget_textinput *text_input;
char *progname;
Display *dpy;
struct DrawInfo dri;
Window root, mainwin;
GC gc;
int strgadw, strgadh;
int fh;
int mainw, mainh, butw;
#ifdef USE_FONTSETS
static XIM xim = (XIM) NULL;
static XIC xic = (XIC) NULL;
#endif
/*
* Loop through the button list and see if we find
* a button. Return 0 if we don't find a button.
*
* Yeah, ideally we'd do this in some gadget / intuition
* UI layer thing, but we're not there yet.
*/
static int
getchoice(Window w)
{
int i;
for (i=1; i<3; i++) {
if (buttons[i]->w == w)
return i;
}
return 0;
}
static 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
}
static void
toggle(int c)
{
if (c == 0)
return;
gadget_button_toggle(buttons[c]);
}
static void
abortchoice(void)
{
if(depressed) {
depressed=0;
if (selected > 0) {
gadget_button_set_depressed(buttons[selected], 0);
}
toggle(selected);
}
selected = 0;
}
static void
endchoice(void)
{
int c=selected;
abortchoice();
XCloseDisplay(dpy);
if(c==1) {
system(text_input->buf);
}
exit(0);
}
int
main(int argc, char *argv[])
{
XWindowAttributes attr;
static XSizeHints size_hints;
static XTextProperty txtprop1, txtprop2;
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;
#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
/* Main window */
mainwin=XCreateSimpleWindow(dpy, root, 20, 20, mainw, mainh, 1,
dri.dri_Pens[SHADOWPEN],
dri.dri_Pens[BACKGROUNDPEN]);
gc=XCreateGC(dpy, mainwin, 0, NULL);
XSetBackground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]);
#ifndef USE_FONTSETS
XSetFont(dpy, gc, dri.dri_Font->fid);
#endif
/* Text input window */
text_input = gadget_textinput_create(dpy, &dri, gc, mainwin,
mainw-BUT_SIDE-strgadw,
TOP_SPACE+fh+INT_SPACE-3,
strgadw, strgadh, 256);
#ifdef USE_FONTSETS
gadget_textinput_set_xic(text_input, xic);
#endif
/* Create OK button */
buttons[1] = gadget_button_init(dpy, &dri, gc, mainwin,
BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, /* x, y */
butw, fh+2*BUT_VSPACE); /* width, height */
gadget_button_set_text(buttons[1], ok_txt);
/* Create cancel button */
buttons[2] = gadget_button_init(dpy, &dri, gc, mainwin,
mainw-butw-BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, /* x, y */
butw, fh+2*BUT_VSPACE); /* width, height */
gadget_button_set_text(buttons[2], cancel_txt);
XSelectInput(dpy, mainwin, ExposureMask|KeyPressMask|ButtonPressMask);
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 == text_input->w)
gadget_textinput_repaint(text_input);
else if(event.xexpose.window == buttons[1]->w) {
gadget_button_refresh(buttons[1]);
} else if(event.xexpose.window == buttons[2]->w) {
gadget_button_refresh(buttons[2]);
}
}
case LeaveNotify:
if (depressed) {
if ((selected > 0) && event.xcrossing.window == buttons[selected]->w) {
depressed = 0;
gadget_button_set_depressed(buttons[selected], 0);
toggle(selected);
}
}
break;
case EnterNotify:
if((!depressed) && selected && event.xcrossing.window == buttons[selected]->w) {
depressed = 1;
gadget_button_set_depressed(buttons[selected], 1);
toggle(selected);
}
break;
case ButtonPress:
if(event.xbutton.button==Button1) {
if(stractive && event.xbutton.window!= text_input->w) {
stractive=0;
gadget_textinput_selected(text_input, 0);
gadget_textinput_repaint(text_input);
}
if((c=getchoice(event.xbutton.window))) {
abortchoice();
depressed = 1;
selected = c;
if (selected > 0) {
gadget_button_set_depressed(buttons[selected], 1);
}
toggle(selected);
} else if(event.xbutton.window== text_input->w) {
gadget_textinput_selected(text_input, 1);
gadget_textinput_buttonevent(text_input, &event.xbutton);
gadget_textinput_repaint(text_input);
}
}
break;
case ButtonRelease:
if(event.xbutton.button==Button1 && selected) {
if(depressed)
endchoice();
else
abortchoice();
}
break;
case KeyPress:
if(stractive) {
gadget_textinput_keyevent(text_input, &event.xkey);
gadget_textinput_repaint(text_input);
if (gadget_textinput_crlf(text_input)) {
selected = 1;
endchoice();
exit(1);
}
}
}
}
}