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>
22 #include <sys/types.h>
23 #include <sys/socket.h>
26 #include "../notionflux.h"
28 static void die(const char *s
)
30 fprintf(stderr
, "%s\n", s
);
35 static void die_e(const char *s
)
41 static void mywrite(int fd
, const char *buf
, int n
)
46 if(k
<0 && (errno
!=EAGAIN
&& errno
!=EINTR
))
56 static int myread(int fd
, char *buf
, int n
)
62 k
=read(fd
, buf
, left
);
63 if(k
<0 && (errno
!=EAGAIN
&& errno
!=EINTR
))
76 static char buf
[MAX_DATA
];
82 static Display
*dpy
=NULL
;
85 static ulong
xwindow_get_property_(Window win
, Atom atom
, Atom type
,
86 ulong n32expected
, bool more
, uchar
**p
,
94 status
=XGetWindowProperty(dpy
, win
, atom
, 0L, n32expected
,
95 False
, type
, &real_type
, format
, &n
,
98 if(status
!=Success
|| *p
==NULL
)
101 if(extra
==0 || !more
)
105 n32expected
+=(extra
+4)/4;
119 ulong
xwindow_get_property(Window win
, Atom atom
, Atom type
,
120 ulong n32expected
, bool more
, uchar
**p
)
123 return xwindow_get_property_(win
, atom
, type
, n32expected
, more
, p
,
128 char *xwindow_get_string_property(Window win
, Atom a
, int *nret
)
133 n
=xwindow_get_property(win
, a
, XA_STRING
, 64L, TRUE
, (uchar
**)&p
);
138 return (n
<=0 ? NULL
: p
);
142 void xwindow_set_string_property(Window win
, Atom a
, const char *value
)
145 XDeleteProperty(dpy
, win
, a
);
147 XChangeProperty(dpy
, win
, a
, XA_STRING
,
148 8, PropModeReplace
, (uchar
*)value
, strlen(value
));
153 static char *get_socket()
158 dpy
=XOpenDisplay(NULL
);
161 die_e("Unable to open display.");
163 a
=XInternAtom(dpy
, "_NOTION_MOD_NOTIONFLUX_SOCKET", True
);
166 die_e("Missing atom. Notion not running?");
168 s
=xwindow_get_string_property(DefaultRootWindow(dpy
), a
, NULL
);
179 int main(int argc
, char *argv
[])
182 struct sockaddr_un serv
;
183 const char *sockname
;
189 if(argc
!=3 || strcmp(argv
[1], "-e")!=0)
190 die("Usage: notionflux [-e code]");
192 if(strlen(argv
[2])>=MAX_DATA
)
193 die("Too much data.");
198 sockname
=get_socket();
202 if(strlen(sockname
)>SOCK_MAX
)
203 die("Socket name too long.");
205 sock
=socket(AF_UNIX
, SOCK_STREAM
, 0);
207 die_e("Opening socket");
209 serv
.sun_family
=AF_UNIX
;
210 strcpy(serv
.sun_path
, sockname
);
212 if(connect(sock
, (struct sockaddr
*)&serv
, sizeof(struct sockaddr_un
))<0)
213 die_e("Connecting socket");
216 mywrite(sock
, argv
[2], strlen(argv
[2])+1);
220 if(fgets(buf
, MAX_DATA
, stdin
)==NULL
)
222 mywrite(sock
, buf
, strlen(buf
));
224 mywrite(sock
, &c
, 1);
227 n
=myread(sock
, &res
, 1);
229 if(n
!=1 || (res
!='E' && res
!='S'))
230 die("Invalid response");
233 n
=myread(sock
, buf
, MAX_DATA
);