/[rdesktop]/sourceforge.net/trunk/rdesktop/ipc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /sourceforge.net/trunk/rdesktop/ipc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 399 - (show annotations)
Fri Jun 6 10:10:04 2003 UTC (20 years, 11 months ago) by forsberg
File MIME type: text/plain
File size: 5261 byte(s)
Inter-rdesktop communication, initial revision.

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Communication between different rdesktop processes using X properties
4 Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <X11/Xlib.h>
22 #include <X11/Xatom.h>
23 #include "rdesktop.h"
24 #include "xproto.h"
25
26 Atom ipc_atom;
27
28 extern Display *display;
29 extern Window wnd;
30
31 static struct stream in;
32 static struct stream out;
33 static const uint16 headerlen = 12;
34
35 struct _ipc_channel;
36
37 typedef struct _ipc_channel
38 {
39 uint16 messagetype;
40 void (*callback) (unsigned char *, uint16 length);
41 struct _ipc_channel *next;
42 }
43 ipc_channel;
44
45 static ipc_channel *ipc_channels = NULL;
46
47 void
48 ipc_register_ipcnotify(uint16 messagetype, void (*notifycallback) (unsigned char *, uint16))
49 {
50 ipc_channel *this;
51 if (NULL != ipc_channels)
52 {
53 this = ipc_channels;
54 while (NULL != this->next)
55 this = this->next;
56 this->next = xmalloc(sizeof(ipc_channel));
57 this->next->next = NULL;
58 this = this->next;
59 }
60 else
61 {
62 this = xmalloc(sizeof(ipc_channel));
63 this->next = NULL;
64 ipc_channels = this;
65 }
66 this->messagetype = messagetype;
67 this->callback = notifycallback;
68 }
69
70 void
71 ipc_deregister_ipcnotify(uint16 messagetype)
72 {
73 ipc_channel *this, *prev;
74 prev = this = ipc_channels;
75 while (NULL != this)
76 {
77 if (this->messagetype == messagetype)
78 {
79 if (prev == this)
80 ipc_channels = this->next;
81 else
82 prev->next = this->next;
83 xfree(this);
84 return;
85 }
86 }
87 }
88
89 void
90 ipc_recv_message(XPropertyEvent * xev)
91 {
92 int actual_format_return;
93 unsigned long nitems_return, bytes_after_return;
94 unsigned char *prop_return;
95 unsigned char *data = NULL;
96 uint16 totalsize, rdesktop_ipc_version, messagetype;
97 uint32 sender_wnd;
98 Atom actual_type_return;
99 ipc_channel *channel = ipc_channels;
100
101 DEBUG_RDP5(("Got event in ipc_recv_message\n"));
102
103 in.end = in.p = in.data;
104
105 XGetWindowProperty(display, DefaultRootWindow(display), ipc_atom, 0, 1, False, // Delete
106 AnyPropertyType,
107 &actual_type_return,
108 &actual_format_return,
109 &nitems_return, &bytes_after_return, &prop_return);
110
111 memcpy(in.end, prop_return, 2);
112 XFree(prop_return);
113 in_uint32_le(&in, totalsize);
114 in.end += 4;
115
116 DEBUG_RDP5(("ipc totalsize is %d\n", totalsize));
117
118 XGetWindowProperty(display, DefaultRootWindow(display), ipc_atom, 1, (totalsize - 1) / 4, False, // Delete
119 AnyPropertyType,
120 &actual_type_return,
121 &actual_format_return,
122 &nitems_return, &bytes_after_return, &prop_return);
123
124 memcpy(in.end, prop_return, totalsize - 4);
125 XFree(prop_return);
126
127 in_uint16_le(&in, rdesktop_ipc_version);
128
129 DEBUG_RDP5(("Got rdesktop_ipc_version %d\n", rdesktop_ipc_version));
130
131 if (rdesktop_ipc_version > RDESKTOP_IPC_VERSION)
132 {
133 warning("IPC version of sending Rdesktop is higher than ours. Returning without trying to parse message\n");
134 return;
135 }
136
137 in_uint16_le(&in, messagetype);
138 in_uint32_le(&in, sender_wnd);
139
140 DEBUG_RDP5(("header: %d, %d, %d\n", rdesktop_ipc_version, messagetype, sender_wnd));
141
142
143 if (sender_wnd == wnd)
144 {
145 DEBUG_RDP5(("We sent this message, returning..\n"));
146 return; /* We are not interested in our own events.. */
147 }
148
149 DEBUG_RDP5(("Not our window..\n"));
150
151 /* Check if we are interested by traversing our callback list */
152 while (NULL != channel)
153 {
154 DEBUG_RDP5(("Found channel for messagetype %d\n", channel->messagetype));
155 if (messagetype == channel->messagetype)
156 {
157 data = xmalloc(in.size - headerlen);
158 in_uint8p(&in, data, totalsize - headerlen);
159 channel->callback(data, totalsize - headerlen);
160 return;
161 }
162 /* Callback is responsible for freeing data */
163 channel = channel->next;
164 }
165 }
166
167 void
168 ipc_init(void)
169 {
170 ipc_atom = XInternAtom(display, "_RDESKTOP_IPC", False);
171 xwin_register_propertynotify(DefaultRootWindow(display), ipc_atom, ipc_recv_message);
172 in.size = 4096;
173 in.data = xmalloc(in.size);
174 out.size = 4096;
175 out.data = xmalloc(out.size);
176 }
177
178 void
179 ipc_send_message(uint16 messagetype, unsigned char *data, uint16 length)
180 {
181
182 if ((length + headerlen) > out.size)
183 {
184 out.data = xrealloc(out.data, length + headerlen);
185 out.size = length + headerlen;
186 }
187 out.p = out.data;
188 out.end = out.data + out.size;
189
190 out_uint32_le(&out, length + headerlen);
191
192 out_uint16_le(&out, RDESKTOP_IPC_VERSION);
193 out_uint16_le(&out, messagetype);
194 out_uint32_le(&out, wnd);
195
196 out_uint8p(&out, data, length);
197 s_mark_end(&out);
198
199 DEBUG_RDP5(("length+headerlen is %d\n", length + headerlen));
200
201 XChangeProperty(display,
202 DefaultRootWindow(display),
203 ipc_atom, XA_STRING, 8, PropModeReplace, out.data, out.end - out.data);
204 XFlush(display);
205 }

  ViewVC Help
Powered by ViewVC 1.1.26