#include "mapcache.h"
#include "ps2.h"
#include "kbd.h"
+#include "mouse.h"
#include "vga.h"
#include "pci.h"
#include "surface.h"
DEMU_SEQ_EVTCHN_OPEN,
DEMU_SEQ_PORTS_BOUND,
DEMU_SEQ_BUF_PORT_BOUND,
+ DEMU_SEQ_CMD_INITIALIZED,
DEMU_SEQ_KBD_INITIALIZED,
+ DEMU_SEQ_MOUSE_INITIALIZED,
DEMU_SEQ_VNC_INITIALIZED,
DEMU_SEQ_VGA_INITIALIZED,
DEMU_SEQ_PS2_INITIALIZED,
void *priv;
};
+struct demu_kbd_cmd {
+ char cmd;
+ rfbKeySym sym;
+ int down;
+};
+
+struct demu_mouse_cmd {
+ char cmd;
+ int x;
+ int y;
+ int buttons;
+};
+
+#define MAX_CMDLEN (__max(sizeof (struct demu_mouse_cmd), \
+ sizeof (struct demu_kbd_cmd)))
+
typedef struct demu_state {
demu_seq_t seq;
timer_t timer_id;
void (*tick)(void);
+ int cmd[2];
xc_interface *xch;
xc_interface *xceh;
domid_t domid;
evtchn_port_t buf_ioreq_local_port;
uint32_t width;
uint32_t height;
- int32_t x;
- int32_t y;
uint32_t depth;
uint8_t *default_framebuffer;
uint8_t *framebuffer;
static void demu_vnc_mouse(int buttonMask, int x, int y, rfbClientPtr client)
{
- int dx, dy, dz;
- int lb, mb, rb;
-
- if (demu_state.x == -1)
- goto done;
+ struct demu_mouse_cmd cmd;
- lb = !!(buttonMask & 0x01);
- mb = !!(buttonMask & 0x02);
- rb = !!(buttonMask & 0x04);
+ cmd.cmd = 'M';
+ cmd.x = x;
+ cmd.y = y;
+ cmd.buttons = buttonMask;
- dx = x - demu_state.x;
- dy = y - demu_state.y;
- dz = 0;
-
- if (buttonMask & 0x08)
- dz = -1;
- if (buttonMask & 0x10)
- dz = 1;
-
- ps2_mouse_event(dx, dy, dz, lb, mb, rb);
-
-done:
- demu_state.x = x;
- demu_state.y = y;
+ write(demu_state.cmd[1], &cmd, sizeof (cmd));
rfbDefaultPtrAddEvent(buttonMask, x, y, client);
}
static void demu_vnc_key(rfbBool down, rfbKeySym sym, rfbClientPtr client)
{
- kbd_event(sym, down);
+ struct demu_kbd_cmd cmd;
+
+ cmd.cmd = 'K';
+ cmd.sym = sym;
+ cmd.down = down;
+
+ write(demu_state.cmd[1], &cmd, sizeof (cmd));
}
static void demu_vnc_remove_client(rfbClientPtr client)
unsigned int x, y;
rfbScreenInfoPtr screen;
- demu_state.x = -1;
- demu_state.y = -1;
-
framebuffer = malloc(DEMU_VNC_DEFAULT_WIDTH *
DEMU_VNC_DEFAULT_HEIGHT *
DEMU_VNC_DEFAULT_DEPTH);
demu_state.buf_ioreq_local_port);
break;
+ case DEMU_SEQ_CMD_INITIALIZED:
+ DBG(">CMD_INITIALIZED\n");
+ break;
+
case DEMU_SEQ_KBD_INITIALIZED:
DBG(">KBD_INITIALIZED\n");
break;
+ case DEMU_SEQ_MOUSE_INITIALIZED:
+ DBG(">MOUSE_INITIALIZED\n");
+ break;
+
case DEMU_SEQ_VNC_INITIALIZED:
DBG(">VNC_INITIALIZED\n");
break;
demu_state.seq = DEMU_SEQ_KBD_INITIALIZED;
}
+ if (demu_state.seq == DEMU_SEQ_MOUSE_INITIALIZED) {
+ DBG("<MOUSE_INITIALIZED\n");
+ mouse_teardown();
+
+ demu_state.seq = DEMU_SEQ_KBD_INITIALIZED;
+ }
+
if (demu_state.seq == DEMU_SEQ_KBD_INITIALIZED) {
DBG("<KBD_INITIALIZED\n");
kbd_teardown();
+ demu_state.seq = DEMU_SEQ_CMD_INITIALIZED;
+ }
+
+ if (demu_state.seq == DEMU_SEQ_CMD_INITIALIZED) {
+ DBG("<CMD_INITIALIZED\n");
+
+ close(demu_state.cmd[1]);
+ close(demu_state.cmd[0]);
+
demu_state.seq = DEMU_SEQ_PORTS_BOUND;
}
demu_seq_next();
+ if (pipe(demu_state.cmd) < 0)
+ goto fail11;
+
+ demu_seq_next();
+
rc = kbd_initialize((keymap) ? keymap : DEMU_KEYMAP);
if (rc < 0)
- goto fail11;
+ goto fail12;
+
+ demu_seq_next();
+
+ rc = mouse_initialize();
+ if (rc < 0)
+ goto fail13;
demu_seq_next();
rc = demu_vnc_initialize();
if (rc < 0)
- goto fail12;
+ goto fail14;
demu_seq_next();
DEMU_VRAM_SIZE,
(rom_file) ? rom_file : DEMU_ROM_FILE);
if (rc < 0)
- goto fail13;
+ goto fail15;
demu_seq_next();
rc = ps2_initialize();
if (rc < 0)
- goto fail14;
+ goto fail16;
demu_seq_next();
rc = surface_initialize();
if (rc < 0)
- goto fail15;
+ goto fail17;
demu_seq_next();
rc = pthread_create(&demu_state.thread, NULL, demu_thread, NULL);
if (rc != 0)
- goto fail16;
+ goto fail18;
demu_seq_next();
assert(demu_state.seq == DEMU_SEQ_INITIALIZED);
return 0;
+fail18:
+ DBG("fail18\n");
+
+fail17:
+ DBG("fail17\n");
+
fail16:
DBG("fail16\n");
sigset_t block;
int efd;
int tfd;
+ int cfd;
int rc;
prog = basename(argv[0]);
efd = xc_evtchn_fd(demu_state.xceh);
+ cfd = demu_state.cmd[0];
+
for (;;) {
fd_set rfds;
fd_set wfds;
FD_SET(tfd, &rfds);
FD_SET(efd, &rfds);
+ FD_SET(cfd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = demu_state.screen->deferUpdateTime * 1000;
- nfds = max(tfd, efd) + 1;
+ nfds = __max(tfd, (__max(efd, cfd))) + 1;
rc = select(nfds, &rfds, &wfds, &xfds, &tv);
if (rc > 0) {
demu_poll_iopages();
if (FD_ISSET(tfd, &rfds)) {
- char buf;
+ char buf;
- read(tfd, &buf, 1);
+ (void) read(tfd, &buf, 1);
demu_timer_tick();
}
+
+ if (FD_ISSET(cfd, &rfds)) {
+ char buf[MAX_CMDLEN];
+ ssize_t len;
+
+ len = read(cfd, buf, MAX_CMDLEN);
+ if (len > 0) {
+ switch (buf[0]) {
+ case 'K': {
+ struct demu_kbd_cmd *cmd;
+
+ assert(len >= sizeof (struct demu_kbd_cmd));
+ cmd = (struct demu_kbd_cmd *)&buf[0];
+
+ kbd_event(cmd->sym, cmd->down);
+ break;
+ }
+ case 'M': {
+ struct demu_mouse_cmd *cmd;
+
+ assert(len >= sizeof (struct demu_mouse_cmd));
+ cmd = (struct demu_mouse_cmd *)&buf[0];
+
+ mouse_event(cmd->x, cmd->y, cmd->buttons);
+ break;
+ }
+ default:
+ assert(FALSE);
+ break;
+ }
+ }
+ }
}
if (rc < 0 && errno != EINTR)
--- /dev/null
+/*
+ * Copyright (c) 2014, Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <err.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <string.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <rfb/rfb.h>
+#include <rfb/keysym.h>
+
+#include "debug.h"
+#include "mouse.h"
+#include "ps2.h"
+
+typedef struct mouse {
+ int x;
+ int y;
+} mouse_t;
+
+static mouse_t mouse_state;
+
+void
+mouse_event(int x, int y, int buttons)
+{
+ int lb, mb, rb;
+ int dx, dy, dz;
+
+ if (mouse_state.x == -1)
+ goto done;
+
+ lb = !!(buttons & 0x01);
+ mb = !!(buttons & 0x02);
+ rb = !!(buttons & 0x04);
+
+ dx = x - mouse_state.x;
+ dy = y - mouse_state.y;
+ dz = 0;
+
+ if (buttons & 0x08)
+ dz = -1;
+ if (buttons & 0x10)
+ dz = 1;
+
+ ps2_mouse_event(dx, dy, dz, lb, mb, rb);
+
+done:
+ mouse_state.x = x;
+ mouse_state.y = y;
+}
+
+int
+mouse_initialize()
+{
+ mouse_state.x = -1;
+ mouse_state.y = -1;
+
+ return 0;
+}
+
+void
+mouse_teardown(void)
+{
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-tab-always-indent: nil
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * c-basic-indent: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/*
+ * Copyright (c) 2014, Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef _MOUSE_H
+#define _MOUSE_H
+
+int mouse_initialize(void);
+void mouse_teardown(void);
+
+void mouse_event(int x, int y, int buttons);
+
+#endif /*_MOUSE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-tab-always-indent: nil
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * c-basic-indent: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
+