Add non blocking virtio port code
[vd_agent/hramrach.git] / vdagent-x11.c
blob8180d3c2508fa5f9fcf096d7094146d60bd07e1e
1 /* vdagent-x11.c vdagent x11 code
3 Copyright 2010 Red Hat, Inc.
5 Red Hat Authors:
6 Hans de Goede <hdegoede@redhat.com>
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* Note *all* X11 calls in this file which do not wait for a result must be
23 followed by an XFlush, given that the X11 code pumping the event loop
24 (and thus flushing queued writes) is only called when there is data to be
25 read from the X11 socket. */
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <X11/Xlib.h>
30 #include "vdagentd-proto.h"
31 #include "vdagent-x11.h"
33 struct vdagent_x11 {
34 Display *display;
35 struct udscs_connection *vdagentd;
36 int verbose;
37 int fd;
38 int screen;
39 int root_window;
40 int width;
41 int height;
44 static void vdagent_x11_send_guest_xorg_res(struct vdagent_x11 *x11);
46 struct vdagent_x11 *vdagent_x11_create(struct udscs_connection *vdagentd,
47 int verbose)
49 struct vdagent_x11 *x11;
50 XWindowAttributes attrib;
52 x11 = calloc(1, sizeof(*x11));
53 if (!x11) {
54 fprintf(stderr, "out of memory allocating vdagent_x11 struct\n");
55 return NULL;
58 x11->vdagentd = vdagentd;
59 x11->verbose = verbose;
61 x11->display = XOpenDisplay(NULL);
62 if (!x11->display) {
63 fprintf(stderr, "could not connect to X-server\n");
64 free(x11);
65 return NULL;
68 x11->screen = DefaultScreen(x11->display);
69 x11->root_window = RootWindow(x11->display, x11->screen);
70 x11->fd = ConnectionNumber(x11->display);
72 XSelectInput(x11->display, x11->root_window, StructureNotifyMask);
73 XGetWindowAttributes(x11->display, x11->root_window, &attrib);
75 x11->width = attrib.width;
76 x11->height = attrib.height;
78 vdagent_x11_send_guest_xorg_res(x11);
80 return x11;
83 void vdagent_x11_destroy(struct vdagent_x11 *x11)
85 if (!x11)
86 return;
88 XCloseDisplay(x11->display);
89 free(x11);
92 int vdagent_x11_get_fd(struct vdagent_x11 *x11)
94 return x11->fd;
97 void vdagent_x11_do_read(struct vdagent_x11 *x11)
99 XEvent event;
100 int handled = 0;
102 if (!XPending(x11->display))
103 return;
105 XNextEvent(x11->display, &event);
106 switch (event.type) {
107 case ConfigureNotify:
108 if (event.xconfigure.window != x11->root_window)
109 break;
111 handled = 1;
113 if (event.xconfigure.width == x11->width &&
114 event.xconfigure.height == x11->height)
115 break;
117 x11->width = event.xconfigure.width;
118 x11->height = event.xconfigure.height;
120 vdagent_x11_send_guest_xorg_res(x11);
121 break;
123 if (!handled && x11->verbose)
124 fprintf(stderr, "unhandled x11 event, type %d, window %d\n",
125 (int)event.type, (int)event.xany.window);
128 static void vdagent_x11_send_guest_xorg_res(struct vdagent_x11 *x11)
130 struct vdagentd_guest_xorg_resolution res;
131 struct udscs_message_header header;
133 header.type = VDAGENTD_GUEST_XORG_RESOLUTION;
134 header.opaque = 0;
135 header.size = sizeof(res);
137 res.width = x11->width;
138 res.height = x11->height;
140 udscs_write(x11->vdagentd, &header, (uint8_t *)&res);