mirror of
https://github.com/amiwm/amiwm.git
synced 2026-04-14 11:04:18 +00:00
Merge pull request #4 from erikarn/ahc_20220409_gadgets
Ahc 20220409 gadgets
This commit is contained in:
580
executecmd.c
580
executecmd.c
@@ -21,6 +21,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "drawinfo.h"
|
#include "drawinfo.h"
|
||||||
|
#include "gadget_button.h"
|
||||||
|
#include "gadget_textinput.h"
|
||||||
|
|
||||||
#ifdef AMIGAOS
|
#ifdef AMIGAOS
|
||||||
#include <pragmas/xlib_pragmas.h>
|
#include <pragmas/xlib_pragmas.h>
|
||||||
@@ -30,27 +32,14 @@ extern struct Library *XLibBase;
|
|||||||
#define MAX_CMD_CHARS 256
|
#define MAX_CMD_CHARS 256
|
||||||
#define VISIBLE_CMD_CHARS 35
|
#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 ok_txt[]="Ok", cancel_txt[]="Cancel";
|
||||||
static const char enter_txt[]="Enter Command and its Arguments:";
|
static const char enter_txt[]="Enter Command and its Arguments:";
|
||||||
static const char cmd_txt[]="Command:";
|
static const char cmd_txt[]="Command:";
|
||||||
|
|
||||||
static int selected=0, depressed=0, stractive=1;
|
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];
|
struct gadget_button *buttons[3];
|
||||||
int buf_len=0;
|
struct gadget_textinput *text_input;
|
||||||
int cur_pos=0;
|
|
||||||
int left_pos=0;
|
|
||||||
int cur_x=6;
|
|
||||||
|
|
||||||
char *progname;
|
char *progname;
|
||||||
|
|
||||||
@@ -58,368 +47,121 @@ Display *dpy;
|
|||||||
|
|
||||||
struct DrawInfo dri;
|
struct DrawInfo dri;
|
||||||
|
|
||||||
Window root, mainwin, strwin;
|
Window root, mainwin;
|
||||||
GC gc;
|
GC gc;
|
||||||
|
|
||||||
int strgadw, strgadh, fh, mainw, mainh, butw;
|
int strgadw, strgadh;
|
||||||
|
|
||||||
|
int fh;
|
||||||
|
int mainw, mainh, butw;
|
||||||
|
|
||||||
#ifdef USE_FONTSETS
|
#ifdef USE_FONTSETS
|
||||||
static XIM xim = (XIM) NULL;
|
static XIM xim = (XIM) NULL;
|
||||||
static XIC xic = (XIC) NULL;
|
static XIC xic = (XIC) NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int getchoice(Window w)
|
/*
|
||||||
|
* 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;
|
int i;
|
||||||
for(i=1; i<3; i++)
|
for (i=1; i<3; i++) {
|
||||||
if(button[i]==w)
|
if (buttons[i]->w == w)
|
||||||
return i;
|
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; l<buf_len-left_pos; ) {
|
|
||||||
c=mbrlen(cmdline+left_pos+l, buf_len-left_pos-l, NULL);
|
|
||||||
w=6+XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, l+c);
|
|
||||||
if(w>strgadw-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<buf_len) {
|
|
||||||
XSetBackground(dpy, gc, ~0);
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL);
|
|
||||||
XmbDrawImageString(dpy, strwin, dri.dri_FontSet, gc, cur_x,
|
|
||||||
3+dri.dri_Ascent, cmdline+cur_pos, l);
|
|
||||||
#else
|
|
||||||
XDrawImageString(dpy, strwin, gc, cur_x, 3+dri.dri_Ascent,
|
|
||||||
cmdline+cur_pos, 1);
|
|
||||||
#endif
|
|
||||||
XSetBackground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]);
|
|
||||||
} else {
|
|
||||||
XSetForeground(dpy, gc, ~0);
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
XFillRectangle(dpy, strwin, gc, cur_x, 3,
|
|
||||||
XExtentsOfFontSet(dri.dri_FontSet)->
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
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
|
#else
|
||||||
--cur_pos;
|
XDrawString(dpy, mainwin, gc, TEXT_SIDE, TOP_SPACE+dri.dri_Ascent,
|
||||||
|
enter_txt, strlen(enter_txt));
|
||||||
#endif
|
#endif
|
||||||
}
|
XSetForeground(dpy, gc, dri.dri_Pens[HIGHLIGHTTEXTPEN]);
|
||||||
break;
|
|
||||||
case XK_Right:
|
|
||||||
if(cur_pos<buf_len) {
|
|
||||||
#ifdef USE_FONTSETS
|
#ifdef USE_FONTSETS
|
||||||
int l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL);
|
w = XmbTextEscapement(dri.dri_FontSet, cmd_txt, strlen(cmd_txt));
|
||||||
if(l>0)
|
XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc,
|
||||||
cur_pos+=l;
|
mainw-strgadw-w-TEXT_SIDE-BUT_SIDE,
|
||||||
|
TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent,
|
||||||
|
cmd_txt, strlen(cmd_txt));
|
||||||
#else
|
#else
|
||||||
cur_pos++;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case XK_Begin:
|
static void
|
||||||
cur_pos=0;
|
toggle(int c)
|
||||||
break;
|
{
|
||||||
case XK_End:
|
if (c == 0)
|
||||||
cur_pos=buf_len;
|
return;
|
||||||
break;
|
gadget_button_toggle(buttons[c]);
|
||||||
case XK_Delete:
|
}
|
||||||
if(cur_pos<buf_len) {
|
|
||||||
int l=1;
|
static void
|
||||||
#ifdef USE_FONTSETS
|
abortchoice(void)
|
||||||
l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL);
|
{
|
||||||
if(l<=0)
|
if(depressed) {
|
||||||
break;
|
depressed=0;
|
||||||
#endif
|
if (selected > 0) {
|
||||||
buf_len-=l;
|
gadget_button_set_depressed(buttons[selected], 0);
|
||||||
for(x=cur_pos; x<buf_len; x++)
|
}
|
||||||
cmdline[x]=cmdline[x+l];
|
toggle(selected);
|
||||||
cmdline[x] = 0;
|
|
||||||
} else XBell(dpy, 100);
|
|
||||||
break;
|
|
||||||
case XK_BackSpace:
|
|
||||||
if(cur_pos>0) {
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
selected = 0;
|
||||||
#endif
|
|
||||||
buf_len-=l;
|
|
||||||
for(x=(cur_pos-=l); x<buf_len; x++)
|
|
||||||
cmdline[x]=cmdline[x+l];
|
|
||||||
cmdline[x] = 0;
|
|
||||||
} else XBell(dpy, 100);
|
|
||||||
break;
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
default:
|
|
||||||
if(stat == XLookupBoth)
|
|
||||||
stat = XLookupChars;
|
|
||||||
}
|
|
||||||
if(stat == XLookupChars) {
|
|
||||||
#else
|
|
||||||
default:
|
|
||||||
#endif
|
|
||||||
for(i=0; i<n && buf_len<MAX_CMD_CHARS; i++) {
|
|
||||||
for(x=buf_len; x>cur_pos; --x)
|
|
||||||
cmdline[x]=cmdline[x-1];
|
|
||||||
cmdline[cur_pos++]=buf[i];
|
|
||||||
buf_len++;
|
|
||||||
}
|
|
||||||
if(i<n)
|
|
||||||
XBell(dpy, 100);
|
|
||||||
}
|
|
||||||
if(cur_pos<left_pos)
|
|
||||||
left_pos=cur_pos;
|
|
||||||
cur_x=6;
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
if(cur_pos>left_pos)
|
|
||||||
cur_x+=XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, cur_pos-left_pos);
|
|
||||||
if(cur_pos<buf_len) {
|
|
||||||
int l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL);
|
|
||||||
x=XmbTextEscapement(dri.dri_FontSet, cmdline+cur_pos, l);
|
|
||||||
} else
|
|
||||||
x=XExtentsOfFontSet(dri.dri_FontSet)->max_logical_extent.width;
|
|
||||||
#else
|
|
||||||
if(cur_pos>left_pos)
|
|
||||||
cur_x+=XTextWidth(dri.dri_Font, cmdline+left_pos, cur_pos-left_pos);
|
|
||||||
if(cur_pos<buf_len)
|
|
||||||
x=XTextWidth(dri.dri_Font, cmdline+cur_pos, 1);
|
|
||||||
else
|
|
||||||
x=dri.dri_Font->max_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)
|
static void
|
||||||
|
endchoice(void)
|
||||||
{
|
{
|
||||||
int w, l=1;
|
int c=selected;
|
||||||
stractive=1;
|
|
||||||
cur_pos=left_pos;
|
abortchoice();
|
||||||
cur_x=6;
|
XCloseDisplay(dpy);
|
||||||
while(cur_x<e->x && cur_pos<buf_len) {
|
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
|
#ifdef USE_FONTSETS
|
||||||
l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL);
|
char *p;
|
||||||
if(l<=0)
|
|
||||||
break;
|
setlocale(LC_CTYPE, "");
|
||||||
w=XmbTextEscapement(dri.dri_FontSet, cmdline+cur_pos, l);
|
|
||||||
#else
|
|
||||||
w=XTextWidth(dri.dri_Font, cmdline+cur_pos, 1);
|
|
||||||
#endif
|
#endif
|
||||||
if(cur_x+w>e->x)
|
progname=argv[0];
|
||||||
break;
|
if(!(dpy = XOpenDisplay(NULL))) {
|
||||||
cur_x+=w;
|
fprintf(stderr, "%s: cannot connect to X server %s\n",
|
||||||
cur_pos+=l;
|
progname, XDisplayName(NULL));
|
||||||
}
|
exit(1);
|
||||||
refresh_str();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void toggle(int c)
|
root = RootWindow(dpy, DefaultScreen(dpy));
|
||||||
{
|
XGetWindowAttributes(dpy, root, &attr);
|
||||||
XSetWindowBackground(dpy, button[c], dri.dri_Pens[(depressed&&c==selected)?
|
init_dri(&dri, dpy, root, attr.colormap, False);
|
||||||
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
|
#ifdef USE_FONTSETS
|
||||||
strgadw=VISIBLE_CMD_CHARS*XExtentsOfFontSet(dri.dri_FontSet)->
|
strgadw=VISIBLE_CMD_CHARS*XExtentsOfFontSet(dri.dri_FontSet)->
|
||||||
@@ -458,39 +200,6 @@ int main(int argc, char *argv[])
|
|||||||
mainw=w2;
|
mainw=w2;
|
||||||
|
|
||||||
mainh=3*fh+TOP_SPACE+BOT_SPACE+2*INT_SPACE+2*BUT_VSPACE;
|
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
|
#ifdef USE_FONTSETS
|
||||||
if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p)
|
if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p)
|
||||||
@@ -510,6 +219,40 @@ int main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
#endif
|
#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;
|
size_hints.flags = PResizeInc;
|
||||||
txtprop1.value=(unsigned char *)"Execute a File";
|
txtprop1.value=(unsigned char *)"Execute a File";
|
||||||
txtprop2.value=(unsigned char *)"ExecuteCmd";
|
txtprop2.value=(unsigned char *)"ExecuteCmd";
|
||||||
@@ -532,37 +275,51 @@ int main(int argc, char *argv[])
|
|||||||
if(!event.xexpose.count) {
|
if(!event.xexpose.count) {
|
||||||
if(event.xexpose.window == mainwin)
|
if(event.xexpose.window == mainwin)
|
||||||
refresh_main();
|
refresh_main();
|
||||||
else if(event.xexpose.window == strwin)
|
else if(event.xexpose.window == text_input->w)
|
||||||
refresh_str();
|
gadget_textinput_repaint(text_input);
|
||||||
else if(event.xexpose.window == ok)
|
else if(event.xexpose.window == buttons[1]->w) {
|
||||||
refresh_button(ok, ok_txt, 1);
|
gadget_button_refresh(buttons[1]);
|
||||||
else if(event.xexpose.window == cancel)
|
} else if(event.xexpose.window == buttons[2]->w) {
|
||||||
refresh_button(cancel, cancel_txt, 2);
|
gadget_button_refresh(buttons[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
if(depressed && event.xcrossing.window==button[selected]) {
|
if (depressed) {
|
||||||
depressed=0;
|
if ((selected > 0) && event.xcrossing.window == buttons[selected]->w) {
|
||||||
toggle(selected);
|
depressed = 0;
|
||||||
|
gadget_button_set_depressed(buttons[selected], 0);
|
||||||
|
toggle(selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
if((!depressed) && selected && event.xcrossing.window==button[selected]) {
|
if((!depressed) && selected && event.xcrossing.window == buttons[selected]->w) {
|
||||||
depressed=1;
|
depressed = 1;
|
||||||
toggle(selected);
|
gadget_button_set_depressed(buttons[selected], 1);
|
||||||
|
toggle(selected);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
if(event.xbutton.button==Button1) {
|
if(event.xbutton.button==Button1) {
|
||||||
if(stractive && event.xbutton.window!=strwin) {
|
if(stractive && event.xbutton.window!= text_input->w) {
|
||||||
stractive=0;
|
stractive=0;
|
||||||
refresh_str();
|
gadget_textinput_selected(text_input, 0);
|
||||||
|
gadget_textinput_repaint(text_input);
|
||||||
}
|
}
|
||||||
if((c=getchoice(event.xbutton.window))) {
|
if((c=getchoice(event.xbutton.window))) {
|
||||||
abortchoice();
|
abortchoice();
|
||||||
depressed=1;
|
depressed = 1;
|
||||||
toggle(selected=c);
|
selected = c;
|
||||||
} else if(event.xbutton.window==strwin)
|
if (selected > 0) {
|
||||||
strbutton(&event.xbutton);
|
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;
|
break;
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
@@ -574,8 +331,15 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
if(stractive)
|
if(stractive) {
|
||||||
strkey(&event.xkey);
|
gadget_textinput_keyevent(text_input, &event.xkey);
|
||||||
|
gadget_textinput_repaint(text_input);
|
||||||
|
if (gadget_textinput_crlf(text_input)) {
|
||||||
|
selected = 1;
|
||||||
|
endchoice();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ RM = -rm -f
|
|||||||
OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \
|
OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \
|
||||||
mdicon.o mdwindow.o kbdsupport.o hotkey.o \
|
mdicon.o mdwindow.o kbdsupport.o hotkey.o \
|
||||||
lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \
|
lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \
|
||||||
iffparse.o
|
iffparse.o gadget_button.o gadget_textbox.o gadget_textinput.o
|
||||||
|
|
||||||
SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \
|
SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \
|
||||||
mdicon.c mdwindow.c kbdsupport.c hotkey.c \
|
mdicon.c mdwindow.c kbdsupport.c hotkey.c \
|
||||||
lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \
|
lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \
|
||||||
iffparse.c
|
iffparse.c gadget_button.c gadget_textbox.c gadget_textinput.c
|
||||||
|
|
||||||
all : libami.a
|
all : libami.a
|
||||||
|
|
||||||
|
|||||||
136
libami/gadget_button.c
Normal file
136
libami/gadget_button.c
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
#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"
|
||||||
|
|
||||||
|
#ifdef AMIGAOS
|
||||||
|
#include <pragmas/xlib_pragmas.h>
|
||||||
|
extern struct Library *XLibBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the button code from the executecmd.c tool.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct gadget_button *
|
||||||
|
gadget_button_init(Display *dpy, struct DrawInfo *dri, GC gc, Window mainwin,
|
||||||
|
int x, int y, int butw, int buth)
|
||||||
|
{
|
||||||
|
struct gadget_button *b;
|
||||||
|
|
||||||
|
b = calloc(1, sizeof(*b));
|
||||||
|
if (b == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
b->dpy = dpy;
|
||||||
|
b->dri = dri;
|
||||||
|
b->x = x;
|
||||||
|
b->y = y;
|
||||||
|
b->butw = butw;
|
||||||
|
b->buth = buth;
|
||||||
|
b->txt = strdup("");
|
||||||
|
b->gc = gc;
|
||||||
|
|
||||||
|
b->w = XCreateSimpleWindow(dpy, mainwin,
|
||||||
|
x, y,
|
||||||
|
butw, /* width */
|
||||||
|
buth, /* height */
|
||||||
|
0, /* depth */
|
||||||
|
dri->dri_Pens[SHADOWPEN],
|
||||||
|
dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
|
||||||
|
XSelectInput(dpy, b->w, ExposureMask | ButtonPressMask
|
||||||
|
| ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);
|
||||||
|
|
||||||
|
return (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_button_set_text(struct gadget_button *b, const char *txt)
|
||||||
|
{
|
||||||
|
if (b->txt != NULL)
|
||||||
|
free(b->txt);
|
||||||
|
b->txt = strdup(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_button_refresh(struct gadget_button *b)
|
||||||
|
{
|
||||||
|
int fh = b->dri->dri_Ascent + b->dri->dri_Descent;
|
||||||
|
int h = fh + (2 * BUT_VSPACE);
|
||||||
|
int l=strlen(b->txt);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int tw = XmbTextEscapement(b->dri->dri_FontSet, b->txt, l);
|
||||||
|
#else
|
||||||
|
int tw = XTextWidth(b->dri->dri_Font, b->txt, l);
|
||||||
|
#endif
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[TEXTPEN]);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
XmbDrawString(b->dpy, b->w, b->dri->dri_FontSet, b->gc,
|
||||||
|
(b->butw-tw)>>1, b->dri->dri_Ascent+BUT_VSPACE, b->txt, l);
|
||||||
|
#else
|
||||||
|
XDrawString(b->dpy, b->w, b->gc, (b->butw-tw)>>1,
|
||||||
|
b->dri->dri_Ascent+BUT_VSPACE, b->txt, l);
|
||||||
|
#endif
|
||||||
|
XSetForeground(b->dpy, b->gc,
|
||||||
|
b->dri->dri_Pens[b->depressed ? SHADOWPEN:SHINEPEN]);
|
||||||
|
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 0, 0, b->butw-2, 0);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 0, 0, 0, h-2);
|
||||||
|
XSetForeground(b->dpy, b->gc,
|
||||||
|
b->dri->dri_Pens[b->depressed ? SHINEPEN:SHADOWPEN]);
|
||||||
|
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 1, h-1, b->butw-1, h-1);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, b->butw-1, 1, b->butw-1, h-1);
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
XDrawPoint(b->dpy, b->w, b->gc, b->butw-1, 0);
|
||||||
|
XDrawPoint(b->dpy, b->w, b->gc, 0, h-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_button_set_depressed(struct gadget_button *b, int depressed)
|
||||||
|
{
|
||||||
|
b->depressed = depressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_button_toggle(struct gadget_button *b)
|
||||||
|
{
|
||||||
|
int pen;
|
||||||
|
|
||||||
|
pen = (b->depressed) ? FILLPEN : BACKGROUNDPEN;
|
||||||
|
|
||||||
|
|
||||||
|
XSetWindowBackground(b->dpy, b->w, b->dri->dri_Pens[pen]);
|
||||||
|
XClearWindow(b->dpy, b->w);
|
||||||
|
gadget_button_refresh(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_button_free(struct gadget_button *b)
|
||||||
|
{
|
||||||
|
XDestroyWindow(b->dpy, b->w);
|
||||||
|
free(b->txt);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
35
libami/gadget_button.h
Normal file
35
libami/gadget_button.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __LIBAMI__GADGET_BUTTON_H__
|
||||||
|
#define __LIBAMI__GADGET_BUTTON_H__
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
struct gadget_button {
|
||||||
|
Display *dpy;
|
||||||
|
struct DrawInfo *dri;
|
||||||
|
Window w;
|
||||||
|
GC gc;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int buth;
|
||||||
|
int butw;
|
||||||
|
char *txt;
|
||||||
|
int depressed;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct gadget_button * gadget_button_init(Display *dpy,
|
||||||
|
struct DrawInfo *dri, GC gc, Window mainwin,
|
||||||
|
int x, int y, int butw, int buth);
|
||||||
|
extern void gadget_button_set_text(struct gadget_button *b, const char *txt);
|
||||||
|
extern void gadget_button_refresh(struct gadget_button *b);
|
||||||
|
extern void gadget_button_set_depressed(struct gadget_button *b,
|
||||||
|
int depressed);
|
||||||
|
extern void gadget_button_toggle(struct gadget_button *b);
|
||||||
|
extern void gadget_button_free(struct gadget_button *b);
|
||||||
|
|
||||||
|
#endif /* __LIBAMI__GADGET_BUTTON_H__ */
|
||||||
123
libami/gadget_textbox.c
Normal file
123
libami/gadget_textbox.c
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "drawinfo.h"
|
||||||
|
#include "libami.h"
|
||||||
|
|
||||||
|
#ifdef AMIGAOS
|
||||||
|
#include <pragmas/xlib_pragmas.h>
|
||||||
|
extern struct Library *XLibBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "gadget_textbox.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct gadget_textbox_line {
|
||||||
|
struct line *next;
|
||||||
|
const char *text;
|
||||||
|
int l, w, h;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct gadget_textbox {
|
||||||
|
struct gadget_textbox_line *firstline, *lastline;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct gadget_textbox *
|
||||||
|
gadget_textbox_create(Display *dpy, struct DrawInfo *dri, GC gc,
|
||||||
|
Window mainwin, int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
struct gadget_textbox *g;
|
||||||
|
|
||||||
|
g = calloc(1, sizeof(*g));
|
||||||
|
if (g == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
g->dpy = dpy;
|
||||||
|
g->dri = dri;
|
||||||
|
g->gc = gc;
|
||||||
|
g->x = x;
|
||||||
|
g->y = y;
|
||||||
|
g->width = width;
|
||||||
|
g->height = height;
|
||||||
|
|
||||||
|
g->w = XCreateSimpleWindow(g->dpy, mainwin,
|
||||||
|
g->x, g->y,
|
||||||
|
g->width, g->height,
|
||||||
|
0,
|
||||||
|
g->dri->dri_Pens[SHADOWPEN],
|
||||||
|
g->dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
XSelectInput(g->dpy, g->w, ExposureMask);
|
||||||
|
|
||||||
|
return (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textbox_free(struct gadget_textbox *g)
|
||||||
|
{
|
||||||
|
/* XXX TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gadget_textbox_line *
|
||||||
|
gadget_textbox_addline(struct gadget_textbox *g, const char *text)
|
||||||
|
{
|
||||||
|
struct gadget_textbox_line *l;
|
||||||
|
|
||||||
|
l = calloc(1, sizeof(*l));
|
||||||
|
if (l == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
if(g->lastline)
|
||||||
|
g->lastline->next = l;
|
||||||
|
else
|
||||||
|
g->firstline = l;
|
||||||
|
g->lastline = l;
|
||||||
|
l->text = strdup(text);
|
||||||
|
l->l = strlen(text);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
l->w = XmbTextEscapement(g->dri->dri_FontSet, l->text, l->l);
|
||||||
|
#else
|
||||||
|
l->w = XTextWidth(g->dri->dri_Font, l->text, l->l);
|
||||||
|
#endif
|
||||||
|
l->h = g->dri->dri_Ascent + g->dri->dri_Descent;
|
||||||
|
|
||||||
|
return (l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textbox_refresh(struct gadget_textbox *g)
|
||||||
|
{
|
||||||
|
// This is OBVIOUSLY the wrong value for x here, but let's get it going
|
||||||
|
int x = TXT_HSPACE / 2;
|
||||||
|
int y = ((g->dri->dri_Ascent+g->dri->dri_Descent)>>1)+g->dri->dri_Ascent;
|
||||||
|
|
||||||
|
struct gadget_textbox_line *l;
|
||||||
|
|
||||||
|
/* Draw the bounding box */
|
||||||
|
XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[SHADOWPEN]);
|
||||||
|
XDrawLine(g->dpy, g->w, g->gc, 0, 0, g->width-2, 0);
|
||||||
|
XDrawLine(g->dpy, g->w, g->gc, 0, 0, 0, g->height-2);
|
||||||
|
|
||||||
|
XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[SHINEPEN]);
|
||||||
|
XDrawLine(g->dpy, g->w, g->gc, 0, g->height-1, g->width-1, g->height-1);
|
||||||
|
XDrawLine(g->dpy, g->w, g->gc, g->width-1, 0, g->width-1, g->height-1);
|
||||||
|
|
||||||
|
/* Draw text lines */
|
||||||
|
XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[TEXTPEN]);
|
||||||
|
for(l = g->firstline; l; l=l->next) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
XmbDrawString(g->dpy, g->w, g->dri->dri_FontSet, g->gc,
|
||||||
|
x, y, l->text, l->l);
|
||||||
|
#else
|
||||||
|
XDrawString(g->dpy, g->w, g->gc, x, y, l->text, l->l);
|
||||||
|
#endif
|
||||||
|
y+=g->dri->dri_Ascent + g->dri->dri_Descent;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
libami/gadget_textbox.h
Normal file
35
libami/gadget_textbox.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef __LIBAMI_GADGET_TEXTBOX_H__
|
||||||
|
#define __LIBAMI_GADGET_TEXTBOX_H__
|
||||||
|
|
||||||
|
// These are for the text box widget
|
||||||
|
#define TXT_HSPACE 48
|
||||||
|
#define TXT_TOPSPACE 4
|
||||||
|
#define TXT_MIDSPACE 3
|
||||||
|
#define TXT_BOTSPACE 4
|
||||||
|
|
||||||
|
struct gadget_textbox_line {
|
||||||
|
struct gadget_textbox_line *next;
|
||||||
|
const char *text;
|
||||||
|
int l, w, h;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gadget_textbox {
|
||||||
|
Display *dpy;
|
||||||
|
struct DrawInfo *dri;
|
||||||
|
GC gc;
|
||||||
|
Window w;
|
||||||
|
int x, y;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
struct gadget_textbox_line *firstline, *lastline;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct gadget_textbox *gadget_textbox_create(Display *dpy,
|
||||||
|
struct DrawInfo *dri, GC gc, Window mainwin, int x, int y,
|
||||||
|
int width, int height);
|
||||||
|
extern void gadget_textbox_free(struct gadget_textbox *g);
|
||||||
|
extern struct gadget_textbox_line * gadget_textbox_addline(
|
||||||
|
struct gadget_textbox *g, const char *text);
|
||||||
|
extern void gadget_textbox_refresh(struct gadget_textbox *g);
|
||||||
|
|
||||||
|
#endif /* __LIBAMI_GADGET_TEXTBOX_H__ */
|
||||||
349
libami/gadget_textinput.c
Normal file
349
libami/gadget_textinput.c
Normal file
@@ -0,0 +1,349 @@
|
|||||||
|
#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_textinput.h"
|
||||||
|
|
||||||
|
#ifdef AMIGAOS
|
||||||
|
#include <pragmas/xlib_pragmas.h>
|
||||||
|
extern struct Library *XLibBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct gadget_textinput *
|
||||||
|
gadget_textinput_create(Display *dpy, struct DrawInfo *dri,
|
||||||
|
GC gc, Window mainwin, int x, int y, int width, int height,
|
||||||
|
int textsize)
|
||||||
|
{
|
||||||
|
struct gadget_textinput *b;
|
||||||
|
|
||||||
|
b = calloc(1, sizeof(*b));
|
||||||
|
if (b == NULL)
|
||||||
|
return (NULL);
|
||||||
|
b->dpy = dpy;
|
||||||
|
b->dri = dri;
|
||||||
|
b->gc = gc;
|
||||||
|
b->x = x;
|
||||||
|
b->y = y;
|
||||||
|
b->width = width;
|
||||||
|
b->height = height;
|
||||||
|
b->buf = calloc(textsize + 1, sizeof(char));
|
||||||
|
if (b->buf == NULL) {
|
||||||
|
free(b);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
b->cur_x = 6;
|
||||||
|
b->size = textsize;
|
||||||
|
b->w = XCreateSimpleWindow(dpy, mainwin, x, y,
|
||||||
|
width, height, 0,
|
||||||
|
b->dri->dri_Pens[SHADOWPEN],
|
||||||
|
b->dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
|
||||||
|
XSelectInput(dpy, b->w, ExposureMask|ButtonPressMask);
|
||||||
|
|
||||||
|
return (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
void
|
||||||
|
gadget_textinput_set_xic(struct gadget_textinput *g, XIC xic)
|
||||||
|
{
|
||||||
|
g->xic = xic;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
gadget_textinput_repaint_str(struct gadget_textinput *b)
|
||||||
|
{
|
||||||
|
int l, mx=6;
|
||||||
|
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[TEXTPEN]);
|
||||||
|
if(b->len > b->left_pos) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int w, c;
|
||||||
|
|
||||||
|
for (l=0; l<b->len - b->left_pos; ) {
|
||||||
|
c=mbrlen(b->buf+b->left_pos+l, b->len-b->left_pos-l, NULL);
|
||||||
|
w=6+XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos, l+c);
|
||||||
|
if(w>b->width-6)
|
||||||
|
break;
|
||||||
|
mx=w;
|
||||||
|
l+=c;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmbDrawImageString(b->dpy, b->w, b->dri->dri_FontSet, b->gc,
|
||||||
|
6, 3+b->dri->dri_Ascent,
|
||||||
|
b->buf+b->left_pos, l);
|
||||||
|
#else
|
||||||
|
mx+=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos, l=b->len-b->left_pos);
|
||||||
|
while(mx>b->width-6)
|
||||||
|
mx-=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos + --l, 1);
|
||||||
|
XDrawImageString(b->dpy, b->w, b->gc, 6, 3+b->dri->dri_Ascent,
|
||||||
|
b->buf+b->left_pos, l);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
XFillRectangle(b->dpy, b->w, b->gc, mx, 3, b->width-mx-6, b->width - 6);
|
||||||
|
if(b->selected) {
|
||||||
|
if(b->cur_pos<b->len) {
|
||||||
|
XSetBackground(b->dpy, b->gc, ~0);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL);
|
||||||
|
XmbDrawImageString(b->dpy, b->w, b->dri->dri_FontSet, b->gc, b->cur_x,
|
||||||
|
3+b->dri->dri_Ascent, b->buf+b->cur_pos, l);
|
||||||
|
#else
|
||||||
|
XDrawImageString(b->dpy, b->w, b->gc, cur_x, 3+b->dri->dri_Ascent,
|
||||||
|
b->buf+b->cur_pos, 1);
|
||||||
|
#endif
|
||||||
|
XSetBackground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]);
|
||||||
|
} else {
|
||||||
|
XSetForeground(b->dpy, b->gc, ~0);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
XFillRectangle(b->dpy, b->w, b->gc, b->cur_x, 3,
|
||||||
|
XExtentsOfFontSet(b->dri->dri_FontSet)->
|
||||||
|
max_logical_extent.width, b->height - 6);
|
||||||
|
#else
|
||||||
|
XFillRectangle(b->dpy, b->w, b->gc, cur_x, 3,
|
||||||
|
b->dri->dri_Font->max_bounds.width, b->height - 6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textinput_repaint(struct gadget_textinput *b)
|
||||||
|
{
|
||||||
|
|
||||||
|
gadget_textinput_repaint_str(b);
|
||||||
|
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[SHINEPEN]);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 0, b->height-1, 0, 0);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 0, 0, b->width-2, 0);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 3, b->height-2, b->width-4,
|
||||||
|
b->height-2);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, b->width-4, b->height-2, b->width-4, 2);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 1, 1, 1, b->height-2);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, b->width-3, 1, b->width-3, b->height-2);
|
||||||
|
XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[SHADOWPEN]);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 1, b->height-1, b->width-1,
|
||||||
|
b->height-1);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, b->width-1, b->height-1, b->width-1, 0);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 3, b->height-3, 3, 1);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 3, 1, b->width-4, 1);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, 2, 1, 2, b->height-2);
|
||||||
|
XDrawLine(b->dpy, b->w, b->gc, b->width-2, 1, b->width-2, b->height-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textinput_free(struct gadget_textinput *b)
|
||||||
|
{
|
||||||
|
if (b->buf)
|
||||||
|
free(b->buf);
|
||||||
|
XDestroyWindow(b->dpy, b->w);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textinput_keyevent(struct gadget_textinput *b, XKeyEvent *e)
|
||||||
|
{
|
||||||
|
#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(b->xic, e, buf, sizeof(buf), &ks, &stat);
|
||||||
|
if(stat == XLookupKeySym || stat == XLookupBoth)
|
||||||
|
#endif
|
||||||
|
switch(ks) {
|
||||||
|
case XK_Return:
|
||||||
|
case XK_Linefeed:
|
||||||
|
b->crlf = 1;
|
||||||
|
break;
|
||||||
|
case XK_Left:
|
||||||
|
if(b->cur_pos) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int p=b->cur_pos;
|
||||||
|
// int z;
|
||||||
|
while(p>0) {
|
||||||
|
--p;
|
||||||
|
if(((int)mbrlen(b->buf+p, b->cur_pos-p, NULL))>0) {
|
||||||
|
b->cur_pos=p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
--cur_pos;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XK_Right:
|
||||||
|
if(b->cur_pos<b->len) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL);
|
||||||
|
if(l>0)
|
||||||
|
b->cur_pos+=l;
|
||||||
|
#else
|
||||||
|
b->cur_pos++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XK_Begin:
|
||||||
|
b->cur_pos=0;
|
||||||
|
break;
|
||||||
|
case XK_End:
|
||||||
|
b->cur_pos=b->len;
|
||||||
|
break;
|
||||||
|
case XK_Delete:
|
||||||
|
if(b->cur_pos<b->len) {
|
||||||
|
int l=1;
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL);
|
||||||
|
if(l<=0)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
b->len-=l;
|
||||||
|
for(x=b->cur_pos; x<b->len; x++)
|
||||||
|
b->buf[x]=b->buf[x+l];
|
||||||
|
b->buf[x] = 0;
|
||||||
|
} else XBell(b->dpy, 100);
|
||||||
|
break;
|
||||||
|
case XK_BackSpace:
|
||||||
|
if(b->cur_pos>0) {
|
||||||
|
int l=1;
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int p=b->cur_pos;
|
||||||
|
while(p>0) {
|
||||||
|
--p;
|
||||||
|
if(((int)mbrlen(b->buf+p, b->len-p, NULL))>0) {
|
||||||
|
l= b->cur_pos - p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
b->len -= l;
|
||||||
|
for(x=(b->cur_pos-=l); x<b->len; x++)
|
||||||
|
b->buf[x]=b->buf[x+l];
|
||||||
|
b->buf[x] = 0;
|
||||||
|
} else XBell(b->dpy, 100);
|
||||||
|
break;
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
default:
|
||||||
|
if(stat == XLookupBoth)
|
||||||
|
stat = XLookupChars;
|
||||||
|
}
|
||||||
|
if(stat == XLookupChars) {
|
||||||
|
#else
|
||||||
|
default:
|
||||||
|
#endif
|
||||||
|
for(i=0; i<n && b->len<b->size-1; i++) {
|
||||||
|
for(x=b->len; x>b->cur_pos; --x)
|
||||||
|
b->buf[x]=b->buf[x-1];
|
||||||
|
b->buf[b->cur_pos++]=buf[i];
|
||||||
|
b->len++;
|
||||||
|
}
|
||||||
|
if(i<n)
|
||||||
|
XBell(b->dpy, 100);
|
||||||
|
}
|
||||||
|
if(b->cur_pos<b->left_pos)
|
||||||
|
b->left_pos=b->cur_pos;
|
||||||
|
b->cur_x=6;
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
if(b->cur_pos>b->left_pos)
|
||||||
|
b->cur_x+=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos,
|
||||||
|
b->cur_pos-b->left_pos);
|
||||||
|
if(b->cur_pos < b->len) {
|
||||||
|
int l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL);
|
||||||
|
x=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->cur_pos, l);
|
||||||
|
} else
|
||||||
|
x=XExtentsOfFontSet(b->dri->dri_FontSet)->max_logical_extent.width;
|
||||||
|
#else
|
||||||
|
if(b->cur_pos > b->left_pos)
|
||||||
|
b->cur_x+=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos, b->cur_pos-b->left_pos);
|
||||||
|
if(b->cur_pos<b->buf_len)
|
||||||
|
x=XTextWidth(b->dri->dri_Font, b->buf+b->cur_pos, 1);
|
||||||
|
else
|
||||||
|
x=b->dri->dri_Font->max_bounds.width;
|
||||||
|
#endif
|
||||||
|
if((x+=b->cur_x-(b->width-6))>0) {
|
||||||
|
b->cur_x-=x;
|
||||||
|
while(x>0) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
int l=mbrlen(b->buf+b->left_pos, b->len-b->left_pos, NULL);
|
||||||
|
x-=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos, l);
|
||||||
|
b->left_pos += l;
|
||||||
|
#else
|
||||||
|
x-=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos++, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
b->cur_x+=x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textinput_buttonevent(struct gadget_textinput *b, XButtonEvent *e)
|
||||||
|
{
|
||||||
|
int w, l=1;
|
||||||
|
b->cur_pos=b->left_pos;
|
||||||
|
b->cur_x=6;
|
||||||
|
while(b->cur_x<e->x && b->cur_pos<b->len) {
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL);
|
||||||
|
if(l<=0)
|
||||||
|
break;
|
||||||
|
w=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->cur_pos, l);
|
||||||
|
#else
|
||||||
|
w=XTextWidth(b->dri->dri_Font, b->buf+b->cur_pos, 1);
|
||||||
|
#endif
|
||||||
|
if(b->cur_x+w>e->x)
|
||||||
|
break;
|
||||||
|
b->cur_x+=w;
|
||||||
|
b->cur_pos+=l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
void strbutton(XButtonEvent *e)
|
||||||
|
{
|
||||||
|
refresh_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
gadget_textinput_selected(struct gadget_textinput *b, int selected)
|
||||||
|
{
|
||||||
|
b->selected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gadget_textinput_crlf(struct gadget_textinput *b)
|
||||||
|
{
|
||||||
|
return (b->crlf);
|
||||||
|
}
|
||||||
46
libami/gadget_textinput.h
Normal file
46
libami/gadget_textinput.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef __LIBAMI__GADGET_TEXTINPUT_H__
|
||||||
|
#define __LIBAMI__GADGET_TEXTINPUT_H__
|
||||||
|
|
||||||
|
struct gadget_textinput {
|
||||||
|
Display *dpy;
|
||||||
|
struct DrawInfo *dri;
|
||||||
|
Window w;
|
||||||
|
GC gc;
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
XIC xic;
|
||||||
|
#endif
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
/* XXX TODO: create a string representation here already */
|
||||||
|
char *buf;
|
||||||
|
int len;
|
||||||
|
int size;
|
||||||
|
|
||||||
|
/* Position of textbox cursor and rendering start */
|
||||||
|
int cur_pos;
|
||||||
|
int left_pos;
|
||||||
|
int cur_x;
|
||||||
|
|
||||||
|
int selected;
|
||||||
|
int crlf;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct gadget_textinput * gadget_textinput_create(Display *dpy,
|
||||||
|
struct DrawInfo *dri, GC gc, Window mainwin,
|
||||||
|
int x, int y, int width, int height, int text_size);
|
||||||
|
#ifdef USE_FONTSETS
|
||||||
|
extern void gadget_textinput_set_xic(struct gadget_textinput *g, XIC xic);
|
||||||
|
#endif
|
||||||
|
extern void gadget_textinput_repaint(struct gadget_textinput *b);
|
||||||
|
extern void gadget_textinput_free(struct gadget_textinput *b);
|
||||||
|
extern void gadget_textinput_keyevent(struct gadget_textinput *b,
|
||||||
|
XKeyEvent *e);
|
||||||
|
extern void gadget_textinput_buttonevent(struct gadget_textinput *b,
|
||||||
|
XButtonEvent *e);
|
||||||
|
extern void gadget_textinput_selected(struct gadget_textinput *b, int selected);
|
||||||
|
extern int gadget_textinput_crlf(struct gadget_textinput *b);
|
||||||
|
|
||||||
|
#endif /* __LIBAMI__GADGET_TEXTINPUT_H__ */
|
||||||
211
requestchoice.c
211
requestchoice.c
@@ -13,30 +13,33 @@
|
|||||||
extern struct Library *XLibBase;
|
extern struct Library *XLibBase;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// These are used for button spacing, not the button itself
|
||||||
#define BUT_BUTSPACE (2*(2+5))
|
#define BUT_BUTSPACE (2*(2+5))
|
||||||
#define BUT_INTSPACE 12
|
#define BUT_INTSPACE 12
|
||||||
#define BUT_EXTSPACE 4
|
#define BUT_EXTSPACE 4
|
||||||
#define BUT_VSPACE 6
|
|
||||||
#define TXT_HSPACE 48
|
#include "gadget_button.h"
|
||||||
#define TXT_TOPSPACE 4
|
#include "gadget_textbox.h"
|
||||||
#define TXT_MIDSPACE 3
|
|
||||||
#define TXT_BOTSPACE 4
|
|
||||||
|
|
||||||
struct choice {
|
struct choice {
|
||||||
struct choice *next;
|
struct choice *next;
|
||||||
const char *text;
|
const char *text;
|
||||||
int l, w;
|
int l, w;
|
||||||
Window win;
|
struct gadget_button *b;
|
||||||
} *firstchoice=NULL, *lastchoice=NULL;
|
} *firstchoice=NULL, *lastchoice=NULL;
|
||||||
|
|
||||||
struct line {
|
struct line {
|
||||||
struct line *next;
|
struct line *next;
|
||||||
const char *text;
|
const char *text;
|
||||||
int l, w, h;
|
int l, w, h;
|
||||||
} *firstline=NULL, *lastline=NULL;
|
} *firstline=NULL, *lastline=NULL;
|
||||||
|
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
Window root, mainwin, textwin;
|
Window root, mainwin;
|
||||||
|
|
||||||
|
//Window textwin;
|
||||||
|
struct gadget_textbox *g_textbox;
|
||||||
|
|
||||||
char *progname;
|
char *progname;
|
||||||
GC gc;
|
GC gc;
|
||||||
Pixmap stipple;
|
Pixmap stipple;
|
||||||
@@ -49,43 +52,59 @@ struct DrawInfo dri;
|
|||||||
|
|
||||||
struct RDArgs *ra=NULL;
|
struct RDArgs *ra=NULL;
|
||||||
|
|
||||||
void selection(int n)
|
static void
|
||||||
|
selection(int n)
|
||||||
{
|
{
|
||||||
printf("%d\n", n);
|
printf("%d\n", n);
|
||||||
XDestroyWindow(dpy, mainwin);
|
XDestroyWindow(dpy, mainwin);
|
||||||
XCloseDisplay(dpy);
|
XCloseDisplay(dpy);
|
||||||
FreeArgs(ra);
|
FreeArgs(ra);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *myalloc(size_t s)
|
static void
|
||||||
|
*myalloc(size_t s)
|
||||||
{
|
{
|
||||||
void *p=calloc(s,1);
|
void *p=calloc(s,1);
|
||||||
if(p)
|
if(p)
|
||||||
return p;
|
return p;
|
||||||
fprintf(stderr, "%s: out of memory!\n", progname);
|
fprintf(stderr, "%s: out of memory!\n", progname);
|
||||||
FreeArgs(ra);
|
FreeArgs(ra);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addchoice(const char *txt)
|
/*
|
||||||
|
* Add a choice to the list of choices, but don't create
|
||||||
|
* the button just yet. This'll be done once all of them
|
||||||
|
* are known and the math to create the window sizing/layout
|
||||||
|
* can be done.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
addchoice(const char *txt)
|
||||||
{
|
{
|
||||||
struct choice *c=myalloc(sizeof(struct choice));
|
struct choice *c=myalloc(sizeof(struct choice));
|
||||||
if(lastchoice)
|
if(lastchoice)
|
||||||
lastchoice->next=c;
|
lastchoice->next=c;
|
||||||
else
|
else
|
||||||
firstchoice=c;
|
firstchoice=c;
|
||||||
lastchoice=c;
|
lastchoice=c;
|
||||||
c->l=strlen(c->text=txt);
|
|
||||||
|
c->l = strlen(txt);
|
||||||
|
c->text = txt;
|
||||||
|
|
||||||
#ifdef USE_FONTSETS
|
#ifdef USE_FONTSETS
|
||||||
totw+=(c->w=XmbTextEscapement(dri.dri_FontSet, c->text, c->l))+BUT_BUTSPACE;
|
totw+=(c->w=XmbTextEscapement(dri.dri_FontSet, c->text, c->l))+BUT_BUTSPACE;
|
||||||
#else
|
#else
|
||||||
totw+=(c->w=XTextWidth(dri.dri_Font, c->text, c->l))+BUT_BUTSPACE;
|
totw+=(c->w=XTextWidth(dri.dri_Font, c->text, c->l))+BUT_BUTSPACE;
|
||||||
#endif
|
#endif
|
||||||
nchoices++;
|
nchoices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addline(const char *txt)
|
/*
|
||||||
|
* Add a line to the text box that we can draw.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
addline(const char *txt)
|
||||||
{
|
{
|
||||||
struct line *l=myalloc(sizeof(struct line));
|
struct line *l=myalloc(sizeof(struct line));
|
||||||
if(lastline)
|
if(lastline)
|
||||||
@@ -94,6 +113,13 @@ void addline(const char *txt)
|
|||||||
firstline=l;
|
firstline=l;
|
||||||
lastline=l;
|
lastline=l;
|
||||||
l->l=strlen(l->text=txt);
|
l->l=strlen(l->text=txt);
|
||||||
|
|
||||||
|
/* These are used to find the size, which we want
|
||||||
|
* to use in order to determine how big our window
|
||||||
|
* should be. It's a bit of a chicken/egg problem
|
||||||
|
* for now whilst this is figured out - it's also
|
||||||
|
* done in gadget_textbox_addline().
|
||||||
|
*/
|
||||||
#ifdef USE_FONTSETS
|
#ifdef USE_FONTSETS
|
||||||
l->w=XmbTextEscapement(dri.dri_FontSet, l->text, l->l);
|
l->w=XmbTextEscapement(dri.dri_FontSet, l->text, l->l);
|
||||||
#else
|
#else
|
||||||
@@ -104,57 +130,13 @@ void addline(const char *txt)
|
|||||||
maxw=l->w;
|
maxw=l->w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh_text()
|
|
||||||
{
|
|
||||||
int w=totw-BUT_EXTSPACE-BUT_EXTSPACE;
|
|
||||||
int h=toth-TXT_TOPSPACE-TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE-
|
|
||||||
(dri.dri_Ascent+dri.dri_Descent);
|
|
||||||
int x=(totw-maxw+TXT_HSPACE)>>1;
|
|
||||||
int y=((dri.dri_Ascent+dri.dri_Descent)>>1)+dri.dri_Ascent;
|
|
||||||
struct line *l;
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[SHADOWPEN]);
|
|
||||||
XDrawLine(dpy, textwin, gc, 0, 0, w-2, 0);
|
|
||||||
XDrawLine(dpy, textwin, gc, 0, 0, 0, h-2);
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[SHINEPEN]);
|
|
||||||
XDrawLine(dpy, textwin, gc, 0, h-1, w-1, h-1);
|
|
||||||
XDrawLine(dpy, textwin, gc, w-1, 0, w-1, h-1);
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]);
|
|
||||||
for(l=firstline; l; l=l->next) {
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
XmbDrawString(dpy, textwin, dri.dri_FontSet, gc, x, y, l->text, l->l);
|
|
||||||
#else
|
|
||||||
XDrawString(dpy, textwin, gc, x, y, l->text, l->l);
|
|
||||||
#endif
|
|
||||||
y+=dri.dri_Ascent+dri.dri_Descent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void refresh_choice(struct choice *c)
|
void refresh_choice(struct choice *c)
|
||||||
{
|
{
|
||||||
int w=c->w+BUT_BUTSPACE;
|
gadget_button_refresh(c->b);
|
||||||
int h=dri.dri_Ascent+dri.dri_Descent+BUT_VSPACE;
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]);
|
|
||||||
#ifdef USE_FONTSETS
|
|
||||||
XmbDrawString(dpy, c->win, dri.dri_FontSet, gc, BUT_BUTSPACE/2,
|
|
||||||
dri.dri_Ascent+BUT_VSPACE/2, c->text, c->l);
|
|
||||||
#else
|
|
||||||
XDrawString(dpy, c->win, gc, BUT_BUTSPACE/2,
|
|
||||||
dri.dri_Ascent+BUT_VSPACE/2, c->text, c->l);
|
|
||||||
#endif
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[(c==selected && depressed)?
|
|
||||||
SHADOWPEN:SHINEPEN]);
|
|
||||||
XDrawLine(dpy, c->win, gc, 0, 0, w-2, 0);
|
|
||||||
XDrawLine(dpy, c->win, gc, 0, 0, 0, h-2);
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[(c==selected && depressed)?
|
|
||||||
SHINEPEN:SHADOWPEN]);
|
|
||||||
XDrawLine(dpy, c->win, gc, 1, h-1, w-1, h-1);
|
|
||||||
XDrawLine(dpy, c->win, gc, w-1, 1, w-1, h-1);
|
|
||||||
XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]);
|
|
||||||
XDrawPoint(dpy, c->win, gc, w-1, 0);
|
|
||||||
XDrawPoint(dpy, c->win, gc, 0, h-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void split(char *str, const char *delim, void (*func)(const char *))
|
static void
|
||||||
|
split(char *str, const char *delim, void (*func)(const char *))
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
if((p=strtok(str, delim)))
|
if((p=strtok(str, delim)))
|
||||||
@@ -167,23 +149,21 @@ struct choice *getchoice(Window w)
|
|||||||
{
|
{
|
||||||
struct choice *c;
|
struct choice *c;
|
||||||
for(c=firstchoice; c; c=c->next)
|
for(c=firstchoice; c; c=c->next)
|
||||||
if(w == c->win)
|
if(w == c->b->w)
|
||||||
return c;
|
return c;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggle(struct choice *c)
|
void toggle(struct choice *c)
|
||||||
{
|
{
|
||||||
XSetWindowBackground(dpy, c->win, dri.dri_Pens[(depressed&&c==selected)?
|
gadget_button_toggle(c->b);
|
||||||
FILLPEN:BACKGROUNDPEN]);
|
|
||||||
XClearWindow(dpy, c->win);
|
|
||||||
refresh_choice(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void abortchoice()
|
void abortchoice()
|
||||||
{
|
{
|
||||||
if(depressed) {
|
if(depressed) {
|
||||||
depressed=0;
|
depressed=0;
|
||||||
|
gadget_button_set_depressed(selected->b, 0);
|
||||||
toggle(selected);
|
toggle(selected);
|
||||||
}
|
}
|
||||||
selected=NULL;
|
selected=NULL;
|
||||||
@@ -210,6 +190,7 @@ int main(int argc, char *argv[])
|
|||||||
static XTextProperty txtprop1, txtprop2;
|
static XTextProperty txtprop1, txtprop2;
|
||||||
int x, y, extra=0, n=0;
|
int x, y, extra=0, n=0;
|
||||||
struct choice *c;
|
struct choice *c;
|
||||||
|
struct line *l;
|
||||||
Argtype array[3], *atp;
|
Argtype array[3], *atp;
|
||||||
|
|
||||||
progname=argv[0];
|
progname=argv[0];
|
||||||
@@ -258,28 +239,41 @@ int main(int argc, char *argv[])
|
|||||||
XDrawPoint(dpy, stipple, gc, 0, 1);
|
XDrawPoint(dpy, stipple, gc, 0, 1);
|
||||||
XDrawPoint(dpy, stipple, gc, 1, 0);
|
XDrawPoint(dpy, stipple, gc, 1, 0);
|
||||||
XSetWindowBackgroundPixmap(dpy, mainwin, stipple);
|
XSetWindowBackgroundPixmap(dpy, mainwin, stipple);
|
||||||
|
|
||||||
|
g_textbox = gadget_textbox_create(dpy, &dri, gc, mainwin,
|
||||||
|
BUT_EXTSPACE,
|
||||||
|
TXT_TOPSPACE,
|
||||||
|
totw - BUT_EXTSPACE - BUT_EXTSPACE,
|
||||||
|
toth-TXT_TOPSPACE- TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE- (dri.dri_Ascent+dri.dri_Descent));
|
||||||
|
#if 0
|
||||||
textwin=XCreateSimpleWindow(dpy, mainwin, BUT_EXTSPACE, TXT_TOPSPACE, totw-
|
textwin=XCreateSimpleWindow(dpy, mainwin, BUT_EXTSPACE, TXT_TOPSPACE, totw-
|
||||||
BUT_EXTSPACE-BUT_EXTSPACE, toth-TXT_TOPSPACE-
|
BUT_EXTSPACE-BUT_EXTSPACE,
|
||||||
TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE-
|
|
||||||
(dri.dri_Ascent+dri.dri_Descent),
|
|
||||||
0, dri.dri_Pens[SHADOWPEN],
|
0, dri.dri_Pens[SHADOWPEN],
|
||||||
dri.dri_Pens[BACKGROUNDPEN]);
|
dri.dri_Pens[BACKGROUNDPEN]);
|
||||||
XSelectInput(dpy, textwin, ExposureMask);
|
XSelectInput(dpy, textwin, ExposureMask);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Lay out + create buttons */
|
||||||
x=BUT_EXTSPACE;
|
x=BUT_EXTSPACE;
|
||||||
y=toth-TXT_BOTSPACE-(dri.dri_Ascent+dri.dri_Descent)-BUT_VSPACE;
|
y=toth-TXT_BOTSPACE-(dri.dri_Ascent+dri.dri_Descent)-BUT_VSPACE;
|
||||||
for(c=firstchoice; c; c=c->next) {
|
for(c=firstchoice; c; c=c->next) {
|
||||||
c->win=XCreateSimpleWindow(dpy, mainwin,
|
c->b = gadget_button_init(dpy, &dri, gc, mainwin,
|
||||||
x+(nchoices==1? (extra>>1):
|
x + (nchoices == 1 ? (extra >> 1) : n++*extra/(nchoices-1)),
|
||||||
n++*extra/(nchoices-1)),
|
y,
|
||||||
y, c->w+BUT_BUTSPACE,
|
c->w + BUT_BUTSPACE,
|
||||||
dri.dri_Ascent+dri.dri_Descent+
|
// Note: the original code didn't need a +2 here, but
|
||||||
BUT_VSPACE, 0,
|
// when using the ported button gadget it's needed or
|
||||||
dri.dri_Pens[SHADOWPEN],
|
// the bottom of the button isn't shown. Figure out why!
|
||||||
dri.dri_Pens[BACKGROUNDPEN]);
|
dri.dri_Ascent+dri.dri_Descent + BUT_VSPACE + 2);
|
||||||
XSelectInput(dpy, c->win, ExposureMask|ButtonPressMask|ButtonReleaseMask|
|
gadget_button_set_text(c->b, c->text);
|
||||||
EnterWindowMask|LeaveWindowMask);
|
|
||||||
x+=c->w+BUT_BUTSPACE+BUT_INTSPACE;
|
x+=c->w+BUT_BUTSPACE+BUT_INTSPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lay out + create text box contents */
|
||||||
|
for (l = firstline; l; l = l->next) {
|
||||||
|
gadget_textbox_addline(g_textbox, l->text);
|
||||||
|
}
|
||||||
|
|
||||||
size_hints.flags = PResizeInc;
|
size_hints.flags = PResizeInc;
|
||||||
txtprop1.value=(unsigned char *)array[0].ptr;
|
txtprop1.value=(unsigned char *)array[0].ptr;
|
||||||
txtprop2.value=(unsigned char *)"RequestChoice";
|
txtprop2.value=(unsigned char *)"RequestChoice";
|
||||||
@@ -297,20 +291,22 @@ int main(int argc, char *argv[])
|
|||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case Expose:
|
case Expose:
|
||||||
if(!event.xexpose.count) {
|
if(!event.xexpose.count) {
|
||||||
if(event.xexpose.window == textwin)
|
if(event.xexpose.window == g_textbox->w)
|
||||||
refresh_text();
|
gadget_textbox_refresh(g_textbox);
|
||||||
else if((c=getchoice(event.xexpose.window)))
|
else if((c=getchoice(event.xexpose.window)))
|
||||||
refresh_choice(c);
|
refresh_choice(c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LeaveNotify:
|
case LeaveNotify:
|
||||||
if(depressed && event.xcrossing.window==selected->win) {
|
if(depressed && event.xcrossing.window==selected->b->w) {
|
||||||
depressed=0;
|
depressed=0;
|
||||||
|
gadget_button_set_depressed(selected->b, 0);
|
||||||
toggle(selected);
|
toggle(selected);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
if((!depressed) && selected && event.xcrossing.window==selected->win) {
|
if((!depressed) && selected && event.xcrossing.window==selected->b->w) {
|
||||||
|
gadget_button_set_depressed(selected->b, 1);
|
||||||
depressed=1;
|
depressed=1;
|
||||||
toggle(selected);
|
toggle(selected);
|
||||||
}
|
}
|
||||||
@@ -320,6 +316,7 @@ int main(int argc, char *argv[])
|
|||||||
(c=getchoice(event.xbutton.window))) {
|
(c=getchoice(event.xbutton.window))) {
|
||||||
abortchoice();
|
abortchoice();
|
||||||
depressed=1;
|
depressed=1;
|
||||||
|
gadget_button_set_depressed(c->b, 1);
|
||||||
toggle(selected=c);
|
toggle(selected=c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user