From 470457e22a1b5537013603d5e367c51e47bb61bf Mon Sep 17 00:00:00 2001 From: James Date: Mon, 5 May 2014 17:50:20 +0100 Subject: fish --- output.c | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 output.c (limited to 'output.c') diff --git a/output.c b/output.c new file mode 100644 index 0000000..c12262c --- /dev/null +++ b/output.c @@ -0,0 +1,441 @@ +#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); + + +} -- cgit v1.2.3