/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 forsberg 399 /* -*- 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