Simplify eesh, enable one-liners like "eesh wl a".

SVN revision: 12239
This commit is contained in:
Kim Woelders 2004-11-21 22:11:09 +00:00
parent 1ee3e08a5c
commit 8d4a8ba6ce
5 changed files with 110 additions and 522 deletions

View File

@ -40,57 +40,21 @@
#define USE_LIBC_STRDUP 1 /* Use libc strdup if present */
#endif
#define LIST_FINDBY_NAME 0
#define LIST_FINDBY_ID 1
#define LIST_FINDBY_BOTH 2
#define LIST_FINDBY_NONE 3
#define LIST_TYPE_COUNT 18
#define LIST_TYPE_ANY 0
#define LIST_TYPE_CLIENT 1
typedef struct _list
{
int type;
char *name;
int id;
void *item;
struct _list *next;
}
List;
typedef struct _client
{
char *name;
Window win;
char *msg;
char *clientname;
char *version;
char *author;
char *email;
char *web;
char *address;
char *info;
Pixmap pmap;
}
Client;
void *FindItem(const char *name, int id, int find_by, int type);
void AddItem(void *item, const char *name, int id, int type);
void *RemoveItem(char *name, int id, int find_by, int type);
void **ListItemType(int *num, int type);
char **ListItems(int *num, int type);
void **ListItemTypeID(int *num, int type, int id);
Window CommsSetup(void);
Window CommsFindCommsWindow(void);
void CommsSend(Client * c, const char *s);
char *CommsGet(Client ** c, XEvent * ev);
Client *MakeClient(Window win);
void ListFreeClient(void *ptr);
void DeleteClient(Client * c);
int HandleComms(XEvent * ev);
char *CommsGet(Client * c, XEvent * ev);
Client *ClientCreate(Window win);
void ClientDestroy(Client * c);
void Alert(const char *fmt, ...);
#define Ecalloc calloc
#define Emalloc malloc
@ -103,25 +67,4 @@ int HandleComms(XEvent * ev);
char *Estrdup(const char *s);
#endif
#define FILEPATH_LEN_MAX 4096
/* This turns on E's internal stack tracking system for coarse debugging */
/* and being able to trace E for profiling/optimisation purposes (which */
/* believe it or not I'm actually doing) */
/* #define DEBUG 1 */
#define EDBUG(l,x) \
;
#define EDBUG_RETURN(x) \
{ \
return (x); \
}
#define EDBUG_RETURN_ \
{ \
return; \
}
void Alert(const char *fmt, ...);
extern Display *disp;
extern List lists;

View File

@ -1,7 +1,7 @@
bin_PROGRAMS = eesh
eesh_SOURCES = E.h comms.c lists.c main.c
eesh_SOURCES = E.h comms.c main.c
LDADD = $(X_LIBS) -lX11

View File

@ -30,15 +30,17 @@ Window
CommsSetup(void)
{
char *str;
EDBUG(5, "CommsSetup");
XSetWindowAttributes attr;
str = getenv("ENL_WM_ROOT");
root_win = (str) ? strtoul(str, NULL, 0) : DefaultRootWindow(disp);
my_win = XCreateSimpleWindow(disp, root_win, -100, -100, 5, 5, 0, 0, 0);
attr.override_redirect = False;
my_win = XCreateWindow(disp, root_win, -100, -100, 5, 5, 0, 0, InputOnly,
DefaultVisual(disp, DefaultScreen(disp)),
CWOverrideRedirect, &attr);
EDBUG_RETURN(my_win);
return my_win;
}
Window
@ -52,54 +54,52 @@ CommsFindCommsWindow(void)
int dint;
unsigned int duint;
EDBUG(6, "CommsFindCommsWindow");
comms_win = None;
a = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True);
if (a == None)
EDBUG_RETURN(None);
return None;
s = NULL;
XGetWindowProperty(disp, root_win, a, 0, 14, False, AnyPropertyType,
&ar, &format, &num, &after, &s);
if (!s)
EDBUG_RETURN(None);
return None;
sscanf((char *)s, "%*s %lx", &comms_win);
XFree(s);
if (comms_win == None)
EDBUG_RETURN(None);
return None;
if (!XGetGeometry(disp, comms_win, &rt, &dint, &dint,
&duint, &duint, &duint, &duint))
EDBUG_RETURN(None);
return None;
s = NULL;
XGetWindowProperty(disp, comms_win, a, 0, 14, False,
AnyPropertyType, &ar, &format, &num, &after, &s);
if (!s)
EDBUG_RETURN(None);
return None;
XFree(s);
XSelectInput(disp, comms_win, StructureNotifyMask | SubstructureNotifyMask);
EDBUG_RETURN(comms_win);
return comms_win;
}
void
CommsSend(Client * c, const char *s)
{
char ss[21];
char ss[20];
int i, j, k, len;
XEvent ev;
Atom a;
EDBUG(5, "CommsSend");
if ((!s) || (!c))
EDBUG_RETURN_;
len = strlen(s);
if ((!s) || (!c) || (c->win == None))
return;
a = XInternAtom(disp, "ENL_MSG", True);
ev.xclient.type = ClientMessage;
ev.xclient.serial = 0;
ev.xclient.send_event = True;
@ -107,6 +107,7 @@ CommsSend(Client * c, const char *s)
ev.xclient.message_type = a;
ev.xclient.format = 8;
len = strlen(s);
for (i = 0; i < len + 1; i += 12)
{
sprintf(ss, "%8x", (int)my_win);
@ -116,148 +117,82 @@ CommsSend(Client * c, const char *s)
if (!s[i + j])
j = 12;
}
ss[20] = 0;
for (k = 0; k < 20; k++)
ev.xclient.data.b[k] = ss[k];
XSendEvent(disp, c->win, False, 0, (XEvent *) & ev);
XSendEvent(disp, c->win, False, 0, &ev);
}
EDBUG_RETURN_;
}
char *
CommsGet(Client ** c, XEvent * ev)
CommsGet(Client * c, XEvent * ev)
{
char s[13], s2[9], *msg, st[32];
char s[13], s2[9], *msg;
int i;
Window win;
Client *cl;
EDBUG(5, "CommsGet");
if ((!ev) || (!c))
EDBUG_RETURN(NULL);
return NULL;
if (ev->type != ClientMessage)
EDBUG_RETURN(NULL);
return NULL;
s[12] = 0;
s2[8] = 0;
msg = NULL;
for (i = 0; i < 8; i++)
s2[i] = ev->xclient.data.b[i];
for (i = 0; i < 12; i++)
s[i] = ev->xclient.data.b[i + 8];
sscanf(s2, "%lx", &win);
cl = (Client *) FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_CLIENT);
if (!cl)
{
cl = MakeClient(win);
if (!cl)
EDBUG_RETURN(NULL);
sprintf(st, "%8x", (int)win);
cl->name = Estrdup(st);
AddItem((void *)cl, st, cl->win, LIST_TYPE_CLIENT);
XSelectInput(disp, win, StructureNotifyMask | SubstructureNotifyMask);
}
if (cl->msg)
if (c->msg)
{
/* append text to end of msg */
cl->msg = Erealloc(cl->msg, strlen(cl->msg) + strlen(s) + 1);
if (!cl->msg)
EDBUG_RETURN(NULL);
strcat(cl->msg, s);
c->msg = Erealloc(c->msg, strlen(c->msg) + strlen(s) + 1);
if (!c->msg)
return NULL;
strcat(c->msg, s);
}
else
{
/* new msg */
cl->msg = Emalloc(strlen(s) + 1);
if (!cl->msg)
EDBUG_RETURN(NULL);
strcpy(cl->msg, s);
c->msg = Emalloc(strlen(s) + 1);
if (!c->msg)
return NULL;
strcpy(c->msg, s);
}
if (strlen(s) < 12)
{
msg = cl->msg;
cl->msg = NULL;
*c = cl;
msg = c->msg;
c->msg = NULL;
}
EDBUG_RETURN(msg);
return msg;
}
Client *
MakeClient(Window win)
ClientCreate(Window win)
{
Client *c;
EDBUG(6, "MakeClient");
c = Emalloc(sizeof(Client));
if (!c)
EDBUG_RETURN(NULL);
c->name = NULL;
return NULL;
c->win = win;
c->msg = NULL;
c->clientname = NULL;
c->version = NULL;
c->author = NULL;
c->email = NULL;
c->web = NULL;
c->address = NULL;
c->info = NULL;
c->pmap = 0;
EDBUG_RETURN(c);
return c;
}
void
ListFreeClient(void *ptr)
ClientDestroy(Client * c)
{
Client *c;
EDBUG(6, "ListFreeClient");
c = (Client *) ptr;
if (!c)
EDBUG_RETURN_;
if (c->name)
Efree(c->name);
return;
if (c->msg)
Efree(c->msg);
if (c->clientname)
Efree(c->clientname);
if (c->version)
Efree(c->version);
if (c->author)
Efree(c->author);
if (c->email)
Efree(c->email);
if (c->web)
Efree(c->web);
if (c->address)
Efree(c->address);
if (c->info)
Efree(c->info);
Efree(c);
EDBUG_RETURN_;
}
void
DeleteClient(Client * c)
{
Client *cc;
EDBUG(6, "DeleteClient");
cc = RemoveItem(NULL, c->win, LIST_FINDBY_ID, LIST_TYPE_CLIENT);
ListFreeClient(cc);
EDBUG_RETURN_;
}
int
HandleComms(XEvent * ev)
{
Client *c;
char *s;
EDBUG(4, "HandleComms");
s = CommsGet(&c, ev);
if (!s)
EDBUG_RETURN(0);
printf("%s\n", s);
fflush(stdout);
Efree(s);
EDBUG_RETURN(1);
}

View File

@ -1,315 +0,0 @@
/*
* Copyright (C) 2000-2004 Carsten Haitzler, Geoff Harrison and various contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
void *
FindItem(const char *name, int id, int find_by, int type)
{
List *ptr;
EDBUG(6, "FindItem");
ptr = lists.next;
if (find_by == LIST_FINDBY_NAME)
{
while (ptr)
{
if ((ptr->type == type) && (!strcmp(name, ptr->name)))
EDBUG_RETURN(ptr->item);
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_ID)
{
while (ptr)
{
if ((ptr->type == type) && (ptr->id == id))
EDBUG_RETURN(ptr->item);
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_BOTH)
{
while (ptr)
{
if ((ptr->type == type) && (!strcmp(name, ptr->name))
&& (ptr->id == id))
EDBUG_RETURN(ptr->item);
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_NONE)
{
while (ptr)
{
if ((ptr->type == type))
EDBUG_RETURN(ptr->item);
ptr = ptr->next;
}
}
EDBUG_RETURN(NULL);
}
void
AddItem(void *item, const char *name, int id, int type)
{
List *ptr;
EDBUG(6, "AddItem");
ptr = Emalloc(sizeof(List));
if (!ptr)
EDBUG_RETURN_;
ptr->item = item;
ptr->name = Estrdup(name);
ptr->id = id;
ptr->type = type;
ptr->next = lists.next;
lists.next = ptr;
EDBUG_RETURN_;
}
void *
RemoveItem(char *name, int id, int find_by, int type)
{
List *ptr, *pptr;
void *p;
EDBUG(6, "RemoveItem");
pptr = NULL;
ptr = lists.next;
if (find_by == LIST_FINDBY_NAME)
{
while (ptr)
{
if ((ptr->type == type) && (!strcmp(name, ptr->name)))
{
if (pptr)
pptr->next = ptr->next;
else
lists.next = ptr->next;
p = ptr->item;
if (ptr->name)
Efree(ptr->name);
Efree(ptr);
EDBUG_RETURN(p);
}
pptr = ptr;
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_ID)
{
while (ptr)
{
if ((ptr->type == type) && (ptr->id == id))
{
if (pptr)
pptr->next = ptr->next;
else
lists.next = ptr->next;
p = ptr->item;
if (ptr->name)
Efree(ptr->name);
Efree(ptr);
EDBUG_RETURN(p);
}
pptr = ptr;
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_BOTH)
{
while (ptr)
{
if ((ptr->type == type) && (!strcmp(name, ptr->name))
&& (ptr->id == id))
{
if (pptr)
pptr->next = ptr->next;
else
lists.next = ptr->next;
p = ptr->item;
if (ptr->name)
Efree(ptr->name);
Efree(ptr);
EDBUG_RETURN(p);
}
pptr = ptr;
ptr = ptr->next;
}
}
else if (find_by == LIST_FINDBY_NONE)
{
while (ptr)
{
if ((ptr->type == type))
{
if (pptr)
pptr->next = ptr->next;
else
lists.next = ptr->next;
p = ptr->item;
if (ptr->name)
Efree(ptr->name);
Efree(ptr);
EDBUG_RETURN(p);
}
pptr = ptr;
ptr = ptr->next;
}
}
EDBUG_RETURN(NULL);
}
void **
ListItemType(int *num, int type)
{
List *ptr;
int i, len;
void **lst;
EDBUG(6, "ListItemType");
*num = 0;
len = 0;
if (type == LIST_TYPE_ANY)
EDBUG_RETURN(NULL);
ptr = lists.next;
while (ptr)
{
if (ptr->type == type)
len++;
ptr = ptr->next;
}
if (!len)
EDBUG_RETURN(NULL);
lst = Emalloc(len * sizeof(void *));
i = 0;
ptr = lists.next;
while (ptr)
{
if (ptr->type == type)
lst[i++] = ptr->item;
ptr = ptr->next;
}
*num = i;
EDBUG_RETURN(lst);
}
char **
ListItems(int *num, int type)
{
List *ptr;
int i, len;
char **list;
EDBUG(7, "ListItems");
i = 0;
len = 0;
list = NULL;
ptr = lists.next;
if (type != LIST_TYPE_ANY)
{
while (ptr)
{
if (ptr->type == type)
len++;
ptr = ptr->next;
}
}
else
{
while (ptr)
{
len++;
ptr = ptr->next;
}
}
list = Emalloc(len * sizeof(char *));
if (!list)
{
*num = 0;
EDBUG_RETURN(NULL);
}
ptr = lists.next;
if (type != LIST_TYPE_ANY)
{
while (ptr)
{
if (ptr->type == type)
{
list[i] = Estrdup(ptr->name);
i++;
}
ptr = ptr->next;
}
}
else
{
while (ptr)
{
list[i] = Estrdup(ptr->name);
i++;
ptr = ptr->next;
}
}
*num = len;
EDBUG_RETURN(list);
}
void **
ListItemTypeID(int *num, int type, int id)
{
List *ptr;
int i, len;
void **lst;
EDBUG(6, "ListItemType");
*num = 0;
len = 0;
if (type == LIST_TYPE_ANY)
EDBUG_RETURN(NULL);
ptr = lists.next;
while (ptr)
{
if ((ptr->type == type) && (ptr->id == id))
len++;
ptr = ptr->next;
}
if (!len)
EDBUG_RETURN(NULL);
lst = Emalloc(len * sizeof(void *));
i = 0;
ptr = lists.next;
while (ptr)
{
if ((ptr->type == type) && (ptr->id == id))
lst[i++] = ptr->item;
ptr = ptr->next;
}
*num = i;
EDBUG_RETURN(lst);
}

View File

@ -25,12 +25,12 @@
/* Global vars */
Display *disp;
List lists;
static char buf[10240];
static int stdin_state;
static char *display_name;
static Client *e;
static Window my_win, comms_win;
static void
process_line(char *line)
@ -87,19 +87,23 @@ main(int argc, char **argv)
Client *me;
int i;
fd_set fd;
char *command;
Window my_win, comms_win;
char waitonly, complete;
char *command, *s;
char mode;
int len, l;
waitonly = 0;
lists.next = NULL;
mode = 0;
display_name = NULL;
command = NULL;
for (i = 0; i < argc; i++)
for (i = 1; i < argc; i++)
{
s = argv[i];
if (*s != '-')
break;
if (!strcmp(argv[i], "-e"))
{
mode = -1;
if (i != (argc - 1))
{
command = argv[++i];
@ -107,7 +111,7 @@ main(int argc, char **argv)
}
else if (!strcmp(argv[i], "-ewait"))
{
waitonly = 1;
mode = 1;
if (i != (argc - 1))
command = argv[++i];
}
@ -122,13 +126,15 @@ main(int argc, char **argv)
else if ((!strcmp(argv[i], "-h")) ||
(!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--help")))
{
printf("%s [ -e \"Command to Send to Enlightenment then exit\"]\n"
" [ -ewait \"Command to Send to E then wait for a reply then exit\"]\n",
argv[0]);
printf("Use \"%s\" by itself to enter the \"interactive mode\"\n"
"Ctrl-D will exit interactive mode (EOF)\n"
"use \"help\" from inside interactive mode for further "
"assistance\n", argv[0]);
printf
("eesh sends commands to E\n\n"
"Examples:\n"
" eesh Command to Send to E then wait for a reply then exit\n"
" eesh -ewait \"Command to Send to E then wait for a reply then exit\"\n"
" eesh -e \"Command to Send to Enlightenment then exit\"\n\n");
printf("Use eesh by itself to enter the \"interactive mode\"\n"
" Ctrl-D will exit interactive mode\n"
" Use \"help\" from inside interactive mode for further assistance\n");
exit(0);
}
}
@ -145,28 +151,41 @@ main(int argc, char **argv)
my_win = CommsSetup();
comms_win = CommsFindCommsWindow();
e = MakeClient(comms_win);
AddItem(e, "E", e->win, LIST_TYPE_CLIENT);
/* Not sure this is used... */
me = MakeClient(my_win);
AddItem(me, "ME", me->win, LIST_TYPE_CLIENT);
e = ClientCreate(comms_win);
me = ClientCreate(my_win);
CommsSend(e, "set clientname eesh");
CommsSend(e, "set version 0.1");
#if 0 /* Speed it up */
CommsSend(e, "set author The Rasterman");
CommsSend(e, "set email raster@rasterman.com");
CommsSend(e, "set web http://www.enlightenment.org");
/* CommsSend(e, "set address NONE"); */
/* CommsSend(e, "set address NONE"); */
CommsSend(e, "set info Enlightenment IPC Shell - talk to E direct");
/* CommsSend(e, "set pixmap 0"); */
/* CommsSend(e, "set pixmap 0"); */
#endif
if (command == NULL && i < argc)
{
mode = 1;
len = 0;
for (; i < argc; i++)
{
l = strlen(argv[i]);
command = Erealloc(command, len + l + 2);
if (len)
command[len++] = ' ';
strcpy(command + len, argv[i]);
len += l;
}
}
if (command)
{
/* Non-interactive */
CommsSend(e, command);
XSync(disp, False);
if (!waitonly)
if (mode <= 0)
goto done;
}
else
@ -200,8 +219,13 @@ main(int argc, char **argv)
switch (ev.type)
{
case ClientMessage:
complete = HandleComms(&ev);
if (waitonly && complete)
s = CommsGet(me, &ev);
if (!s)
break;
printf("%s\n", s);
fflush(stdout);
Efree(s);
if (mode)
goto done;
break;
case DestroyNotify:
@ -213,6 +237,9 @@ main(int argc, char **argv)
}
done:
ClientDestroy(e);
ClientDestroy(me);
return 0;
}
@ -221,11 +248,9 @@ Alert(const char *fmt, ...)
{
va_list ap;
EDBUG(7, "Alert");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
EDBUG_RETURN_;
}
#if !USE_LIBC_STRDUP
@ -235,12 +260,12 @@ Estrdup(const char *s)
char *ss;
int sz;
EDBUG(9, "Estrdup");
if (!s)
EDBUG_RETURN(NULL);
return NULL;
sz = strlen(s);
ss = Emalloc(sz + 1);
strncpy(ss, s, sz + 1);
EDBUG_RETURN(ss);
return ss;
}
#endif