Initial commit!

This commit is contained in:
reddsik
2017-03-26 13:00:19 +02:00
commit c85716f60e
90 changed files with 28790 additions and 0 deletions

45
libami/Makefile Normal file
View File

@@ -0,0 +1,45 @@
srcdir = .
SHELL = /bin/sh
CC = gcc
LEX = flex
YACC = bison -y
RANLIB = ranlib
CFLAGS = -g -O2
YFLAGS = -d
DEFS = -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DYYTEXT_POINTER=1 -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_TERMIO_H=1 -DHAVE_X11_EXTENSIONS_SHAPE_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DRETSIGTYPE=void -DHAVE_WAIT3=1 -DHAVE_SELECT=1 -DHAVE_STRDUP=1 -DHAVE_WAITPID=1 -DHAVE_XSHAPE=1 -DBSD_STYLE_GETTIMEOFDAY=1 -DHAVE_XCREATEFONTSET=1 -DHAVE_XMBTEXTESCAPEMENT=1 -DHAVE_XUTF8DRAWIMAGESTRING=1 -DUSE_FONTSETS=1 -DLAME_ENDIAN=1
ALL_CFLAGS = -I. -I.. $(DEFS) $(CFLAGS)
LIBS = -lSM -lICE -lXext -lXmu -lX11
prefix = /usr/local
exec_prefix = ${prefix}
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
INSTALL = /usr/bin/install -c
LN_S = ln -s
OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \
mdicon.o mdwindow.o kbdsupport.o hotkey.o \
lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \
iffparse.o
SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \
mdicon.c mdwindow.c kbdsupport.c hotkey.c \
lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \
iffparse.c
all : libami.a
libami.a : $(OBJS)
ar rc libami.a $(OBJS)
$(RANLIB) libami.a
.c.o:
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
depend: $(SRCS)
-@rm Makefile.bak
mv Makefile Makefile.bak
( sed '/^#--DO NOT REMOVE THIS LINE--$$/q' < Makefile.bak ; \
$(CC) -MM $(ALL_CFLAGS) $(SRCS) ) > Makefile
#--DO NOT REMOVE THIS LINE--

45
libami/Makefile.in Normal file
View File

@@ -0,0 +1,45 @@
srcdir = @srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
CC = @CC@
LEX = @LEX@
YACC = @YACC@
RANLIB = @RANLIB@
CFLAGS = @CFLAGS@
YFLAGS = -d
DEFS = @DEFS@
ALL_CFLAGS = -I@srcdir@ -I@top_srcdir@ $(DEFS) $(CFLAGS) @X_CFLAGS@
LIBS = @X_LIBS@ @X_PRE_LIBS@ -lXext -lXmu -lX11 @X_EXTRA_LIBS@ @LIBS@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = $(exec_prefix)/bin
libdir = $(exec_prefix)/lib
INSTALL = @INSTALL@
LN_S = @LN_S@
OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \
mdicon.o mdwindow.o kbdsupport.o hotkey.o \
lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \
iffparse.o
SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \
mdicon.c mdwindow.c kbdsupport.c hotkey.c \
lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \
iffparse.c
all : libami.a
libami.a : $(OBJS)
ar rc libami.a $(OBJS)
$(RANLIB) libami.a
.c.o:
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
depend: $(SRCS)
-@rm Makefile.bak
mv Makefile Makefile.bak
( sed '/^#--DO NOT REMOVE THIS LINE--$$/q' < Makefile.bak ; \
$(CC) -MM $(ALL_CFLAGS) $(SRCS) ) > Makefile
#--DO NOT REMOVE THIS LINE--

21
libami/broker.c Normal file
View File

@@ -0,0 +1,21 @@
#include <stdio.h>
#include <stdlib.h>
#include "libami.h"
#include "module.h"
extern void (*md_broker_func)(XEvent *, unsigned long);
int cx_broker(unsigned long mask, void (*callback)(XEvent *, unsigned long))
{
md_broker_func=callback;
return md_command0(md_root, MCMD_SET_BROKER, &mask, sizeof(mask));
}
int cx_send_event(unsigned long mask, XEvent *e)
{
struct mcmd_event me;
me.mask=mask;
me.event=*e;
return md_command0(md_root, MCMD_SEND_EVENT, &me, sizeof(me));
}

235
libami/drawinfo.c Normal file
View File

@@ -0,0 +1,235 @@
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
#include "drawinfo.h"
#ifdef AMIGAOS
#include <pragmas/xlib_pragmas.h>
extern struct Library *XLibBase;
#endif
#define TAG_DRI_VERSION 1
#define TAG_DRI_PENS 2
#define TAG_DRI_FONT 3
#define TAG_DRI_FONTSET 4
extern char *progname;
static char black[] = "#000000";
static char white[] = "#ffffff";
static char grey[] = "#aaaaaa";
static char blue[] = "#6688bb";
char *default_colors[NUMDRIPENS] = {
black, white, black, white, black, blue, black, grey, white,
black, white, black
};
char *default_screenfont =
"-b&h-lucida-medium-r-normal-sans-12-*-*-*-*-*-iso8859-1"
#ifdef USE_FONTSETS
",-b&h-lucida-medium-r-normal-sans-12-*-*-*-*-*-iso10646-1"
",-misc-fixed-medium-r-normal--14-*-*-*-*-*-jisx0208.1983-0"
#endif
;
static void setdriprop(Display *dpy, Atom atom, Atom typ, Window win,
struct DrawInfo *dri)
{
CARD32 prop[/* NUMDRIPENS+6 */ 100], *p=prop;
CARD16 i;
*p++=TAG_DRI_VERSION;
*p++=dri->dri_Version;
#ifdef USE_FONTSETS
*p++=TAG_DRI_FONTSET;
*p++=dri->dri_FontSetAtom;
#else
*p++=TAG_DRI_FONT;
*p++=dri->dri_Font->fid;
#endif
*p++=TAG_DRI_PENS;
*p++=dri->dri_NumPens;
for(i=0; i<dri->dri_NumPens; i++)
*p++=dri->dri_Pens[i];
XChangeProperty(dpy, win, atom, typ, 32, PropModeReplace,
(unsigned char *)prop, p-prop);
}
static void getdriprop(Display *dpy, Atom atom, Atom typ, Window win,
struct DrawInfo *dri)
{
Atom atyp;
int afmt;
unsigned long nitems, extra;
int i,j,n;
CARD32 *prop=NULL;
if(XGetWindowProperty(dpy, win, atom, 0l, NUMDRIPENS+6, False, typ,
&atyp, &afmt, &nitems, &extra,
(unsigned char **)&prop) == Success &&
atyp==typ && afmt==32) {
for(i=0; i<nitems; )
switch(prop[i++]) {
case TAG_DRI_VERSION:
if(i<nitems)
dri->dri_Version=prop[i++];
break;
#ifdef USE_FONTSETS
case TAG_DRI_FONTSET:
if(i<nitems)
dri->dri_FontSetAtom=prop[i++];
break;
#else
case TAG_DRI_FONT:
if(i<nitems)
dri->dri_Font=XQueryFont(dpy, prop[i++]);
break;
#endif
case TAG_DRI_PENS:
if(i<nitems) {
n=prop[i++];
if(n>nitems-i)
n=nitems-i;
if(n>0) {
dri->dri_NumPens=n;
if((dri->dri_Pens=calloc(sizeof(unsigned long), n)))
for(j=0; j<n; j++)
dri->dri_Pens[j]=prop[i++];
}
}
break;
}
}
if(prop)
XFree(prop);
}
Status myXAllocNamedColor(Display *dpy, Colormap cmap, char *color_name,
XColor *screen_def, XColor *exact_def)
{
Status s;
if((s=XAllocNamedColor(dpy, cmap, color_name, screen_def, exact_def)))
return s;
if((s=XLookupColor(dpy, cmap, color_name, screen_def, exact_def))||
(s=XParseColor(dpy, cmap, color_name, exact_def))) {
*screen_def = *exact_def;
screen_def->pixel = 0;
screen_def->flags = DoRed|DoGreen|DoBlue;
s=XAllocColor(dpy, cmap, screen_def);
}
return s;
}
unsigned long allocdripen(Display *dpy, int n, Colormap cm)
{
XColor screen, exact;
char *name;
if(!myXAllocNamedColor(dpy, cm, name = default_colors[n],
&screen, &exact)) {
fprintf(stderr, "%s: cannot allocate color %s\n", progname, name);
exit(1);
}
return screen.pixel;
}
void term_dri(struct DrawInfo *dri, Display *dpy, Colormap cm)
{
if(dri->dri_Pens) {
XFreeColors(dpy, cm, dri->dri_Pens, dri->dri_NumPens, 0);
free(dri->dri_Pens);
dri->dri_Pens = NULL;
}
#ifdef USE_FONTSETS
if(dri->dri_FontSet) {
XFreeFontSet(dpy, dri->dri_FontSet);
dri->dri_FontSet = NULL;
}
#else
if(dri->dri_Font) {
XFreeFont(dpy, dri->dri_Font);
dri->dri_Font = NULL;
}
#endif
}
void init_dri(struct DrawInfo *dri, Display *dpy, Window root, Colormap cm,
int override)
{
int i;
Atom driatom, dritypatom;
driatom=XInternAtom(dpy, "AMIWM_DRAWINFO", False);
dritypatom=XInternAtom(dpy, "DRAWINFO", False);
if(!override) {
memset(dri, 0, sizeof(*dri));
getdriprop(dpy, driatom, dritypatom, root, dri);
}
if(!dri->dri_Version)
dri->dri_Version = DRI_VERSION;
if(!dri->dri_Pens) {
if(!(dri->dri_Pens = calloc(sizeof(unsigned long), NUMDRIPENS))) {
fprintf(stderr, "%s: out of memory\n", progname);
exit(1);
}
for(i=0; i<NUMDRIPENS; i++)
dri->dri_Pens[i] = allocdripen(dpy, i, cm);
dri->dri_NumPens = NUMDRIPENS;
}
#ifdef USE_FONTSETS
if(!dri->dri_FontSet)
{
char *fn;
XFontStruct **fsl;
char **fnl;
char **missing_charsets = NULL;
int n_missing_charsets = 0;
if(dri->dri_FontSetAtom) {
fn = XGetAtomName(dpy, dri->dri_FontSetAtom);
} else {
dri->dri_FontSetAtom = XInternAtom(dpy, fn=default_screenfont, False);
}
dri->dri_FontSet = XCreateFontSet(dpy, fn,
&missing_charsets,
&n_missing_charsets, NULL);
if(missing_charsets)
XFreeStringList(missing_charsets);
if(!dri->dri_FontSet) {
fprintf(stderr, "%s: cannot open font %s\n", progname, fn);
exit(1);
}
if(XFontsOfFontSet(dri->dri_FontSet, &fsl, &fnl) < 1) {
fprintf(stderr, "%s: fontset %s is empty\n", progname, fn);
exit(1);
}
if(fn != default_screenfont)
XFree(fn);
#if 0
//dri->dri_Font = fsl[0];
dri->dri_Font = malloc(sizeof(XFontStruct));
memcpy(dri->dri_Font, fsl[0], sizeof(XFontStruct));
#else
dri->dri_Ascent = fsl[0]->ascent;
dri->dri_Descent = fsl[0]->descent;
dri->dri_MaxBoundsWidth = fsl[0]->max_bounds.width;
#endif
}
#else
if(!dri->dri_Font)
if(!(dri->dri_Font = XLoadQueryFont(dpy, default_screenfont))) {
fprintf(stderr, "%s: cannot open font %s\n", progname,
default_screenfont);
exit(1);
}
dri->dri_Ascent = dri->dri_Font->ascent;
dri->dri_Descent = dri->dri_Font->descent;
dri->dri_MaxBoundsWidth = dri->dri_Font->max_bounds.width;
#endif
if(override)
setdriprop(dpy, driatom, dritypatom, root, dri);
}

65
libami/drawinfo.h Normal file
View File

@@ -0,0 +1,65 @@
#ifndef DRAWINFO_H
#include <X11/Xlib.h>
#include <X11/Xmd.h>
#define DRI_VERSION (2)
struct DrawInfo
{
CARD16 dri_Version; /* will be DRI_VERSION */
CARD16 dri_NumPens; /* guaranteed to be >= 9 */
unsigned long *dri_Pens; /* pointer to pen array */
#ifdef USE_FONTSETS
XFontSet dri_FontSet; /* screen default font */
#else
XFontStruct *dri_Font; /* screen default font */
#endif
CARD16 dri_Depth; /* (initial) depth of screen bitmap */
struct { /* from DisplayInfo database for initial display mode */
CARD16 X;
CARD16 Y;
} dri_Resolution;
BITS32 dri_Flags; /* defined below */
/* New for V39: dri_CheckMark, dri_AmigaKey. */
Pixmap dri_CheckMark; /* pointer to scaled checkmark image
* Will be NULL if DRI_VERSION < 2
*/
Pixmap dri_AmigaKey; /* pointer to scaled Amiga-key image
* Will be NULL if DRI_VERSION < 2
*/
CARD32 dri_Ascent;
CARD32 dri_Descent;
CARD32 dri_MaxBoundsWidth;
#ifdef USE_FONTSETS
Atom dri_FontSetAtom;
CARD32 dri_Reserved; /* avoid recompilation ;^) */
#else
CARD32 dri_Reserved[2]; /* avoid recompilation ;^) */
#endif
};
#define DETAILPEN (0x0000) /* compatible Intuition rendering pens */
#define BLOCKPEN (0x0001) /* compatible Intuition rendering pens */
#define TEXTPEN (0x0002) /* text on background */
#define SHINEPEN (0x0003) /* bright edge on 3D objects */
#define SHADOWPEN (0x0004) /* dark edge on 3D objects */
#define FILLPEN (0x0005) /* active-window/selected-gadget fill */
#define FILLTEXTPEN (0x0006) /* text over FILLPEN */
#define BACKGROUNDPEN (0x0007) /* always color 0 */
#define HIGHLIGHTTEXTPEN (0x0008) /* special color text, on background */
/* New for V39, only present if DRI_VERSION >= 2: */
#define BARDETAILPEN (0x0009) /* text/detail in screen-bar/menus */
#define BARBLOCKPEN (0x000A) /* screen-bar/menus fill */
#define BARTRIMPEN (0x000B) /* trim under screen-bar */
#define NUMDRIPENS (0x000C)
#define DRAWINFO_H
extern void term_dri(struct DrawInfo *, Display *, Colormap);
extern void init_dri(struct DrawInfo *, Display *, Window, Colormap, int);
#endif

72
libami/error.c Normal file
View File

@@ -0,0 +1,72 @@
#include <stdio.h>
#include <string.h>
#include "libami.h"
#ifndef AMIGAOS
static int amiga_errno=0;
#define MIN_ERRNO 103
static const char *syserrmsg[] = {
"not enough memory available", /* 103 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"bad template", /* 114 */
"bad number", /* 115 */
"required argument missing", /* 116 */
"value after keyword missing", /* 117 */
"wrong number of arguments", /* 118 */
NULL,
"argument line invalid or too long" /* 120 */
};
BOOL Fault(LONG code, UBYTE *header, UBYTE *buffer, LONG len)
{
amiga_errno=code;
if(header) {
int hdlen=strlen((char *)header);
if(hdlen+2>len)
return FALSE;
strcpy((char *)buffer, (char *)header);
buffer+=hdlen;
*buffer++=':';
*buffer++=' ';
len-=hdlen+2;
}
if(code>=MIN_ERRNO && code<MIN_ERRNO+sizeof(syserrmsg)/sizeof(syserrmsg[0])
&& syserrmsg[code-MIN_ERRNO]) {
if(len<strlen(syserrmsg[code-MIN_ERRNO])+1)
return FALSE;
strcpy((char *)buffer, syserrmsg[code-MIN_ERRNO]);
} else {
char number[6+4*sizeof(LONG)];
sprintf(number, "Error %ld", code);
if(len<strlen(number)+1)
return FALSE;
strcpy((char *)buffer, number);
}
return TRUE;
}
BOOL PrintFault(LONG code, UBYTE *header)
{
UBYTE buf[128];
if(Fault(code, header, buf, sizeof(buf))) {
fprintf(stderr, "%s\n", (char *)buf);
return TRUE;
} else return FALSE;
}
LONG IoErr()
{
return amiga_errno;
}
LONG SetIoErr(LONG code)
{
LONG old_errno=amiga_errno;
amiga_errno=code;
return old_errno;
}
#endif

21
libami/eventdispatcher.c Normal file
View File

@@ -0,0 +1,21 @@
#include "libami.h"
static int (*eventfunc[LASTEvent])(XEvent*);
static unsigned long eventmask=0;
static void eb_dispatch(XEvent *e, unsigned long mask)
{
if(e->type<0 || e->type>=LASTEvent || (!eventfunc[e->type]) ||
(!eventfunc[e->type](e)))
cx_send_event(mask, e);
}
void cx_event_broker(int type, unsigned long mask, int (*callback)(XEvent*))
{
if(type>=0 && type<LASTEvent) {
eventfunc[type]=callback;
cx_broker(eventmask|=mask, eb_dispatch);
}
}

152
libami/hotkey.c Normal file
View File

@@ -0,0 +1,152 @@
#include "libami.h"
#include <X11/keysym.h>
#include <stdlib.h>
#include <string.h>
static struct hotkey {
struct hotkey *next;
KeySym keysym;
unsigned int mod0;
int keycode;
unsigned int modifiers;
int meta, position;
int grab;
void (*callback)(XEvent *, void *);
void *client_data;
} *hotkeys = NULL;
static XModifierKeymap *modmap=NULL;
static KeySym *keymap=NULL;
static int kbd_mincode, kbd_maxcode, kbd_maxsym;
static unsigned int meta_mask, switch_mask;
static Display *dpy=NULL;
static void lookup_meta()
{
int i, j, k;
KeySym *kp;
unsigned int alt_mask = 0;
meta_mask = switch_mask = 0;
for(i=3; i<8; i++)
for(j=0; j<modmap->max_keypermod; j++)
for(kp=keymap+(modmap->modifiermap[i*modmap->max_keypermod+j]-
kbd_mincode)*kbd_maxsym, k=0; k<kbd_maxsym; k++)
switch(*kp++) {
case XK_Meta_L:
case XK_Meta_R:
meta_mask|=1<<i;
break;
case XK_Mode_switch:
switch_mask|=1<<i;
break;
case XK_Alt_L:
case XK_Alt_R:
alt_mask|=1<<i;
break;
}
if(meta_mask == 0)
meta_mask = (alt_mask? alt_mask :
(switch_mask? switch_mask : Mod1Mask));
}
static void lookup_hotkey(struct hotkey *hk)
{
if(!keymap) {
XDisplayKeycodes(dpy, &kbd_mincode, &kbd_maxcode);
keymap=XGetKeyboardMapping(dpy, kbd_mincode, kbd_maxcode-kbd_mincode+1,
&kbd_maxsym);
}
if(!modmap) {
modmap=XGetModifierMapping(dpy);
if(keymap)
lookup_meta();
}
hk->modifiers=hk->mod0|(hk->meta? meta_mask:0);
if(!(hk->keycode=XKeysymToKeycode(dpy, hk->keysym)))
if((hk->keysym&~0x20)>=XK_A && (hk->keysym&~0x20)<=XK_Z)
hk->keycode=XKeysymToKeycode(dpy, hk->keysym^0x20);
if(hk->keycode && keymap)
if(keymap[(hk->keycode-kbd_mincode)*kbd_maxsym])
;
else if(kbd_maxsym>1 && keymap[(hk->keycode-kbd_mincode)*kbd_maxsym+1])
hk->modifiers|=ShiftMask;
else if(kbd_maxsym>2 && keymap[(hk->keycode-kbd_mincode)*kbd_maxsym+2])
hk->modifiers|=switch_mask;
else if(kbd_maxsym>3 && keymap[(hk->keycode-kbd_mincode)*kbd_maxsym+3])
hk->modifiers|=ShiftMask|switch_mask;
}
static void rethink_keymap()
{
struct hotkey *hk;
if(keymap) {
XFree(keymap);
keymap=NULL;
}
if(modmap) {
XFreeModifiermap(modmap);
modmap=NULL;
}
for(hk=hotkeys; hk; hk=hk->next) {
int oldkc=hk->keycode;
unsigned oldmd=hk->modifiers;
lookup_hotkey(hk);
if(hk->grab>=0 && (hk->keycode!=oldkc || hk->modifiers!=oldmd)) {
md_ungrabkey(hk->grab);
hk->grab=-1;
}
if((hk->position & IN_WINDOW_MASK) && hk->grab<0)
hk->grab=md_grabkey(hk->keycode, hk->modifiers);
}
}
static int mappingfunc(XEvent *e)
{
if(e->xmapping.request==MappingKeyboard ||
e->xmapping.request==MappingModifier) {
e->xmapping.display=dpy;
XRefreshKeyboardMapping(&e->xmapping);
}
rethink_keymap();
return 0;
}
static int keypressfunc(XEvent *e)
{
struct hotkey *hk;
for(hk=hotkeys; hk; hk=hk->next)
if(hk->keycode==e->xkey.keycode &&
(hk->modifiers==e->xkey.state || (hk->modifiers & AnyModifier))) {
hk->callback(e, hk->client_data);
return 1;
}
return 0;
}
void cx_hotkey(KeySym ks, unsigned int mod, int m, int pos,
void (*cb)(XEvent *, void *), void *cd)
{
struct hotkey *hk=malloc(sizeof(struct hotkey));
if(hk) {
if(!dpy) {
dpy=md_display();
cx_event_broker(KeyPress, KeyPressMask, keypressfunc);
cx_event_broker(MappingNotify, 0, mappingfunc);
}
hk->next=hotkeys;
hk->keysym=ks;
hk->mod0=mod;
hk->meta=m;
hk->position=pos;
hk->callback=cb;
hk->client_data=cd;
lookup_hotkey(hk);
hk->grab=((pos&IN_WINDOW_MASK)? md_grabkey(hk->keycode, hk->modifiers):-1);
hotkeys=hk;
}
}

579
libami/iconlib.c Normal file
View File

@@ -0,0 +1,579 @@
#include "libami.h"
#include "alloc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifndef AMIGAOS
#define WBDISK 1
#define WBDRAWER 2
#define WBTOOL 3
#define WBPROJECT 4
#define WBGARBAGE 5
#define WBDEVICE 6
#define WBKICK 7
#define WBAPPICON 8
#define WB_DISKMAGIC 0xe310
char *BumpRevision(char *newbuf, char *oldname)
{
char tmpbuf[32];
int n;
if(!strncmp(oldname, "copy_of_", 8)) {
sprintf(newbuf, "copy_2_of_%.*s", 20, oldname);
} else if(2==sscanf(oldname, "copy_%d_of_%30s", &n, tmpbuf)) {
sprintf(newbuf, "copy_%d_of_", n+1);
tmpbuf[30-strlen(newbuf)]='\0';
strcat(newbuf, tmpbuf);
} else {
sprintf(newbuf, "copy_of_%.*s", 22, oldname);
}
return newbuf;
}
BOOL DeleteDiskObject(char *name)
{
int res;
#ifdef HAVE_ALLOCA
char *infoname=alloca(strlen(name)+8);
#else
char *infoname=malloc(strlen(name)+8);
if(infoname==NULL)
return FALSE;
#endif
sprintf(infoname, "%s.info", name);
res=unlink(infoname)>=0;
#ifndef HAVE_ALLOCA
free(infoname);
#endif
return res;
}
char *FindToolType(char **toolTypeArray, char *typeName)
{
char *p;
while((p=*toolTypeArray++)) {
char *p2=typeName;
while(*p2)
if(ToUpper(*p2)!=ToUpper(*p))
break;
else { p2++; p++; }
if(!*p2) {
if(!*p) return p;
if(*p=='=') return p+1;
}
}
return NULL;
}
void FreeDiskObject(struct DiskObject *diskobj)
{
if(diskobj->do_Gadget.GadgetRender) free(diskobj->do_Gadget.GadgetRender);
if(diskobj->do_Gadget.SelectRender) free(diskobj->do_Gadget.SelectRender);
if(diskobj->do_DefaultTool) free(diskobj->do_DefaultTool);
if(diskobj->do_ToolTypes) {
char *p, **pp=diskobj->do_ToolTypes;
while((p=*pp++)) free(p);
free(diskobj->do_ToolTypes);
}
if(diskobj->do_DrawerData) free(diskobj->do_DrawerData);
if(diskobj->do_ToolWindow) free(diskobj->do_ToolWindow);
free(diskobj);
}
static UWORD getu16(char **p)
{
union { UWORD n; char b[2]; } v;
#ifdef LAME_ENDIAN
v.b[1]=*(*p)++;
v.b[0]=*(*p)++;
#else
v.b[0]=*(*p)++;
v.b[1]=*(*p)++;
#endif
return v.n;
}
static WORD get16(char **p)
{
union { WORD n; char b[2]; } v;
#ifdef LAME_ENDIAN
v.b[1]=*(*p)++;
v.b[0]=*(*p)++;
#else
v.b[0]=*(*p)++;
v.b[1]=*(*p)++;
#endif
return v.n;
}
static ULONG getu32(char **p)
{
union { ULONG n; char b[4]; } v;
#ifdef LAME_ENDIAN
v.b[3]=*(*p)++;
v.b[2]=*(*p)++;
v.b[1]=*(*p)++;
v.b[0]=*(*p)++;
#else
v.b[0]=*(*p)++;
v.b[1]=*(*p)++;
v.b[2]=*(*p)++;
v.b[3]=*(*p)++;
#endif
return v.n;
}
static LONG get32(char **p)
{
union { LONG n; char b[4]; } v;
#ifdef LAME_ENDIAN
v.b[3]=*(*p)++;
v.b[2]=*(*p)++;
v.b[1]=*(*p)++;
v.b[0]=*(*p)++;
#else
v.b[0]=*(*p)++;
v.b[1]=*(*p)++;
v.b[2]=*(*p)++;
v.b[3]=*(*p)++;
#endif
return v.n;
}
#define SANITYMAXLEN (1<<20)
static char *loadstring(FILE *f)
{
ULONG l;
char buf[4], *p=buf;
if(1!=fread(buf, 4, 1, f) || (l=getu32(&p))>SANITYMAXLEN || !(p=malloc(l)))
return NULL;
fread(p, 1, l, f);
return p;
}
static char **loadtooltypes(FILE *f)
{
LONG i, n;
char **p, buf[4], *tp=buf;
if(1!=fread(buf, 4, 1, f) || (n=(getu32(&tp)>>2))>SANITYMAXLEN ||
!(p=calloc(n, sizeof(char *))))
return NULL;
--n;
for(i=0; i<n; i++)
if(!(p[i]=loadstring(f))) {
while(--i>=0)
free(p[i]);
free(p);
return NULL;
}
return p;
}
#define MAXICONSIZE 2000
static struct Image *loadimage(FILE *f)
{
char buf[20], *p=buf;
WORD le, te, w, h, d;
int imgsz;
struct Image *im;
if(1!=fread(buf, 20, 1, f))
return NULL;
le=get16(&p); te=get16(&p); w=get16(&p); h=get16(&p); d=get16(&p);
if(w<=0 || w>MAXICONSIZE || h<=0 || h>MAXICONSIZE || d<1 || d>8)
return NULL;
imgsz=2*((w+15)>>4)*h*d;
if(!(im=malloc(imgsz+sizeof(struct Image))))
return NULL;
im->LeftEdge=le; im->TopEdge=te; im->Width=w; im->Height=h;
im->Depth=d; im->ImageData=(UWORD*)getu32(&p);
im->PlanePick=*p++; im->PlaneOnOff=*p++;
im->NextImage=(struct Image *)getu32(&p);
if(im->ImageData) {
im->ImageData=(UWORD *)(im+1);
fread(im->ImageData, 1, imgsz, f);
}
return im;
}
static struct Image *backfillimage(struct Image *im)
{
return NULL;
}
#define GETBITS(v,n) do{if(bits<(n)){if(!srclen--)return dst-dst0;data=(data\
<<8)|*src++;bits+=8;};v=(data>>(bits-(n)))&((1<<(n))-1);bits-=(n);}while(0)
static LONG unpack_rle(unsigned char *src, LONG srclen, char *dst, LONG dstlen,
int bpp, int comp)
{
char *dst0 = dst;
unsigned char *srcn = src+srclen;
int bits=0, data=0;
if(!comp) {
if(srclen>dstlen)
srclen = dstlen;
memcpy(dst, src, srclen);
return srclen;
}
while(dstlen>0) {
int code;
GETBITS(code, 8);
if(code&0x80) {
char rpt;
GETBITS(rpt, bpp);
code -= 0x100;
if((dstlen-=(1-code))<0)
break;
do { *dst++ = rpt; } while(code++);
} else {
if((dstlen-=(code+1))<0)
break;
do GETBITS(*dst++, bpp); while(code--);
}
}
if(src != srcn)
fprintf(stderr, "Warning: Left %d bytes unused.\n", srcn-src);
return dst-dst0;
}
static void decode_IMAG(unsigned char *buf, LONG len, int width, int height,
APTR *im)
{
struct {
int transp, ncolors, flags, bodycomp, palcomp, bpp;
int bodybytes, palbytes;
} hdr;
char *dbuf;
struct Image *ii;
if(len<10)
return;
hdr.transp = *buf++;
hdr.ncolors = (*buf++)+1;
hdr.flags = *buf++;
hdr.bodycomp = *buf++;
hdr.palcomp = *buf++;
hdr.bpp = *buf++;
hdr.bodybytes = ((buf[0]<<8)|(buf[1]))+1;
hdr.palbytes = ((buf[2]<<8)|(buf[3]))+1;
buf+=4;
len -= 10;
if(!(hdr.flags&1))
hdr.transp = -1;
if(!(hdr.flags&2))
hdr.ncolors = 0;
if(hdr.bodybytes > len)
hdr.bodybytes = len;
if(hdr.palbytes+hdr.bodybytes > len)
hdr.palbytes = len-hdr.bodybytes;
if(hdr.bodycomp>1 || hdr.palcomp>1)
return;
if((dbuf = malloc(sizeof(struct Image)+width*height+3*hdr.ncolors+3))==NULL)
return;
/* body */
if(unpack_rle(buf, hdr.bodybytes, dbuf+sizeof(struct Image), width*height,
hdr.bpp, hdr.bodycomp) != width*height) {
free(dbuf);
return;
}
/* palette */
if(unpack_rle(buf+hdr.bodybytes, hdr.palbytes,
dbuf+sizeof(struct Image)+width*height+3, 3*hdr.ncolors,
8, hdr.palcomp) != 3*hdr.ncolors) {
free(dbuf);
return;
}
if(*im != NULL)
free(*im);
*im = (APTR) (ii = (struct Image *)dbuf);
dbuf += sizeof(struct Image);
ii->ImageData = (UWORD *)dbuf;
dbuf += width*height;
*dbuf++ = hdr.transp;
*dbuf++ = hdr.ncolors-1;
*dbuf++ = hdr.flags;
ii->LeftEdge = ii->TopEdge = 0;
ii->Width = width;
ii->Height = height;
ii->Depth = -1;
ii->PlanePick = ii->PlaneOnOff = 0;
ii->NextImage = NULL;
return;
}
static void decode_glowicon(struct DiskObject *diskobj, char *glow, LONG len)
{
int imgno=0, gotface=0;
struct { char width, height; UWORD dunno1, dunno2; } face;
while(len>=8) {
ULONG id = getu32(&glow);
LONG clen = get32(&glow);
char *chunk = glow;
len -= 8;
if(clen<0)
clen = len;
if(clen>len)
break;
switch(id) {
case 0x46414345: /* FACE */
if(clen>=6) {
face.width = 1+*chunk++;
face.height = 1+*chunk++;
face.dunno1 = getu16(&chunk);
face.dunno2 = getu16(&chunk);
gotface = 1;
diskobj->do_Gadget.Width = face.width;
diskobj->do_Gadget.Height = face.height;
break;
}
break;
case 0x494d4147: /* IMAG */
if(!gotface || imgno>1)
break;
decode_IMAG((unsigned char *)chunk, clen, face.width, face.height,
(imgno++? &diskobj->do_Gadget.SelectRender :
&diskobj->do_Gadget.GadgetRender));
break;
}
if(clen&1)
clen++;
len -= clen;
glow += clen;
}
}
static struct DiskObject *int_load_do(char *filename)
{
FILE *f;
struct DiskObject *diskobj;
char buf[78], *p=buf;
int error=0;
if((f=fopen(filename, "r"))) {
if(1==fread(buf, 78, 1, f) &&
(diskobj=calloc(1, sizeof(struct DiskObject)))) {
diskobj->do_Magic=getu16(&p); diskobj->do_Version=getu16(&p);
if(diskobj->do_Magic!=WB_DISKMAGIC) {
free(diskobj);
return NULL;
}
diskobj->do_Gadget.NextGadget=(struct Gadget *)getu32(&p);
diskobj->do_Gadget.LeftEdge=get16(&p);
diskobj->do_Gadget.TopEdge=get16(&p);
diskobj->do_Gadget.Width=get16(&p); diskobj->do_Gadget.Height=get16(&p);
diskobj->do_Gadget.Flags=getu16(&p);
diskobj->do_Gadget.Activation=getu16(&p);
diskobj->do_Gadget.GadgetType=getu16(&p);
diskobj->do_Gadget.GadgetRender=(APTR)getu32(&p);
diskobj->do_Gadget.SelectRender=(APTR)getu32(&p);
diskobj->do_Gadget.GadgetText=(struct IntuiText *)getu32(&p);
diskobj->do_Gadget.MutualExclude=get32(&p);
diskobj->do_Gadget.SpecialInfo=(APTR)getu32(&p);
diskobj->do_Gadget.GadgetID=getu16(&p);
diskobj->do_Gadget.UserData=(APTR)getu32(&p);
diskobj->do_Type=*p; p+=2;
diskobj->do_DefaultTool=(char *)getu32(&p);
diskobj->do_ToolTypes=(char **)getu32(&p);
diskobj->do_CurrentX=get32(&p);
diskobj->do_CurrentY=get32(&p);
diskobj->do_DrawerData=(struct DrawerData *)getu32(&p);
diskobj->do_ToolWindow=(char *)getu32(&p);
diskobj->do_StackSize=get32(&p);
if(diskobj->do_DrawerData) {
struct DrawerData *dd;
if(1==fread(buf, 56, 1, f) &&
(diskobj->do_DrawerData=dd=calloc(1, sizeof(struct DrawerData)))) {
p=buf;
dd->dd_NewWindow.LeftEdge=get16(&p);
dd->dd_NewWindow.TopEdge=get16(&p);
dd->dd_NewWindow.Width=get16(&p);
dd->dd_NewWindow.Height=get16(&p);
dd->dd_NewWindow.DetailPen=*p++;
dd->dd_NewWindow.BlockPen=*p++;
dd->dd_NewWindow.IDCMPFlags=getu32(&p);
dd->dd_NewWindow.Flags=getu32(&p);
dd->dd_NewWindow.FirstGadget=(struct Gadget *)getu32(&p);
dd->dd_NewWindow.CheckMark=(struct Image *)getu32(&p);
dd->dd_NewWindow.Title=(UBYTE *)getu32(&p);
dd->dd_NewWindow.Screen=(struct Screen *)getu32(&p);
dd->dd_NewWindow.BitMap=(struct BitMap *)getu32(&p);
dd->dd_NewWindow.MinWidth=get16(&p);
dd->dd_NewWindow.MinHeight=get16(&p);
dd->dd_NewWindow.MaxWidth=getu16(&p);
dd->dd_NewWindow.MaxHeight=getu16(&p);
dd->dd_NewWindow.Type=getu16(&p);
dd->dd_CurrentX=get32(&p);
dd->dd_CurrentY=get32(&p);
} else error++;
}
if(!(diskobj->do_Gadget.GadgetRender=loadimage(f)))
error++;
if(diskobj->do_Gadget.Flags&2)
if(!(diskobj->do_Gadget.SelectRender=loadimage(f)))
error++;
else ;
else if(diskobj->do_Gadget.Flags&1)
if(!(diskobj->do_Gadget.SelectRender=
backfillimage((struct Image *)diskobj->do_Gadget.GadgetRender)))
error++;
else ;
else diskobj->do_Gadget.SelectRender=NULL;
if(diskobj->do_DefaultTool)
if(!(diskobj->do_DefaultTool=loadstring(f)))
error++;
if(diskobj->do_ToolTypes)
if(!(diskobj->do_ToolTypes=loadtooltypes(f)))
error++;
if(diskobj->do_ToolWindow)
if(!(diskobj->do_ToolWindow=loadstring(f)))
error++;
if(diskobj->do_DrawerData && diskobj->do_Version) {
char buf[6], *p=buf;
if(1==fread(buf, 6, 1, f)) {
diskobj->do_DrawerData->dd_Flags=getu32(&p);
diskobj->do_DrawerData->dd_ViewModes=getu16(&p);
}
}
if(diskobj->do_Version) {
/* Check for GlowIcon */
char buf[8], *p = buf, *glowicon;
LONG len;
if(1==fread(buf, 4, 1, f) && !strncmp(buf, "FORM", 4) &&
1==fread(buf, 8, 1, f) && !strncmp(buf+4, "ICON", 4) &&
(len = get32(&p))>4 && (glowicon = malloc(len))!=NULL) {
if(1==fread(glowicon, len-4, 1, f))
decode_glowicon(diskobj, glowicon, len-4);
free(glowicon);
}
}
if(!error) {
fclose(f);
return diskobj;
}
FreeDiskObject(diskobj);
}
fclose(f);
}
return NULL;
}
struct DiskObject *GetDefDiskObject(LONG def_type)
{
static char *defnames[]= {
"disk", "drawer", "tool", "project",
"garbage", "device", "kick", "appicon"
};
static char *icondir=NULL;
static int l;
char *buf;
struct DiskObject *diskobj;
if(def_type<WBDISK || def_type>WBAPPICON)
return NULL;
if(!icondir)
if(!(icondir = get_current_icondir()))
return NULL;
else
l = strlen(icondir);
#ifdef HAVE_ALLOCA
buf = alloca(l+18);
#else
buf = malloc(l+18);
if(buf==NULL) return NULL;
#endif
sprintf(buf, "%s/def_%s.info", icondir, defnames[def_type-WBDISK]);
diskobj=int_load_do(buf);
#ifndef HAVE_ALLOCA
free(buf);
#endif
return diskobj;
}
struct DiskObject *GetDiskObject(char *name)
{
struct DiskObject *diskobj;
#ifdef HAVE_ALLOCA
char *buf = alloca(strlen(name)+6);
#else
char *buf = malloc(strlen(name)+6);
if(buf==NULL) return NULL;
#endif
sprintf(buf, "%s.info", name);
diskobj=int_load_do(buf);
#ifndef HAVE_ALLOCA
free(buf);
#endif
return diskobj;
}
struct DiskObject *GetDiskObjectNew(char *name)
{
struct DiskObject *d;
struct stat st;
if((d=GetDiskObject(name))) return d;
if(stat(name, &st)<0) return NULL;
if(S_ISREG(st.st_mode))
if(st.st_mode&0555)
return GetDefDiskObject(WBTOOL);
else
return GetDefDiskObject(WBPROJECT);
else if(S_ISDIR(st.st_mode))
return GetDefDiskObject(WBDRAWER);
else if(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
return GetDefDiskObject(WBDEVICE);
else
return NULL;
}
#ifdef notdef
BOOL MatchToolValue(char *typeString, char *value)
{
}
BOOL PutDiskObject(char *name, struct DiskObject *diskobj)
{
}
#endif
#endif

126
libami/iconutil.c Normal file
View File

@@ -0,0 +1,126 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include "libami.h"
#include "alloc.h"
#include "drawinfo.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
Pixmap image_to_pixmap(Display *dpy, Window win, GC gc, unsigned long bg,
unsigned long *iconcolor, int iconcolormask,
struct Image *im, int width, int height,
struct ColorStore *cs)
{
int bpr, bitmap_pad, x, y;
XImage *ximg;
unsigned char *img;
Pixmap pm;
XWindowAttributes attr;
int fail=0;
if(!dpy || !win || !gc || !im || !(img=(unsigned char *)im->ImageData))
return None;
if(width<=0) width=im->Width;
if(height<=0) height=im->Height;
XGetWindowAttributes(dpy, win, &attr);
bpr=2*((im->Width+15)>>4);
if (attr.depth > 16)
bitmap_pad = 32;
else if (attr.depth > 8)
bitmap_pad = 16;
else
bitmap_pad = 8;
ximg=XCreateImage(dpy, attr.visual, attr.depth, ZPixmap, 0, NULL,
im->Width, im->Height, bitmap_pad, 0);
#ifndef HAVE_ALLOCA
if(!(ximg->data = malloc(ximg->bytes_per_line * im->Height))) {
XDestroyImage(ximg);
return None;
}
#else
ximg->data = alloca(ximg->bytes_per_line * im->Height);
#endif
if(im->Depth==-1) {
int transp, ncolors, flags;
unsigned char *pal = img + im->Width * im->Height;
unsigned long ic[256];
transp = *pal++;
ncolors = 1+*pal++;
flags = *pal++;
if(!(flags&1))
transp = -1;
if(!(flags&2))
ncolors = 0;
memset(ic, 0, sizeof(ic));
if(!ncolors) {
if(cs) cs->colors = NULL;
} else if(!cs || !(cs->colors = calloc(ncolors, sizeof(unsigned long)))) {
ncolors = 0;
fail = 1;
}
for(x=0; x<ncolors; x++) {
XColor color;
color.pixel = 0;
color.red = (*pal++)*0x101;
color.green = (*pal++)*0x101;
color.blue = (*pal++)*0x101;
color.flags = DoRed|DoGreen|DoBlue;
XAllocColor(dpy, attr.colormap, &color);
ic[x] = color.pixel;
}
if(cs) {
cs->cmap = attr.colormap;
cs->ncolors = ncolors;
if(ncolors) memcpy(cs->colors, ic, ncolors*sizeof(unsigned long));
}
for(y=0; y<im->Height; y++)
for(x=0; x<im->Width; x++)
XPutPixel(ximg, x, y, ic[*img++]);
} else
for(y=0; y<im->Height; y++)
for(x=0; x<im->Width; x++) {
unsigned char b=1, v=im->PlaneOnOff&~(im->PlanePick);
INT16 p=0;
while(p<im->Depth && b) {
if(b&im->PlanePick)
if(img[(p++*im->Height+y)*bpr+(x>>3)]&(128>>(x&7)))
v|=b;
b<<=1;
}
XPutPixel(ximg, x, y, iconcolor[v&iconcolormask]);
}
if((pm=(fail?None:XCreatePixmap(dpy, win, width, height, attr.depth)))) {
XSetForeground(dpy, gc, bg);
XFillRectangle(dpy, pm, gc, 0, 0, width, height);
XPutImage(dpy, pm, gc, ximg, 0, 0, im->LeftEdge, im->TopEdge,
im->Width, im->Height);
}
#ifndef HAVE_ALLOCA
free(ximg->data);
#endif
ximg->data=NULL;
XDestroyImage(ximg);
if(pm == None)
free_color_store(dpy, cs);
return pm;
}
void free_color_store(Display *dpy, struct ColorStore *cs)
{
if(cs && cs->colors) {
XFreeColors(dpy, cs->cmap, cs->colors, cs->ncolors, 0);
free(cs->colors);
cs->colors = NULL;
}
}

163
libami/iffparse.c Normal file
View File

@@ -0,0 +1,163 @@
#include "libami.h"
#include "alloc.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
#ifndef AMIGAOS
static LONG callIFFHook(struct IFFHandle *iff, LONG cmd, APTR buf, LONG nby)
{
struct IFFStreamCmd c;
c.sc_Command = cmd;
c.sc_Buf = buf;
c.sc_NBytes = nby;
if(iff->iff_Hook == NULL)
return IFFERR_NOHOOK;
else
return iff->iff_Hook->h_SubEntry(iff->iff_Hook, iff, &c);
}
LONG ReadChunkBytes( struct IFFHandle *iff, APTR buf, long numBytes );
LONG WriteChunkBytes( struct IFFHandle *iff, APTR buf, long numBytes );
LONG ReadChunkRecords( struct IFFHandle *iff, APTR buf, long bytesPerRecord,
long numRecords );
LONG WriteChunkRecords( struct IFFHandle *iff, APTR buf, long bytesPerRecord,
long numRecords );
LONG PushChunk( struct IFFHandle *iff, long type, long id, long size );
LONG PopChunk( struct IFFHandle *iff );
LONG EntryHandler( struct IFFHandle *iff, long type, long id, long position,
struct Hook *handler, APTR object );
LONG ExitHandler( struct IFFHandle *iff, long type, long id, long position,
struct Hook *handler, APTR object );
LONG PropChunk( struct IFFHandle *iff, long type, long id );
LONG PropChunks( struct IFFHandle *iff, LONG *propArray, long numPairs );
LONG StopChunk( struct IFFHandle *iff, long type, long id );
LONG StopChunks( struct IFFHandle *iff, LONG *propArray, long numPairs );
LONG CollectionChunk( struct IFFHandle *iff, long type, long id );
LONG CollectionChunks( struct IFFHandle *iff, LONG *propArray,
long numPairs );
LONG StopOnExit( struct IFFHandle *iff, long type, long id );
struct StoredProperty *FindProp( struct IFFHandle *iff, long type, long id );
struct CollectionItem *FindCollection( struct IFFHandle *iff, long type,
long id );
struct ContextNode *FindPropContext( struct IFFHandle *iff );
struct ContextNode *CurrentChunk( struct IFFHandle *iff );
struct ContextNode *ParentChunk( struct ContextNode *contextNode );
struct LocalContextItem *AllocLocalItem( long type, long id, long ident,
long dataSize );
APTR LocalItemData( struct LocalContextItem *localItem );
void SetLocalItemPurge( struct LocalContextItem *localItem,
struct Hook *purgeHook );
void FreeLocalItem( struct LocalContextItem *localItem );
struct LocalContextItem *FindLocalItem( struct IFFHandle *iff, long type,
long id, long ident );
LONG StoreLocalItem( struct IFFHandle *iff, struct LocalContextItem *localItem,
long position );
void StoreItemInContext( struct IFFHandle *iff,
struct LocalContextItem *localItem,
struct ContextNode *contextNode );
LONG GoodID( long id );
LONG GoodType( long type );
STRPTR IDtoStr( long id, STRPTR buf );
void InitIFF( struct IFFHandle *iff, long flags, struct Hook *streamHook )
{
iff->iff_Flags = flags;
iff->iff_Hook = streamHook;
}
struct IFFHandle *AllocIFF( void )
{
return (struct IFFHandle *)calloc(1, sizeof(struct IFFHandle));
}
LONG OpenIFF( struct IFFHandle *iff, long rwMode )
{
return callIFFHook(iff, IFFCMD_INIT, NULL, 0);
}
LONG ParseIFF( struct IFFHandle *iff, long control )
{
return IFFERR_NOHOOK;
}
void CloseIFF( struct IFFHandle *iff )
{
callIFFHook(iff, IFFCMD_CLEANUP, NULL, 0);
}
void FreeIFF( struct IFFHandle *iff )
{
free(iff);
}
#else
static ULONG __saveds __asm hllDispatch(register __a0 struct Hook *hook,
register __a2 APTR object,
register __a1 APTR message)
{
return ((ULONG (*)(struct Hook *, APTR, APTR))hook->h_SubEntry)
(hook, object, message);
}
#endif
static ULONG iffFileHook(struct Hook *hook, APTR object, APTR message)
{
struct IFFStreamCmd *cmd = (struct IFFStreamCmd *)message;
switch(cmd->sc_Command) {
case IFFCMD_INIT:
return 0;
case IFFCMD_CLEANUP:
close(((struct IFFHandle *)object)->iff_Stream);
return 0;
case IFFCMD_READ:
return IFFERR_READ;
case IFFCMD_WRITE:
return IFFERR_WRITE;
case IFFCMD_SEEK:
return IFFERR_SEEK;
}
return 0;
}
LONG OpenIFFasFile( struct IFFHandle *iff, char *fn, char *mode )
{
static struct Hook hook =
#ifdef AMIGAOS
{ { 0, 0 }, hllDispatch, iffFileHook, 0 };
#else
{ { 0, 0 }, 0, iffFileHook, 0 };
#endif
int m, fd;
LONG r;
if((fd = open(fn, (strchr(mode, 'w')==NULL? O_RDONLY :
(O_WRONLY|O_TRUNC|O_CREAT)), 0666))<0)
return IFFERR_READ;
iff->iff_Stream = fd;
InitIFF( iff, (strchr(mode, 'w')==NULL? (m=IFFF_READ|IFFF_RSEEK) :
(m=IFFF_WRITE|IFFF_RSEEK)), &hook );
if((r=OpenIFF( iff, m ))!=0) {
close(fd);
return r;
}
return 0;
}

23
libami/kbdsupport.c Normal file
View File

@@ -0,0 +1,23 @@
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdlib.h>
#include <string.h>
#include "libami.h"
#include "module.h"
int md_grabkey(int keycode, unsigned int modifiers)
{
int pkt[2], res=-1;
char *ptr=NULL;
pkt[0]=keycode; pkt[1]=modifiers;
if(md_command(None, MCMD_ADD_KEYGRAB, pkt, sizeof(pkt), &ptr)>=sizeof(int))
res=*((int*)ptr);
if(ptr) free(ptr);
return res;
}
int md_ungrabkey(int id)
{
return md_command0(None, MCMD_DEL_KEYGRAB, &id, sizeof(id));
}

BIN
libami/libami.a Normal file

Binary file not shown.

393
libami/libami.h Normal file
View File

@@ -0,0 +1,393 @@
#ifndef LIBAMI_H
#define LIBAMI_H
#include <X11/Xlib.h>
#include <X11/Xmd.h>
#ifdef AMIGAOS
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <utility/hooks.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/iffparse.h>
#include <proto/locale.h>
#else
#define GLOBAL extern
#define IMPORT extern
#define STATIC static
#define REGISTER register
#ifndef VOID
#define VOID void
#endif
#ifndef BYTE
#define BYTE Amiga_BYTE
#endif
#ifndef BOOL
#define BOOL Amiga_BOOL
#endif
typedef void *APTR;
typedef INT32 LONG;
typedef CARD32 ULONG;
typedef BITS32 LONGBITS;
typedef INT16 WORD;
typedef CARD16 UWORD;
typedef BITS16 WORDBITS;
typedef INT8 BYTE;
typedef CARD8 UBYTE;
typedef CARD8 BYTEBITS;
typedef CARD16 RPTR;
typedef unsigned char *STRPTR;
typedef INT16 BOOL;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0L
#endif
#define WF_NOICONIFY 1
struct Node {
struct Node *ln_Succ;
struct Node *ln_Pred;
UBYTE ln_Type;
BYTE ln_Pri;
char *ln_Name;
};
struct MinNode {
struct MinNode *mln_Succ;
struct MinNode *mln_Pred;
};
struct List {
struct Node *lh_Head;
struct Node *lh_Tail;
struct Node *lh_TailPred;
UBYTE lh_Type;
UBYTE l_pad;
};
struct MinList {
struct MinNode *mlh_Head;
struct MinNode *mlh_Tail;
struct MinNode *mlh_TailPred;
};
extern void AddHead(struct List *, struct Node *);
extern void AddTail(struct List *, struct Node *);
extern void Enqueue(struct List *, struct Node *);
extern struct Node *FindName(struct List *, STRPTR);
extern void Insert(struct List *, struct Node *, struct Node *);
extern struct Node *RemHead(struct List *);
extern void Remove(struct Node *);
extern struct Node *RemTail(struct List *);
extern void NewList(struct List *);
struct CSource {
UBYTE *CS_Buffer;
LONG CS_Length;
LONG CS_CurChr;
};
struct RDArgs {
struct CSource RDA_Source;
void *RDA_DAList;
UBYTE *RDA_Buffer;
LONG RDA_BufSiz;
UBYTE *RDA_ExtHelp;
LONG RDA_Flags;
};
struct Image
{
WORD LeftEdge, TopEdge, Width, Height, Depth;
UWORD *ImageData;
UBYTE PlanePick, PlaneOnOff;
struct Image *NextImage;
};
struct Gadget
{
struct Gadget *NextGadget;
WORD LeftEdge, TopEdge, Width, Height;
UWORD Flags, Activation, GadgetType;
APTR GadgetRender, SelectRender;
struct IntuiText *GadgetText;
LONG MutualExclude;
APTR SpecialInfo;
UWORD GadgetID;
APTR UserData;
};
struct NewWindow
{
WORD LeftEdge, TopEdge, Width, Height;
UBYTE DetailPen, BlockPen;
ULONG IDCMPFlags, Flags;
struct Gadget *FirstGadget;
struct Image *CheckMark;
UBYTE *Title;
struct Screen *Screen;
struct BitMap *BitMap;
WORD MinWidth, MinHeight;
UWORD MaxWidth, MaxHeight;
UWORD Type;
};
struct DrawerData {
struct NewWindow dd_NewWindow;
LONG dd_CurrentX;
LONG dd_CurrentY;
ULONG dd_Flags;
UWORD dd_ViewModes;
};
struct DiskObject {
UWORD do_Magic;
UWORD do_Version;
struct Gadget do_Gadget;
UBYTE do_Type;
char *do_DefaultTool;
char **do_ToolTypes;
LONG do_CurrentX;
LONG do_CurrentY;
struct DrawerData *do_DrawerData;
char *do_ToolWindow;
LONG do_StackSize;
};
struct Hook
{
struct MinNode h_MinNode;
ULONG (*h_Entry)(); /* assembler entry point */
ULONG (*h_SubEntry)(); /* often HLL entry point */
APTR h_Data; /* owner specific */
};
struct IFFHandle
{
ULONG iff_Stream;
ULONG iff_Flags;
LONG iff_Depth; /* Depth of context stack */
/* private fields */
struct Hook *iff_Hook;
};
struct IFFStreamCmd
{
LONG sc_Command; /* Operation to be performed (IFFCMD_) */
APTR sc_Buf; /* Pointer to data buffer */
LONG sc_NBytes; /* Number of bytes to be affected */
};
#define RDAB_STDIN 0 /* Use "STDIN" rather than "COMMAND LINE" */
#define RDAF_STDIN 1
#define RDAB_NOALLOC 1 /* If set, do not allocate extra string space.*/
#define RDAF_NOALLOC 2
#define RDAB_NOPROMPT 2 /* Disable reprompting for string input. */
#define RDAF_NOPROMPT 4
#define ITEM_EQUAL -2 /* "=" Symbol */
#define ITEM_ERROR -1 /* error */
#define ITEM_NOTHING 0 /* *N, ;, endstreamch */
#define ITEM_UNQUOTED 1 /* unquoted item */
#define ITEM_QUOTED 2 /* quoted item */
#define MAX_TEMPLATE_ITEMS 100
#define MAX_MULTIARGS 128
#define ERROR_NO_FREE_STORE 103
#define ERROR_BAD_TEMPLATE 114
#define ERROR_BAD_NUMBER 115
#define ERROR_REQUIRED_ARG_MISSING 116
#define ERROR_KEY_NEEDS_ARG 117
#define ERROR_TOO_MANY_ARGS 118
#define ERROR_LINE_TOO_LONG 120
#define IFFERR_EOF -1L /* Reached logical end of file */
#define IFFERR_EOC -2L /* About to leave context */
#define IFFERR_NOSCOPE -3L /* No valid scope for property */
#define IFFERR_NOMEM -4L /* Internal memory alloc failed */
#define IFFERR_READ -5L /* Stream read error */
#define IFFERR_WRITE -6L /* Stream write error */
#define IFFERR_SEEK -7L /* Stream seek error */
#define IFFERR_MANGLED -8L /* Data in file is corrupt */
#define IFFERR_SYNTAX -9L /* IFF syntax error */
#define IFFERR_NOTIFF -10L /* Not an IFF file */
#define IFFERR_NOHOOK -11L /* No call-back hook provided */
#define IFF_RETURN2CLIENT -12L /* Client handler normal return */
#define IFFF_READ 0L /* read mode - default */
#define IFFF_WRITE 1L /* write mode */
#define IFFF_RWBITS (IFFF_READ | IFFF_WRITE) /* read/write bits */
#define IFFF_FSEEK (1L<<1) /* forward seek only */
#define IFFF_RSEEK (1L<<2) /* random seek */
#define IFFF_RESERVED 0xFFFF0000L /* Don't touch these bits */
#define IFFCMD_INIT 0 /* Prepare the stream for a session */
#define IFFCMD_CLEANUP 1 /* Terminate stream session */
#define IFFCMD_READ 2 /* Read bytes from stream */
#define IFFCMD_WRITE 3 /* Write bytes to stream */
#define IFFCMD_SEEK 4 /* Seek on stream */
#define IFFCMD_ENTRY 5 /* You just entered a new context */
#define IFFCMD_EXIT 6 /* You're about to leave a context */
#define IFFCMD_PURGELCI 7 /* Purge a LocalContextItem */
extern void FreeArgs(struct RDArgs *);
extern LONG ReadItem(STRPTR, LONG, struct CSource *);
extern LONG FindArg(STRPTR, STRPTR);
extern struct RDArgs * ReadArgs(STRPTR, LONG *, struct RDArgs *);
extern UBYTE ToUpper(UBYTE);
extern LONG StrToLong(STRPTR, LONG *);
extern LONG Stricmp(STRPTR, STRPTR);
extern char *BumpRevision(char *, char *);
extern BOOL DeleteDiskObject(char *);
extern void FreeDiskObject(struct DiskObject *);
extern struct DiskObject *GetDefDiskObject(LONG);
extern struct DiskObject *GetDiskObject(char *);
extern struct DiskObject *GetDiskObjectNew(char *);
extern BOOL MatchToolValue(char *, char *);
extern BOOL PutDiskObject(char *, struct DiskObject *);
extern BOOL Fault(LONG, UBYTE *, UBYTE *, LONG);
extern BOOL PrintFault(LONG, UBYTE *);
extern LONG IoErr();
extern LONG SetIoErr(LONG);
extern struct IFFHandle *AllocIFF( void );
extern LONG OpenIFF( struct IFFHandle *iff, long rwMode );
extern LONG ParseIFF( struct IFFHandle *iff, long control );
extern void CloseIFF( struct IFFHandle *iff );
extern void FreeIFF( struct IFFHandle *iff );
extern LONG ReadChunkBytes( struct IFFHandle *iff, APTR buf, long numBytes );
extern LONG WriteChunkBytes( struct IFFHandle *iff, APTR buf, long numBytes );
extern LONG ReadChunkRecords( struct IFFHandle *iff, APTR buf, long bytesPerRecord, long numRecords );
extern LONG WriteChunkRecords( struct IFFHandle *iff, APTR buf, long bytesPerRecord, long numRecords );
extern LONG PushChunk( struct IFFHandle *iff, long type, long id, long size );
extern LONG PopChunk( struct IFFHandle *iff );
extern LONG EntryHandler( struct IFFHandle *iff, long type, long id, long position, struct Hook *handler, APTR object );
extern LONG ExitHandler( struct IFFHandle *iff, long type, long id, long position, struct Hook *handler, APTR object );
extern LONG PropChunk( struct IFFHandle *iff, long type, long id );
extern LONG PropChunks( struct IFFHandle *iff, LONG *propArray, long numPairs );
extern LONG StopChunk( struct IFFHandle *iff, long type, long id );
extern LONG StopChunks( struct IFFHandle *iff, LONG *propArray, long numPairs );
extern LONG CollectionChunk( struct IFFHandle *iff, long type, long id );
extern LONG CollectionChunks( struct IFFHandle *iff, LONG *propArray, long numPairs );
extern LONG StopOnExit( struct IFFHandle *iff, long type, long id );
extern struct StoredProperty *FindProp( struct IFFHandle *iff, long type, long id );
extern struct CollectionItem *FindCollection( struct IFFHandle *iff, long type, long id );
extern struct ContextNode *FindPropContext( struct IFFHandle *iff );
extern struct ContextNode *CurrentChunk( struct IFFHandle *iff );
extern struct ContextNode *ParentChunk( struct ContextNode *contextNode );
extern struct LocalContextItem *AllocLocalItem( long type, long id, long ident, long dataSize );
extern APTR LocalItemData( struct LocalContextItem *localItem );
extern void SetLocalItemPurge( struct LocalContextItem *localItem, struct Hook *purgeHook );
extern void FreeLocalItem( struct LocalContextItem *localItem );
extern struct LocalContextItem *FindLocalItem( struct IFFHandle *iff, long type, long id, long ident );
extern LONG StoreLocalItem( struct IFFHandle *iff, struct LocalContextItem *localItem, long position );
extern void StoreItemInContext( struct IFFHandle *iff, struct LocalContextItem *localItem, struct ContextNode *contextNode );
extern void InitIFF( struct IFFHandle *iff, long flags, struct Hook *streamHook );
extern LONG GoodID( long id );
extern LONG GoodType( long type );
extern STRPTR IDtoStr( long id, STRPTR buf );
#endif
extern LONG OpenIFFasFile( struct IFFHandle *iff, char *fn, char *mode );
struct ColorStore { unsigned long *colors; int ncolors; Colormap cmap; };
extern Pixmap image_to_pixmap(Display *, Window, GC, unsigned long,
unsigned long *, int, struct Image *, int, int,
struct ColorStore *);
extern void free_color_store(Display *, struct ColorStore *);
typedef union { LONG num; APTR ptr; } Argtype;
extern void initargs(int, char **);
extern char *amiwm_version;
extern int md_fd;
extern Window md_root;
#define WINDOW_EVENT(e) ((e)->xany.display==(Display *)1)
#define FRAME_EVENT(e) ((e)->xany.display==(Display *)2)
#define ICON_EVENT(e) ((e)->xany.display==(Display *)3)
#define IN_ROOT_MASK 1
#define IN_WINDOW_MASK 2
#define IN_FRAME_MASK 4
#define IN_ICON_MASK 8
#define IN_ANYTHING_MASK (~0)
/* module.c */
extern void md_exit(int);
extern int md_handle_input(void);
extern void md_process_queued_events(void);
extern void md_main_loop(void);
extern int md_connection_number(void);
extern int md_command(XID, int, void *, int, char **);
extern int md_command0(XID, int, void *, int);
extern int md_command00(XID, int);
extern Display *md_display(void);
extern char *md_init(int, char *[]);
/* broker.c */
extern int cx_broker(unsigned long, void (*)(XEvent *, unsigned long));
extern int cx_send_event(unsigned long, XEvent *);
/* mdscreen.c */
extern int md_rotate_screen(Window);
extern int md_front(Window);
extern int md_back(Window);
extern int md_iconify(Window);
extern int md_errormsg(Window, char *);
/* eventdispatcher.c */
extern void cx_event_broker(int, unsigned long, int (*)(XEvent*));
/* kbdsupport.c */
extern int md_grabkey(int, unsigned int);
extern int md_ungrabkey(int);
/* hotkey.c */
extern void cx_hotkey(KeySym, unsigned int, int, int,
void (*)(XEvent*,void*), void*);
/* mdicon.c */
extern Window md_create_appicon(Window, int, int, char *,
Pixmap, Pixmap, Pixmap);
extern Pixmap md_image_to_pixmap(Window, unsigned long, struct Image *,
int, int, struct ColorStore *);
extern char *get_current_icondir(void);
/* mdwindow.c */
extern int md_set_appwindow(Window);
#endif

85
libami/lists.c Normal file
View File

@@ -0,0 +1,85 @@
#include "libami.h"
#ifndef AMIGAOS
void NewList(struct List *list)
{
list->lh_TailPred = (struct Node *)&list->lh_Head;
list->lh_Tail = NULL;
list->lh_Head = (struct Node *)&list->lh_Tail;
}
void AddHead(struct List *list, struct Node *node)
{
struct Node *oldhead = list->lh_Head;
list->lh_Head = node;
node->ln_Succ = oldhead;
node->ln_Pred = (struct Node *)&list->lh_Head;
oldhead->ln_Pred = node;
}
void AddTail(struct List *list, struct Node *node)
{
struct Node *oldtail = list->lh_TailPred;
list->lh_TailPred = node;
node->ln_Succ = (struct Node *)&list->lh_Tail;
node->ln_Pred = oldtail;
oldtail->ln_Succ = node;
}
struct Node *RemHead(struct List *list)
{
struct Node *node = list->lh_Head;
if(node->ln_Succ) {
list->lh_Head = node->ln_Succ;
node->ln_Succ->ln_Pred = (struct Node *)&list->lh_Head;
return node;
} else return NULL;
}
struct Node *RemTail(struct List *list)
{
struct Node *node = list->lh_TailPred;
if(node->ln_Pred) {
list->lh_TailPred = node->ln_Pred;
node->ln_Pred->ln_Succ = (struct Node *)&list->lh_Tail;
return node;
} else return NULL;
}
void Insert(struct List *list, struct Node *node, struct Node *after)
{
if(!after) after = (struct Node *)&list->lh_Head;
node->ln_Succ = after->ln_Succ;
node->ln_Pred = after;
after->ln_Succ->ln_Pred = node;
after->ln_Succ = node;
}
void Remove(struct Node *node)
{
node->ln_Pred->ln_Succ = node->ln_Succ;
node->ln_Succ->ln_Pred = node->ln_Pred;
}
void Enqueue(struct List *list, struct Node *node)
{
struct Node *before = list->lh_Head;
while(before->ln_Succ && before->ln_Pri >= node->ln_Pri)
before = before->ln_Succ;
node->ln_Succ = before;
node->ln_Pred = before->ln_Pred;
before->ln_Pred->ln_Succ = node;
before->ln_Pred = node;
}
struct Node *FindName(struct List *list, STRPTR name)
{
struct Node *node;
for(node = list->lh_Head; node->ln_Succ; node = node->ln_Succ)
if(!strcmp((char *)name, node->ln_Name))
return node;
return NULL;
}
#endif

71
libami/mdicon.c Normal file
View File

@@ -0,0 +1,71 @@
#include <stdlib.h>
#include <string.h>
#include "libami.h"
#include "module.h"
#include "alloc.h"
Window md_create_appicon(Window p, int x, int y, char *name,
Pixmap pm1, Pixmap pm2, Pixmap pmm)
{
char *data;
Window w;
int res, l=strlen(name);
#ifdef HAVE_ALLOCA
struct NewAppIcon *nai=alloca(sizeof(struct NewAppIcon)+l);
#else
struct NewAppIcon *nai=malloc(sizeof(struct NewAppIcon)+l);
if(nai==NULL) return None;
#endif
nai->x=x; nai->y=y;
nai->pm1=pm1; nai->pm2=pm2; nai->pmm=pmm;
strcpy(nai->name, name);
res=md_command(p, MCMD_CREATEAPPICON, nai, sizeof(struct NewAppIcon)+l,
&data);
if(res<sizeof(w)) {
if(data) free(data);
#ifndef HAVE_ALLOCA
free(nai);
#endif
return None;
}
memcpy(&w, data, sizeof(w));
free(data);
#ifndef HAVE_ALLOCA
free(nai);
#endif
return w;
}
Pixmap md_image_to_pixmap(Window w, unsigned long bgcolor, struct Image *i,
int width, int height, struct ColorStore *cs)
{
Display *dpy = md_display();
static GC gc = None;
Pixmap pm;
static int iconcolormask;
static unsigned long *iconcolor = NULL;
if(gc == None && w != None)
gc = XCreateGC(dpy, w, 0, NULL);
if(iconcolor == NULL) {
char *p;
int res = md_command(w, MCMD_GETICONPALETTE, NULL, 0, &p);
if(res<0)
return None;
iconcolor = (unsigned long *)(void *)p;
iconcolormask = (res/sizeof(unsigned long))-1;
}
pm = image_to_pixmap(md_display(), w, gc, bgcolor, iconcolor, iconcolormask,
i, width, height, cs);
return pm;
}
char *get_current_icondir()
{
char *p;
if(md_command(None, MCMD_GETICONDIR, NULL, 0, &p)>=0 && p)
return p;
if(p) free(p);
return NULL;
}

35
libami/mdscreen.c Normal file
View File

@@ -0,0 +1,35 @@
#include "libami.h"
#include "module.h"
#include <string.h>
int md_rotate_screen(XID id)
{
return md_command00(id, MCMD_ROTATE_SCREEN);
}
int md_front(XID id)
{
return md_command00(id, MCMD_FRONT);
}
int md_back(XID id)
{
return md_command00(id, MCMD_BACK);
}
int md_iconify(XID id)
{
return md_command00(id, MCMD_ICONIFY);
}
int md_errormsg(Window id, char *str)
{
return md_command0(id, MCMD_ERRORMSG, str, strlen(str));
}
int md_managemenu(Window id, int menu, int item, int subitem)
{
int data[3];
data[0]=menu; data[1]=item; data[2]=subitem;
return md_command0(id, MCMD_MANAGEMENU, data, sizeof(data));
}

7
libami/mdwindow.c Normal file
View File

@@ -0,0 +1,7 @@
#include "libami.h"
#include "module.h"
int md_set_appwindow(Window w)
{
return md_command00(w, MCMD_SETAPPWINDOW);
}

236
libami/module.c Normal file
View File

@@ -0,0 +1,236 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <signal.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "libami.h"
#include "module.h"
#include "alloc.h"
static int md_in_fd=-1, md_out_fd=-1;
static char *md_name = "";
char *amiwm_version;
Window md_root = None;
static int md_int_len=0;
static char *md_int_buf=NULL;
void (*md_broker_func)(XEvent *, unsigned long);
void md_exit(int signal)
{
if(md_in_fd>=0)
close(md_in_fd);
if(md_out_fd>=0)
close(md_out_fd);
exit(0);
}
static int md_write(void *ptr, int len)
{
char *p=ptr;
int r, tot=0;
while(len>0) {
if((r=write(md_out_fd, p, len))<0)
if(errno==EINTR)
continue;
else
return r;
if(!r)
return tot;
tot+=r;
p+=r;
len-=r;
}
return tot;
}
static int md_read(void *ptr, int len)
{
char *p=ptr;
int r, tot=0;
while(len>0) {
if((r=read(md_in_fd, p, len))<0)
if(errno==EINTR)
continue;
else
return r;
if(!r)
if(tot)
return tot;
else
md_exit(0);
tot+=r;
p+=r;
len-=r;
}
return tot;
}
static int md_int_load(int len)
{
if(len>=md_int_len)
if(md_int_buf!=NULL)
md_int_buf=realloc(md_int_buf, md_int_len=len+1);
else
md_int_buf=malloc(md_int_len=len+1);
md_int_buf[len]='\0';
return md_read(md_int_buf, len);
}
static struct md_queued_event {
struct md_queued_event *next;
struct mcmd_event e;
} *event_head=NULL, *event_tail=NULL;
void md_process_queued_events()
{
struct md_queued_event *e;
while((e=event_head)) {
event_head=e->next;
md_broker_func(&e->e.event, e->e.mask);
free(e);
}
}
static void md_enqueue(struct mcmd_event *e)
{
struct md_queued_event *qe=malloc(sizeof(struct md_queued_event));
if(qe) {
qe->e=*e;
qe->next=NULL;
if(event_head) {
event_tail->next=qe;
event_tail=qe;
} else {
event_head=event_tail=qe;
}
}
}
static int md_get_async(int len)
{
if(md_int_load(len)!=len)
return -1;
if(md_broker_func)
md_enqueue((struct mcmd_event *)md_int_buf);
return 1;
}
int md_handle_input()
{
int res;
if(md_read(&res, sizeof(res))!=sizeof(res))
return -1;
if(res>=0) {
if(!res)
return 0;
md_int_load(res);
return 0;
} else {
res=~res;
if(!res)
return 0;
return md_get_async(res);
}
}
int md_command(XID id, int cmd, void *data, int data_len, char **buffer)
{
int res;
struct mcmd_header mcmd;
*buffer=NULL;
mcmd.id = id;
mcmd.cmd = cmd;
mcmd.len = data_len;
if(md_write(&mcmd, sizeof(mcmd))!=sizeof(mcmd) ||
md_write(data, data_len)!=data_len ||
md_read(&res, sizeof(res))!=sizeof(res))
return -1;
while(res<-1) {
md_get_async(~res);
if(md_read(&res, sizeof(res))!=sizeof(res))
return -1;
}
if(res>0) {
*buffer=malloc(res);
if(md_read(*buffer, res)!=res)
return -1;
}
return res;
}
int md_command0(XID id, int cmd, void *data, int data_len)
{
char *ptr=NULL;
int res=md_command(id, cmd, data, data_len, &ptr);
if(ptr) free(ptr);
return res;
}
int md_command00(XID id, int cmd)
{
return md_command0(id, cmd, NULL, 0);
}
static void md_fail()
{
fprintf(stderr, "%s: cannot establish connection to amiwm\n", md_name);
exit(1);
}
Display *md_display()
{
static Display *dpy=NULL;
if(!dpy)
dpy=XOpenDisplay(NULL);
return dpy;
}
char *md_init(int argc, char *argv[])
{
if(argc>0)
md_name=argv[0];
if(argc>2) {
md_in_fd=strtol(argv[1], NULL, 0);
md_out_fd=strtol(argv[2], NULL, 0);
} else
md_fail();
signal(SIGHUP, md_exit);
signal(SIGPIPE, md_exit);
if(argc>3)
md_root=strtol(argv[3], NULL, 0);
else
md_root=None;
if(md_command(None, MCMD_GET_VERSION, NULL, 0, &amiwm_version)<=0)
md_fail();
return (argc>4? argv[4]:NULL);
}
void md_main_loop()
{
do md_process_queued_events(); while(md_handle_input()>=0);
}
int md_connection_number()
{
return md_in_fd;
}

537
libami/readargs.c Normal file
View File

@@ -0,0 +1,537 @@
#include "libami.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef AMIGAOS
void initargs(int argc, char **argv)
{
}
#else
static char *cmdline=NULL;
int cmdline_allocated=0, cmdline_used=0;
static void addachar(char c)
{
if(cmdline_used>=cmdline_allocated) {
if(!cmdline_allocated) cmdline_allocated=128;
while(cmdline_allocated<=cmdline_used)
cmdline_allocated<<=1;
if(cmdline!=NULL)
cmdline=realloc(cmdline, cmdline_allocated);
else
cmdline=malloc(cmdline_allocated);
}
cmdline[cmdline_used++]=c;
}
static void addquoted(const char *arg)
{
char ch;
addachar(' '); addachar('"');
while((ch=*arg++)) switch(ch) {
case '\n': addachar('*'); addachar('N'); break;
case '\"': addachar('*'); addachar('\"'); break;
case '*': addachar(ch);
default: addachar(ch);
}
addachar('"');
}
static void addunquoted(const char *arg, int cnt)
{
if(cnt) {
addachar(' ');
while(cnt--)
addachar(*arg++);
}
}
static void addarg(const char *arg)
{
if(*arg!='\"') {
int plain=strcspn(arg, "\t\n ;=");
if(!arg[plain]) {
addunquoted(arg, plain);
return;
} else if(arg[plain]=='=') {
addunquoted(arg, plain);
addunquoted("=", 1);
arg+=plain+1;
if(!*arg)
return;
}
}
addquoted(arg);
}
void initargs(int argc, char **argv)
{
while(--argc) addarg(*++argv);
addachar('\n');
addachar('\0');
}
#endif
#ifndef AMIGAOS
#define RDAF_PRIVATE1 0x40000000
#define RDAF_PRIVATE2 0x20000000
void FreeArgs(struct RDArgs *rdargs)
{
if(rdargs) {
APTR daelt, nextda = (APTR)rdargs->RDA_DAList;
rdargs->RDA_Buffer = NULL;
rdargs->RDA_Flags &= (RDAF_PRIVATE1 | RDAF_PRIVATE2);
rdargs->RDA_DAList = NULL;
while((daelt = nextda)) {
nextda = ((Argtype *)daelt)->ptr;
free(daelt);
}
}
}
static UBYTE * ra_alloc(struct RDArgs *rdargs, ULONG size)
{
UBYTE *ptr=NULL;
if((!(rdargs->RDA_Flags & RDAF_NOALLOC)) &&
(ptr=malloc(size+sizeof(Argtype)))) {
memset(ptr, 0, size+sizeof(Argtype));
((Argtype *)ptr)->ptr=rdargs->RDA_DAList;
rdargs->RDA_DAList=ptr;
ptr+=sizeof(Argtype);
}
return ptr;
}
static UBYTE * ra_realloc(struct RDArgs *rdargs, UBYTE **start, UBYTE **end)
{
UBYTE *oldstart=*start;
ULONG newlength=((*end-oldstart+144)&~0x7f)-8;
UBYTE *newstart=ra_alloc(rdargs, newlength+4);
if(!newstart)
return NULL;
*start=newstart;
*end=newstart+newlength;
return oldstart;
}
static LONG CS_ReadChar(struct CSource *cSource)
{
if(!cSource || ((LONG)cSource)==-1 || !cSource->CS_Buffer) {
if(cmdline && *cmdline) {
return (unsigned char)(*cmdline++);
} else
return getchar();
}
if(cSource->CS_CurChr >= cSource->CS_Length)
return -1;
return cSource->CS_Buffer[cSource->CS_CurChr++];
}
static void CS_UnReadChar(struct CSource *cSource, UBYTE ch)
{
if(!cSource || ((LONG)cSource)==-1 || !cSource->CS_Buffer) {
if(cmdline && *cmdline)
--cmdline;
else
ungetc(ch, stdin);
} else if(cSource->CS_CurChr > 0)
--cSource->CS_CurChr;
}
static LONG intreaditem(STRPTR buffer, LONG maxchars, struct CSource *input,
int mode, UBYTE **start, UBYTE **end)
{
int itemlen=0;
int ch, quote='\0';
buffer[0]='\0';
do ch=CS_ReadChar(input); while(ch==' ' || ch=='\t');
if(ch=='"') { quote=ch; ch=CS_ReadChar(input); }
while(ch!='\n' && ch>=0) {
if(quote) {
if(ch==quote)
return ITEM_QUOTED;
if(ch=='*') {
ch=CS_ReadChar(input);
if(ch<0 || ch=='\n') break;
if(ch=='e' || ch=='E') ch='\033';
if(ch=='n' || ch=='N') ch='\n';
}
} else {
if(ch==';')
break;
if(ch==' ' || ch=='\t' || (ch=='=' && itemlen)) {
if(mode<0)
CS_UnReadChar(input, ch);
return ITEM_UNQUOTED;
}
if(ch=='=')
return ITEM_EQUAL;
}
if(++itemlen>=maxchars) {
UBYTE *bufswap;
if(mode<=0 || !(bufswap=ra_realloc((struct RDArgs *)input, start, end)))
return ITEM_ERROR;
memcpy(*start, bufswap, itemlen-1);
buffer=*start+itemlen-1;
maxchars=*end-*start;
}
if(mode<0) {
buffer[itemlen]=ch;
buffer[itemlen+1]='\0';
buffer[0]=itemlen;
} else {
*buffer++=ch;
*buffer='\0';
}
ch=CS_ReadChar(input);
}
CS_UnReadChar(input, ch);
return (quote? ITEM_ERROR : (itemlen? ITEM_UNQUOTED : ITEM_NOTHING));
}
LONG ReadItem(STRPTR buffer, LONG maxchars, struct CSource *input)
{
return intreaditem(buffer, maxchars, input, 0, NULL, NULL);
}
LONG FindArg(STRPTR template, STRPTR keyword)
{
int kwlen=strlen((char *)keyword);
int kwindex, argindex=0;
char ch;
for(;;) {
kwindex=0;
do {
ch=*template++;
if(!ch)
return (kwindex == kwlen? argindex : -1);
if(ch == ',' || ch == '=' || ch == '/')
if(kwindex == kwlen)
return argindex;
else
break;
} while(ToUpper(ch) == ToUpper(keyword[kwindex++]));
while(ch != '=') {
if(ch == ',') {
argindex++;
break;
}
ch=*template++;
if(!ch)
return -1;
}
}
}
#define RA_ALWAYS 1
#define RA_KEYWORD 2
#define RA_SWITCH 4
#define RA_NUMERIC 8
#define RA_FORCE 16
#define RA_TOGGLE 32
#define RA_MULTI 64
#define RA_FOUND 128
static LONG parseswitches(STRPTR template, LONG len, UBYTE *flags, int *numargs)
{
static struct ra_switch { UBYTE flag, ch; } switches[] = {
{ RA_ALWAYS, 'A' },
{ RA_KEYWORD, 'K' },
{ RA_SWITCH, 'S' },
{ RA_NUMERIC, 'N' },
{ RA_FORCE, 'F' },
{ RA_TOGGLE, 'T' },
{ RA_MULTI, '.' },
{ RA_MULTI, 'M' },
{ 0, 0 }
};
struct ra_switch *sw;
int m_used=0;
UBYTE ch;
*numargs=0;
while(++*numargs<=MAX_TEMPLATE_ITEMS) {
*flags++=0;
do {
if(--len<0)
return 0;
if((ch=*template++)=='/') {
ch=ToUpper(*template++);
--len;
for(sw=switches; sw->ch; sw++)
if(sw->ch == ch) {
flags[-1]|=sw->flag;
if((sw->flag&RA_MULTI) && m_used++)
return ERROR_BAD_TEMPLATE;
}
}
} while(ch != ',');
}
return ERROR_LINE_TOO_LONG;
}
static LONG rareaditem(struct RDArgs *rdargs, UBYTE **start, UBYTE **end)
{
while(*end-*start-1<0)
if(!rdargs || !ra_realloc(rdargs, start, end))
return ITEM_ERROR;
return (rdargs?
intreaditem(*start, *end-*start-1, &rdargs->RDA_Source, 1, start, end):
intreaditem(*start, *end-*start-2, (struct CSource *)-1, -1, start, end));
}
struct RDArgs * ReadArgs(STRPTR template, LONG *array, struct RDArgs *rdargs)
{
LONG itemtype;
UBYTE *multiargs[MAX_MULTIARGS+1];
UBYTE switches[MAX_TEMPLATE_ITEMS];
UBYTE *start, *end, sw, *swptr;
Argtype *lastmarg=NULL;
int multinum=0;
int argnum;
LONG ch, error=0;
int numargs;
int munched;
if(rdargs) {
rdargs->RDA_DAList=NULL;
if(!rdargs->RDA_Buffer) {
if(!(rdargs->RDA_Buffer=ra_alloc(rdargs, 128+4)))
goto nomemfail;
rdargs->RDA_BufSiz=128;
}
} else {
rdargs=malloc(128+4+sizeof(struct RDArgs)+sizeof(Argtype));
if(!rdargs)
goto nomemfail;
memset(rdargs, 0, 128+4+sizeof(struct RDArgs)+sizeof(Argtype));
rdargs=(struct RDArgs *)(((char *)rdargs)+sizeof(Argtype));
rdargs->RDA_Buffer=((UBYTE*)rdargs)+sizeof(struct RDArgs);
rdargs->RDA_DAList=(((char *)rdargs)-sizeof(Argtype));
rdargs->RDA_BufSiz=128;
}
start=rdargs->RDA_Buffer;
end=rdargs->RDA_Buffer+rdargs->RDA_BufSiz;
if((error=parseswitches(template, strlen((char *)template),
switches, &numargs)))
goto fail;
for(;;) {
argnum=-1;
switch(itemtype=rareaditem(rdargs, &start, &end)) {
case ITEM_NOTHING:
swptr=switches;
while(numargs-->0) {
int isnumeric=0;
if((*swptr)&RA_MULTI)
if(multinum) {
((Argtype *)array)->ptr=ra_alloc(rdargs,
sizeof(Argtype)*(multinum+1));
if(!((Argtype *)array)->ptr)
goto nomemfail;
memcpy(((Argtype *)array)->ptr, multiargs, sizeof(Argtype)*multinum);
lastmarg=((Argtype *)(((Argtype *)array)->ptr))+multinum-1;
lastmarg[1].ptr=NULL;
isnumeric=((*swptr)&RA_NUMERIC)!=0;
}
else ((Argtype *)array)->ptr=NULL;
array=(LONG*)(((Argtype *)array)+1);
if(!((sw=*swptr++)&RA_FOUND) && (sw&RA_ALWAYS)) {
if((!lastmarg) || (sw&RA_KEYWORD) || multinum<2 ||
isnumeric!=((sw&RA_NUMERIC)!=0)) {
error=ERROR_REQUIRED_ARG_MISSING;
goto fail;
}
((Argtype *)array)[-1].ptr=lastmarg->ptr;
(lastmarg--)->ptr=NULL;
--multinum;
}
}
CS_ReadChar(&rdargs->RDA_Source);
return rdargs;
case ITEM_UNQUOTED:
argnum=FindArg(template, start);
if(argnum<0)
goto not_namedarg;
sw=switches[argnum];
if(sw&RA_SWITCH) {
((Argtype *)array)[argnum].num=-1;
break;
}
if(!(sw&RA_FORCE)) {
LONG argt;
if((argt=rareaditem(rdargs, &start, &end))==ITEM_EQUAL)
argt=rareaditem(rdargs, &start, &end);
if(argt==ITEM_NOTHING) {
error=ERROR_KEY_NEEDS_ARG;
goto fail;
} else if(argt<0) {
error=ERROR_LINE_TOO_LONG;
goto fail;
} else
goto quoted;
}
munched=0;
force:
if(end-start<=munched) {
UBYTE *old;
if(!(old=ra_realloc(rdargs, &start, &end)))
goto nomemfail;
memcpy(start, old, munched);
}
if((ch=CS_ReadChar(&rdargs->RDA_Source))>=0 && ch!='\n') {
start[munched++]=ch;
goto force;
}
if(itemtype!=ITEM_QUOTED)
while((start[munched-1]==' ' || start[munched-1]=='\t') && --munched>0);
start[munched]='\0';
goto quoted2;
not_namedarg:
ch=CS_ReadChar(&rdargs->RDA_Source);
if(ch<0)
goto quoted;
if(ch=='\n' && start[0]=='?' && start[1]=='\0' &&
!(rdargs->RDA_Flags & RDAF_NOPROMPT)) {
UBYTE *helptext = template;
if(!(rdargs->RDA_Flags & RDAF_PRIVATE1)) {
rdargs->RDA_Flags |= RDAF_PRIVATE1;
if(rdargs->RDA_ExtHelp)
helptext=rdargs->RDA_ExtHelp;
}
fprintf(stderr, "%s: ", (char *)helptext);
fflush(stderr);
break;
}
quoted2:
CS_UnReadChar((struct CSource *)rdargs, ch);
quoted:
case ITEM_QUOTED:
if(argnum<0) {
swptr=switches;
error=ERROR_TOO_MANY_ARGS;
for(;;) {
if(++argnum>=numargs)
goto fail;
if((*swptr)&RA_MULTI)
break;
if((sw=*swptr++)&RA_FOUND)
continue;
if(sw&RA_FORCE) {
munched=strlen((char *)start);
if(itemtype!=ITEM_QUOTED)
start[munched++]=' ';
goto force;
}
if(!(sw&RA_KEYWORD))
if(!(sw&=(RA_TOGGLE|RA_SWITCH)))
break;
}
}
sw=switches[argnum];
switches[argnum]|=RA_FOUND;
if(!rdargs) {
((Argtype *)array)[argnum].num=((LONG)start)>>2;
start+=((*start)&~3)+4;
continue;
}
if(sw&RA_MULTI) {
if(multinum>=MAX_MULTIARGS-1) {
error=ERROR_LINE_TOO_LONG;
goto fail;
} if(sw&RA_NUMERIC)
goto numeric;
multiargs[multinum++]=start;
} else if((sw&RA_FOUND)&&!(sw&RA_SWITCH)) {
error=ERROR_TOO_MANY_ARGS;
goto fail;
} else if(sw&RA_TOGGLE) {
if(Stricmp(start, (STRPTR)"yes"))
((Argtype*)array)[argnum].num=-1;
else if(Stricmp(start, (STRPTR)"no"))
((Argtype*)array)[argnum].num=0;
else if(Stricmp(start, (STRPTR)"on"))
((Argtype*)array)[argnum].num=-1;
else if(Stricmp(start, (STRPTR)"off"))
((Argtype*)array)[argnum].num=0;
else {
error=ERROR_KEY_NEEDS_ARG;
goto fail;
}
} else if(sw&RA_NUMERIC) {
LONG n; int len;
numeric:
if((len=StrToLong(start, &n))<=0 || len!=strlen((char *)start)) {
error=ERROR_BAD_NUMBER;
goto fail;
}
start+=sizeof(Argtype)-1;
start-=((LONG)start)&(sizeof(Argtype)-1);
if(end-start<sizeof(LONG))
if(!ra_realloc(rdargs, &start, &end))
goto nomemfail;
*(LONG *)start=n;
if(sw&RA_MULTI)
multiargs[multinum++]=start;
else
((Argtype*)array)[argnum].ptr=start;
start+=sizeof(LONG);
continue;
} else
((Argtype*)array)[argnum].ptr=start;
start+=strlen((char *)start)+1;
break;
default:
error=ERROR_LINE_TOO_LONG;
goto fail;
}
}
nomemfail:
error=ERROR_NO_FREE_STORE;
fail:
do
ch=CS_ReadChar(&rdargs->RDA_Source);
while(ch!='\n' && ch!=';' && ch>=0);
if(rdargs)
FreeArgs(rdargs);
SetIoErr(error);
return NULL;
}
#endif

36
libami/strutil.c Normal file
View File

@@ -0,0 +1,36 @@
#include "libami.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <ctype.h>
#ifndef AMIGAOS
UBYTE ToUpper(UBYTE ch)
{
static int firstcall=1;
if(firstcall) {
setlocale(LC_CTYPE, "");
firstcall=0;
}
return toupper(ch);
}
LONG StrToLong(STRPTR str, LONG *n)
{
STRPTR end;
*n=strtol((char *)str, (char **)&end, 0);
return end-str;
}
LONG Stricmp(STRPTR a, STRPTR b)
{
while(*a && *b)
if(ToUpper(*a++)!=ToUpper(*b++))
return FALSE;
return !(*a || *b);
}
#endif