2 * mod_notionflux/notionflux/notionflux.c
4 * Copyright (c) Tuomo Valkonen 2004-2005.
6 * This is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
13 #include <X11/Xatom.h>
15 #include <libtu/types.h>
21 #include <sys/types.h>
22 #include <sys/socket.h>
25 #include "../notionflux.h"
27 static void die(const char *s
)
29 fprintf(stderr
, "%s\n", s
);
34 static void die_e(const char *s
)
40 static void mywrite(int fd
, const char *buf
, int n
)
45 if(k
<0 && (errno
!=EAGAIN
&& errno
!=EINTR
))
55 static int myread(int fd
, char *buf
, int n
)
61 k
=read(fd
, buf
, left
);
62 if(k
<0 && (errno
!=EAGAIN
&& errno
!=EINTR
))
75 static char buf
[MAX_DATA
];
81 static Display
*dpy
=NULL
;
84 static ulong
xwindow_get_property_(Window win
, Atom atom
, Atom type
,
85 ulong n32expected
, bool more
, uchar
**p
,
93 status
=XGetWindowProperty(dpy
, win
, atom
, 0L, n32expected
,
94 False
, type
, &real_type
, format
, &n
,
97 if(status
!=Success
|| *p
==NULL
)
100 if(extra
==0 || !more
)
104 n32expected
+=(extra
+4)/4;
118 ulong
xwindow_get_property(Window win
, Atom atom
, Atom type
,
119 ulong n32expected
, bool more
, uchar
**p
)
122 return xwindow_get_property_(win
, atom
, type
, n32expected
, more
, p
,
127 char *xwindow_get_string_property(Window win
, Atom a
, int *nret
)
132 n
=xwindow_get_property(win
, a
, XA_STRING
, 64L, TRUE
, (uchar
**)&p
);
137 return (n
<=0 ? NULL
: p
);
141 void xwindow_set_string_property(Window win
, Atom a
, const char *value
)
144 XDeleteProperty(dpy
, win
, a
);
146 XChangeProperty(dpy
, win
, a
, XA_STRING
,
147 8, PropModeReplace
, (uchar
*)value
, strlen(value
));
152 static char *get_socket()
157 dpy
=XOpenDisplay(NULL
);
160 die_e("Unable to open display.");
162 a
=XInternAtom(dpy
, "_NOTION_MOD_NOTIONFLUX_SOCKET", True
);
165 die_e("Missing atom. Notion not running?");
167 s
=xwindow_get_string_property(DefaultRootWindow(dpy
), a
, NULL
);
178 int main(int argc
, char *argv
[])
181 struct sockaddr_un serv
;
182 const char *sockname
;
188 if(argc
!=3 || strcmp(argv
[1], "-e")!=0)
189 die("Usage: ionflux [-e code]");
191 if(strlen(argv
[2])>=MAX_DATA
)
192 die("Too much data.");
197 sockname
=get_socket();
201 if(strlen(sockname
)>SOCK_MAX
)
202 die("Socket name too long.");
204 sock
=socket(AF_UNIX
, SOCK_STREAM
, 0);
206 die_e("Opening socket");
208 serv
.sun_family
=AF_UNIX
;
209 strcpy(serv
.sun_path
, sockname
);
211 if(connect(sock
, (struct sockaddr
*)&serv
, sizeof(struct sockaddr_un
))<0)
212 die_e("Connecting socket");
215 mywrite(sock
, argv
[2], strlen(argv
[2])+1);
219 if(fgets(buf
, MAX_DATA
, stdin
)==NULL
)
221 mywrite(sock
, buf
, strlen(buf
));
223 mywrite(sock
, &c
, 1);
226 n
=myread(sock
, &res
, 1);
228 if(n
!=1 || (res
!='E' && res
!='S'))
229 die("Invalid response");
232 n
=myread(sock
, buf
, MAX_DATA
);