210 lines
4.7 KiB
C
210 lines
4.7 KiB
C
|
#include "config.h"
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include "comms.h"
|
||
|
|
||
|
static Window comms_win = 0;
|
||
|
static Window my_win = 0;
|
||
|
|
||
|
static void
|
||
|
_CommsFindCommsWindow(void)
|
||
|
{
|
||
|
unsigned char *s;
|
||
|
Atom a, ar;
|
||
|
unsigned long num, after;
|
||
|
int format;
|
||
|
Window rt;
|
||
|
int dint;
|
||
|
unsigned int duint;
|
||
|
|
||
|
a = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True);
|
||
|
if (a != None)
|
||
|
{
|
||
|
s = NULL;
|
||
|
XGetWindowProperty(disp, root, a, 0, 14, False, AnyPropertyType, &ar,
|
||
|
&format, &num, &after, &s);
|
||
|
if (s)
|
||
|
{
|
||
|
sscanf((char *)s, "%*s %x", (unsigned int *)&comms_win);
|
||
|
XFree(s);
|
||
|
}
|
||
|
else
|
||
|
comms_win = 0;
|
||
|
|
||
|
if (comms_win)
|
||
|
{
|
||
|
if (!XGetGeometry(disp, comms_win, &rt, &dint, &dint,
|
||
|
&duint, &duint, &duint, &duint))
|
||
|
comms_win = 0;
|
||
|
s = NULL;
|
||
|
if (comms_win)
|
||
|
{
|
||
|
XGetWindowProperty(disp, comms_win, a, 0, 14, False,
|
||
|
AnyPropertyType, &ar, &format, &num,
|
||
|
&after, &s);
|
||
|
if (s)
|
||
|
XFree(s);
|
||
|
else
|
||
|
comms_win = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (comms_win)
|
||
|
XSelectInput(disp, comms_win,
|
||
|
StructureNotifyMask | SubstructureNotifyMask);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CommsSetup(void)
|
||
|
{
|
||
|
for (;;)
|
||
|
{
|
||
|
_CommsFindCommsWindow();
|
||
|
if (comms_win != None)
|
||
|
break;
|
||
|
sleep(1);
|
||
|
}
|
||
|
|
||
|
if (!my_win)
|
||
|
{
|
||
|
my_win = XCreateWindow(disp, root, -10, -10, 1, 1, 0,
|
||
|
CopyFromParent, InputOnly, CopyFromParent,
|
||
|
0, NULL);
|
||
|
XSelectInput(disp, my_win,
|
||
|
StructureNotifyMask | SubstructureNotifyMask);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CommsHandleDestroy(Window xwin)
|
||
|
{
|
||
|
if (xwin == comms_win)
|
||
|
comms_win = 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CommsHandlePropertyNotify(XEvent *ev)
|
||
|
{
|
||
|
Atom a = 0;
|
||
|
|
||
|
if (comms_win)
|
||
|
return 0;
|
||
|
if (!a)
|
||
|
a = XInternAtom(disp, "ENLIGHTENMENT_COMMS", True);
|
||
|
if (a == ev->xproperty.atom)
|
||
|
CommsSetup();
|
||
|
if (comms_win)
|
||
|
return 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
CommsSend(const char *buf, unsigned int len)
|
||
|
{
|
||
|
static Atom a = None;
|
||
|
char ss[21];
|
||
|
unsigned int i, j, k;
|
||
|
XEvent ev;
|
||
|
|
||
|
if (!a)
|
||
|
a = XInternAtom(disp, "ENL_MSG", False);
|
||
|
|
||
|
ev.xclient.type = ClientMessage;
|
||
|
ev.xclient.serial = 0;
|
||
|
ev.xclient.send_event = True;
|
||
|
ev.xclient.window = comms_win;
|
||
|
ev.xclient.message_type = a;
|
||
|
ev.xclient.format = 8;
|
||
|
|
||
|
for (i = 0; i < len + 1; i += 12)
|
||
|
{
|
||
|
snprintf(ss, sizeof(ss), "%8x", (int)my_win);
|
||
|
for (j = 0; j < 12; j++)
|
||
|
{
|
||
|
ss[8 + j] = buf[i + j];
|
||
|
if (!buf[i + j])
|
||
|
j = 12;
|
||
|
}
|
||
|
ss[20] = 0;
|
||
|
for (k = 0; k < 20; k++)
|
||
|
ev.xclient.data.b[k] = ss[k];
|
||
|
XSendEvent(disp, comms_win, False, 0, &ev);
|
||
|
}
|
||
|
|
||
|
return len;
|
||
|
}
|
||
|
|
||
|
static Bool
|
||
|
ev_check(Display *d __UNUSED__, XEvent *ev, XPointer p __UNUSED__)
|
||
|
{
|
||
|
if (((ev->type == ClientMessage) && (ev->xclient.window == my_win)) ||
|
||
|
((ev->type == DestroyNotify) &&
|
||
|
(ev->xdestroywindow.window == comms_win)))
|
||
|
return True;
|
||
|
return False;
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
CommsWaitForMessage(void)
|
||
|
{
|
||
|
XEvent ev;
|
||
|
char *msg = NULL;
|
||
|
|
||
|
while ((!msg) && (comms_win))
|
||
|
{
|
||
|
XIfEvent(disp, &ev, ev_check, NULL);
|
||
|
if (ev.type == DestroyNotify)
|
||
|
comms_win = 0;
|
||
|
else
|
||
|
msg = CommsHandleClientMessage(&ev);
|
||
|
}
|
||
|
return msg;
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
CommsHandleClientMessage(XEvent *ev)
|
||
|
{
|
||
|
char s[13], s2[9], *msg = NULL;
|
||
|
int i;
|
||
|
Window win = 0;
|
||
|
static char *c_msg = NULL;
|
||
|
|
||
|
if (!ev)
|
||
|
return NULL;
|
||
|
if (ev->type != ClientMessage)
|
||
|
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, "%x", (int *)&win);
|
||
|
if (win == comms_win)
|
||
|
{
|
||
|
if (c_msg)
|
||
|
{
|
||
|
c_msg = realloc(c_msg, strlen(c_msg) + strlen(s) + 1);
|
||
|
if (!c_msg)
|
||
|
return NULL;
|
||
|
strcat(c_msg, s);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
c_msg = malloc(strlen(s) + 1);
|
||
|
if (!c_msg)
|
||
|
return NULL;
|
||
|
strcpy(c_msg, s);
|
||
|
}
|
||
|
if (strlen(s) < 12)
|
||
|
{
|
||
|
msg = c_msg;
|
||
|
c_msg = NULL;
|
||
|
}
|
||
|
}
|
||
|
return msg;
|
||
|
}
|