2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2004-2008 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include "e16-ecore_hints.h"
29 #include "e16-ecore_list.h"
42 static void CommsSend(Client * c, const char *s);
44 static Ecore_List *client_list = NULL;
46 static Win comms_win = NULL;
49 ClientCreate(Window xwin)
54 c = ECALLOC(Client, 1);
58 Esnprintf(st, sizeof(st), "%8x", (int)xwin);
59 c->name = Estrdup(st);
63 client_list = ecore_list_new();
64 ecore_list_prepend(client_list, c);
70 ClientDestroy(Client * c)
75 ecore_list_node_remove(client_list, c);
87 ClientConfigure(Client * c, const char *str)
94 sscanf(str, "%*s %60s %n", param, &len);
97 if (!strcmp(param, "clientname"))
100 c->clientname = Estrdup(value);
102 else if (!strcmp(param, "version"))
105 c->version = Estrdup(value);
107 else if (!strcmp(param, "author"))
110 else if (!strcmp(param, "email"))
113 else if (!strcmp(param, "web"))
116 else if (!strcmp(param, "address"))
119 else if (!strcmp(param, "info"))
122 c->info = Estrdup(value);
124 else if (!strcmp(param, "pixmap"))
136 ClientMatchWindow(const void *data, const void *match)
138 return ((const Client *)data)->xwin != (Window) match;
142 ClientFind(Window xwin)
144 return (Client *) ecore_list_find(client_list, ClientMatchWindow,
149 ClientCommsGet(Client ** c, XClientMessageEvent * ev)
151 char s[13], s2[9], *msg;
158 if (ev->message_type != E16_ATOM_COMMS_MSG)
163 for (i = 0; i < 8; i++)
164 s2[i] = ev->data.b[i];
165 for (i = 0; i < 12; i++)
166 s[i] = ev->data.b[i + 8];
168 sscanf(s2, "%lx", &xwin);
171 cl = ClientFind(xwin);
174 cl = ClientCreate(xwin);
179 /* append text to end of msg */
180 i = (cl->msg) ? strlen(cl->msg) : 0;
181 cl->msg = EREALLOC(char, cl->msg, i + strlen(s) + 1);
184 strcpy(cl->msg + i, s);
198 ClientIpcReply(void *data, const char *str)
200 Client *c = (Client *) data;
204 /* Don't send empty replies (ack's) if we ever have replied to this
205 * client. Without this hack communication with e.g. epplets fails. */
215 ClientHandleComms(XClientMessageEvent * ev)
220 s = ClientCommsGet(&c, ev);
224 if (EDebug(EDBUG_TYPE_IPC))
225 Eprintf("ClientHandleComms: %s\n", s);
227 if (!strncmp(s, "set ", 4))
229 /* The old Client set command (used by epplets) */
230 if (ClientConfigure(c, s) == 0)
234 if (!IpcExecReply(s, ClientIpcReply, c))
238 s1 = (c->clientname) ? c->clientname : "UNKNOWN";
239 s2 = (c->version) ? c->version : "UNKNOWN";
240 DialogOK(_("E IPC Error"),
241 _("Received Unknown Client Message.\n"
242 "Client Name: %s\n" "Client Version: %s\n"
243 "Message Contents:\n\n" "%s\n"), s1, s2, s);
244 SoundPlay(SOUND_ERROR_IPC);
252 ClientHandleRootEvents(Win win __UNUSED__, XEvent * ev, void *prm __UNUSED__)
257 Eprintf("ClientHandleRootEvents: type=%d win=%#lx\n", ev->type,
263 c = ClientFind(ev->xdestroywindow.window);
272 ClientHandleCommsEvents(Win win __UNUSED__, XEvent * ev, void *prm __UNUSED__)
275 Eprintf("ClientHandleCommsEvents: type=%d win=%#lx\n", ev->type,
281 ClientHandleComms(&(ev->xclient));
291 comms_win = ECreateEventWindow(VROOT, -100, -100, 5, 5);
292 ESelectInput(comms_win, StructureNotifyMask | SubstructureNotifyMask);
293 EventCallbackRegister(comms_win, 0, ClientHandleCommsEvents, NULL);
294 EventCallbackRegister(VROOT, 0, ClientHandleRootEvents, NULL);
296 Esnprintf(s, sizeof(s), "WINID %8lx", WinGetXwin(comms_win));
297 ecore_x_window_prop_string_set(WinGetXwin(comms_win), E16_ATOM_COMMS_WIN, s);
298 ecore_x_window_prop_string_set(WinGetXwin(VROOT), E16_ATOM_COMMS_WIN, s);
302 CommsDoSend(Window win, const char *s)
312 ev.xclient.type = ClientMessage;
313 ev.xclient.serial = 0;
314 ev.xclient.send_event = True;
315 ev.xclient.window = win;
316 ev.xclient.message_type = E16_ATOM_COMMS_MSG;
317 ev.xclient.format = 8;
318 for (i = 0; i < len + 1; i += 12)
320 Esnprintf(ss, sizeof(ss), "%8lx", WinGetXwin(comms_win));
321 for (j = 0; j < 12; j++)
323 ss[8 + j] = s[i + j];
328 for (k = 0; k < 20; k++)
329 ev.xclient.data.b[k] = ss[k];
330 EXSendEvent(win, 0, (XEvent *) & ev);
335 CommsSend(Client * c, const char *s)
340 CommsDoSend(c->xwin, s);