--- /dev/null
+/*\r
+ * mainloop_evhandle.c\r
+ *\r
+ * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * DoHyung Hong <don.hong@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+\r
+#ifdef _WIN32\r
+#include <winsock.h>\r
+#define socklen_t int\r
+#else\r
+#include <netinet/in.h>\r
+#include <sys/ioctl.h>\r
+#endif\r
+\r
+#include "qobject.h"\r
+#include "qemu-common.h"\r
+#include "hw/usb.h"\r
+#include "mloop_event.h"\r
+\r
+#define error_report(x, ...)\r
+\r
+struct mloop_evsock {\r
+ int sockno;\r
+ unsigned short portno;\r
+ unsigned char status;\r
+};\r
+\r
+#define MLOOP_EVSOCK_NULL 0\r
+#define MLOOP_EVSOCK_CREATED 1\r
+#define MLOOP_EVSOCK_NOTBOUND 2\r
+#define MLOOP_EVSOCK_BOUND 3\r
+#define MLOOP_EVSOCK_CONNECTED 4\r
+\r
+#define PACKET_LEN 128\r
+struct mloop_evpack {\r
+ short type;\r
+ short size;\r
+ char data[PACKET_LEN-4];\r
+};\r
+\r
+#define MLOOP_EVTYPE_USB_ADD 1\r
+#define MLOOP_EVTYPE_USB_DEL 2\r
+\r
+static struct mloop_evsock mloop = {-1,0,0};\r
+\r
+static int mloop_evsock_create(struct mloop_evsock *ev)\r
+{\r
+ struct sockaddr sa;\r
+ socklen_t sa_size;\r
+ int ret;\r
+ unsigned long nonblock = 1;\r
+\r
+ if (ev == NULL) {\r
+ error_report("mloop_evsock: null point");\r
+ return -1;\r
+ }\r
+\r
+ ev->sockno = socket(AF_INET, SOCK_DGRAM, 0);\r
+ if( ev->sockno == -1 ) {\r
+ error_report("mloop_evsock: socket() failed");\r
+ return -1;\r
+ }\r
+\r
+#ifdef _WIN32\r
+ ioctlsocket(ev->sockno, FIONBIO, &nonblock );\r
+#else\r
+ ioctl(ev->sockno, FIONBIO, &nonblock);\r
+#endif // _WIN32\r
+\r
+ nonblock = 1 ;\r
+ setsockopt( ev->sockno, SOL_SOCKET, SO_REUSEADDR, (char *)&nonblock, sizeof(nonblock) ) ;\r
+\r
+ memset(&sa, '\0', sizeof(sa));\r
+ ((struct sockaddr_in *) &sa)->sin_family = AF_INET;\r
+ memcpy(&((struct sockaddr_in *) &sa)->sin_addr, "\177\000\000\001", 4); // 127.0.0.1\r
+ ((struct sockaddr_in *) &sa)->sin_port = htons(ev->portno);\r
+ sa_size = sizeof(struct sockaddr_in);\r
+\r
+ ret = bind(ev->sockno, &sa, sa_size);\r
+ if (ret) {\r
+ error_report("mloop_evsock: bind() failed");\r
+ goto mloop_evsock_init_cleanup;\r
+ }\r
+\r
+ if (ev->portno == 0) {\r
+ memset(&sa, '\0', sizeof(sa));\r
+ getsockname(ev->sockno, (struct sockaddr *) &sa, &sa_size);\r
+ ev->portno = ntohs(((struct sockaddr_in *) &sa)->sin_port);\r
+ }\r
+\r
+ ret = connect(ev->sockno, (struct sockaddr *) &sa, sa_size);\r
+ if (ret) {\r
+ error_report("mloop_evsock: connect() failed");\r
+ goto mloop_evsock_init_cleanup;\r
+ }\r
+\r
+ ev->status = MLOOP_EVSOCK_CONNECTED;\r
+ return 0;\r
+\r
+mloop_evsock_init_cleanup:\r
+#ifdef _WIN32\r
+ closesocket(ev->sockno);\r
+#else\r
+ close(ev->sockno);\r
+#endif\r
+ ev->sockno = -1;\r
+ ev->status = 0;\r
+ return ret;\r
+}\r
+\r
+static void mloop_evsock_remove(struct mloop_evsock *ev)\r
+{\r
+ if (!ev) {\r
+ return ;\r
+ }\r
+\r
+ if (ev->sockno > 0) {\r
+#ifdef _WIN32\r
+ shutdown(ev->sockno, SD_BOTH);\r
+ closesocket(ev->sockno);\r
+#else\r
+ shutdown(ev->sockno, SHUT_RDWR);\r
+ close(ev->sockno);\r
+#endif\r
+ ev->sockno = -1;\r
+ ev->status = 0;\r
+ }\r
+}\r
+\r
+static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p)\r
+{\r
+ int ret;\r
+\r
+ if (ev == NULL || ev->sockno == -1) {\r
+ error_report("invalid mloop_evsock");\r
+ return -1;\r
+ }\r
+\r
+ if (p == NULL || p->size <= 0) {\r
+ error_report("invalid mloop_evpack");\r
+ return -1;\r
+ }\r
+\r
+ do {\r
+ ret = send(ev->sockno, p, ntohs(p->size), 0);\r
+#ifdef _WIN32\r
+ } while (ret == -1 && (WSAGetLastError() == WSAEWOULDBLOCK));\r
+#else\r
+ } while (ret == -1 && (errno == EWOULDBLOCK || errno == EINTR));\r
+#endif // _WIN32\r
+\r
+ return ret;\r
+}\r
+\r
+static USBDevice *usbkbd = NULL;\r
+static void mloop_evhandle_usb_add(char *name)\r
+{\r
+ if (name == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (strcmp(name, "keyboard") == 0) {\r
+ if (usbkbd == NULL) {\r
+ usbkbd = usbdevice_create(name);\r
+ }\r
+ else if (usbkbd->attached == 0) {\r
+ usb_device_attach(usbkbd);\r
+ }\r
+ }\r
+}\r
+\r
+static void mloop_evhandle_usb_del(char *name)\r
+{\r
+ if (name == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (strcmp(name, "keyboard") == 0) {\r
+ if (usbkbd && usbkbd->attached != 0) {\r
+ usb_device_detach(usbkbd);\r
+ }\r
+ }\r
+}\r
+\r
+static void mloop_evcb_recv(struct mloop_evsock *ev)\r
+{\r
+ struct mloop_evpack pack;\r
+ int ret;\r
+\r
+ do {\r
+ ret = recv(ev->sockno, (void *)&pack, sizeof(pack), 0);\r
+#ifdef _WIN32\r
+ } while (ret == -1 && WSAGetLastError() == WSAEINTR);\r
+#else\r
+ } while (ret == -1 && errno == EINTR);\r
+#endif // _WIN32\r
+\r
+ if (ret == -1 ) {\r
+ return;\r
+ }\r
+\r
+ if (ret == 0 ) {\r
+ return;\r
+ }\r
+\r
+ pack.type = ntohs(pack.type);\r
+ pack.size = ntohs(pack.size);\r
+\r
+ switch (pack.type) {\r
+ case MLOOP_EVTYPE_USB_ADD:\r
+ mloop_evhandle_usb_add(pack.data);\r
+ break;\r
+ case MLOOP_EVTYPE_USB_DEL:\r
+ mloop_evhandle_usb_del(pack.data);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+extern int qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque);\r
+void mloop_ev_init(void)\r
+{\r
+ int ret = mloop_evsock_create(&mloop);\r
+ if (ret == 0) {\r
+ qemu_set_fd_handler(mloop.sockno, (IOHandler *)mloop_evcb_recv, NULL, &mloop);\r
+ }\r
+}\r
+\r
+void mloop_ev_stop(void)\r
+{\r
+ qemu_set_fd_handler(mloop.sockno, NULL, NULL, NULL);\r
+ mloop_evsock_remove(&mloop);\r
+}\r
+\r
+void mloop_evcmd_usbkbd_on(void)\r
+{\r
+ struct mloop_evpack pack = { htons(MLOOP_EVTYPE_USB_ADD), htons(13), "keyboard" };\r
+ mloop_evsock_send(&mloop, &pack);\r
+}\r
+\r
+void mloop_evcmd_usbkbd_off(void)\r
+{\r
+ struct mloop_evpack pack = { htons(MLOOP_EVTYPE_USB_DEL), htons(13), "keyboard" };\r
+ mloop_evsock_send(&mloop, &pack);\r
+}\r
--- /dev/null
+/*\r
+ * mainloop_evhandle.c\r
+ *\r
+ * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * DoHyung Hong <don.hong@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#ifndef MLOOP_EVENT_H_\r
+#define MLOOP_EVENT_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+void mloop_ev_init(void);\r
+void mloop_ev_stop(void);\r
+\r
+void mloop_evcmd_usbkbd_on(void);\r
+void mloop_evcmd_usbkbd_off(void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* MLOOP_EVENT_H_ */\r