#include "project.h" #include "output_map.h" output_dev_t *output_devs; static output_dev_t * iface_to_dev (int iface) { output_dev_t *ret; for (ret = output_devs; ret; ret = ret->next) { if (!(iface--)) return ret; } return NULL; } static int send_flush (output_dev_t * o) { int ret; uint8_t rbuf[36]; uint8_t xbuf[31] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy (&xbuf[4], &o->seq, 4); o->seq++; /*Sends SCSI test unit ready*/ if (usb_bulk_write (o->devh, 0x2, (char *) xbuf, 31, 10) != 31) return -1; ret = usb_bulk_read (o->devh, 0x81, (char *) rbuf, 36, 10); if (ret <= 0) return -1; return 0; } static int send_msg (output_dev_t * o, uint8_t * msg) { int ret; uint8_t xbuf[31] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x54 }; uint8_t rbuf[36]; memcpy (&xbuf[16], msg, 13); memcpy (&xbuf[4], &o->seq, 4); o->seq++; /* READ CD-DA MSF !*/ if (usb_bulk_write (o->devh, 0x2, (char *) xbuf, 31, 10) != 31) return -1; ret = usb_bulk_read (o->devh, 0x81, (char *) rbuf, 36, 10); if (ret <= 0) return -1; return 0; } static int mouse (output_dev_t * o, uint16_t x, uint16_t y, uint8_t s, int l, int m, int r) { uint8_t bmask = (l ? 1 : 0) | (m ? 4 : 0) | (r ? 2 : 0); uint8_t msg[13] = { 0x33, bmask, s, x & 0xff, x >> 8, y & 0xff, y >> 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // printf ("Mouse x=%4d y=%4d scroll=%2x bmask=%x\n", x, y, s, bmask); return send_msg (o, msg); } static int send_key_list (output_dev_t * o, uint8_t modifiers) { uint8_t msg[13] = { 0x34, modifiers, 0x00 }; memcpy (&msg[3], o->keys, OUTPUT_KEY_LIST_LEN); #if 0 int i; printf ("Keybd modifiers mask=%x key list=", modifiers); for (i = 0; i < OUTPUT_KEY_LIST_LEN; ++i) { if (o->keys[i]) printf ("%02x ", o->keys[i]); } printf ("\n"); #endif return send_msg (o, msg); } static int key_down (output_dev_t * o, uint8_t key, uint8_t modifiers) { int i; //printf("Key %d down modifiers %x\n",key,modifiers); if (key) { do { for (i = 0; i < sizeof (o->keys); ++i) { if (o->keys[i] == key) break; } for (i = 0; i < sizeof (o->keys); ++i) { if (!o->keys[i]) { o->keys[i] = key; break; } } } while (0); } return send_key_list (o, modifiers); } static int key_up (output_dev_t * o, uint8_t key, uint8_t modifiers) { int i; //printf("Key %d up modifiers %x\n",key,modifiers); if (key) { for (i = 0; i < sizeof (o->keys); ++i) { if (o->keys[i] == key) o->keys[i] = 0; } } return send_key_list (o, modifiers); } struct map_ent * lookup_map_ent (int keycode, uint8_t modifiers) { int i; for (i = 0; i < MAP_LEN; ++i) { if (map[i].keycode == keycode) { if (map[i].hacks & (HACK_RCS | HACK_HS)) { /*Do we require a shift key to match ? */ if (modifiers & HACK_SHIFT_MASK) return &map[i]; } else { return &map[i]; } } } return NULL; } void send_keyboard_event (int computer, int k, int ud) { static uint8_t modifiers; uint8_t mods; struct map_ent *e = lookup_map_ent (k, modifiers); output_dev_t *o; map_output (&computer, NULL, NULL); o = iface_to_dev (computer); if (!o) return; if (!e) return; if (e->hacks & HACK_MODIFIER_MASK) { if (ud) { modifiers |= e->hacks & HACK_MODIFIER_MASK; } else { modifiers &= ~(e->hacks & HACK_MODIFIER_MASK); } } if (e->hacks & HACK_HS) { mods = modifiers & ~HACK_SHIFT_MASK; if (ud) { if (modifiers & HACK_SHIFT_L) key_up (o, 0xe1, mods); if (modifiers & HACK_SHIFT_R) key_up (o, 0xe5, mods); } } else { mods = modifiers; } #if 0 printf ("Hacks %8x, modifiers=%4x, mods=%4x, e->keysym=%4x, e->keycode=%4x, e->code=%2x\n", e->hacks, modifiers, mods, e->keysym, e->keycode, e->code); #endif if (ud) key_down (o, e->code, mods); else key_up (o, e->code, mods); if (e->hacks & HACK_HS) { if (!ud) { if (modifiers & HACK_SHIFT_L) key_down (o, 0xe1, modifiers); if (modifiers & HACK_SHIFT_R) key_down (o, 0xe5, modifiers); } } send_flush (o); } void send_mouse_event (int computer, int x, int y, int s, int l, int m, int r) { output_dev_t *o; map_output (&computer, &x, &y); o = iface_to_dev (computer); if (!o) return; if (s < 0) s += 256; if (x < 0) x = 0; if (y < 0) y = 0; if (x > 2047) x = 2047; if (y > 2047) y = 2047; mouse (o, x, y, s, l, m, r); if (s) send_flush (o); } static output_dev_t * get_output_dev (struct usb_device *dev) { struct usb_dev_handle *devh; output_dev_t *o; for (o = output_devs; o; o = o->next) if (!strcmp (o->filename, dev->filename)) return o; printf ("New output: %s\n", dev->filename); devh = usb_open (dev); if (!devh) return NULL; usb_reset (devh); usb_close (devh); usleep (100000); devh = usb_open (dev); if (!devh) return NULL; usb_detach_kernel_driver_np (devh, 0); usb_detach_kernel_driver_np (devh, 1); usb_detach_kernel_driver_np (devh, 2); usb_claim_interface (devh, 0); usb_clear_halt (devh, 0x81); usb_clear_halt (devh, 0x2); o = malloc (sizeof (*o)); bzero (o, sizeof (*o)); strcpy (o->filename, dev->filename); o->devh = devh; o->next = output_devs; output_devs = o; return o; } static void free_output_dev (output_dev_t * o) { printf ("Lost output: %s\n", o->filename); if (o->devh) usb_close (o->devh); free (o); } void scan_output_devs (int init) { struct usb_bus *bus; struct usb_device *dev; output_dev_t *od, **odp; usb_find_busses (); if (!init && !usb_find_devices ()) return; for (od = output_devs; od; od = od->next) od->present = 0; for (bus = usb_get_busses (); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if ((dev->descriptor.idVendor == 0x0ea0) && (dev->descriptor.idProduct == 0x2211)) { od = get_output_dev (dev); if (od) od->present = 1; } } } for (odp = &output_devs; (od = *odp);) { if (!od->present) { *odp = od->next; free_output_dev (od); } else { odp = &od->next; } } } void output_reset (void) { output_dev_t *od, **odp; for (odp = &output_devs; (od = *odp);) { *odp = od->next; free_output_dev (od); } scan_output_devs (1); }