X-Git-Url: https://git.ao2.it/libam7xxx.git/blobdiff_plain/69c8952c3d754f6928f9628e6ce4d7de95fa846d..3fc490e6530865e1b33cd57c7a6bfcc9aff66ab6:/src/am7xxx.c diff --git a/src/am7xxx.c b/src/am7xxx.c index bc671f1..83d9a91 100644 --- a/src/am7xxx.c +++ b/src/am7xxx.c @@ -107,6 +107,7 @@ static struct am7xxx_usb_device_descriptor supported_devices[] = { struct _am7xxx_device { libusb_device_handle *usb_device; uint8_t buffer[AM7XXX_HEADER_WIRE_SIZE]; + am7xxx_device_info *device_info; am7xxx_context *ctx; am7xxx_device *next; }; @@ -556,8 +557,8 @@ static int scan_devices(am7xxx_context *ctx, scan_op op, continue; for (j = 0; j < ARRAY_SIZE(supported_devices); j++) { - if (desc.idVendor == supported_devices[j].vendor_id - && desc.idProduct == supported_devices[j].product_id) { + if (desc.idVendor == supported_devices[j].vendor_id && + desc.idProduct == supported_devices[j].product_id) { if (op == SCAN_OP_BUILD_DEVLIST) { am7xxx_device *new_device; @@ -674,6 +675,7 @@ AM7XXX_PUBLIC void am7xxx_shutdown(am7xxx_context *ctx) while (current) { am7xxx_device *next = current->next; am7xxx_close_device(current); + free(current->device_info); free(current); current = next; } @@ -701,12 +703,28 @@ AM7XXX_PUBLIC int am7xxx_open_device(am7xxx_context *ctx, am7xxx_device **dev, ret = scan_devices(ctx, SCAN_OP_OPEN_DEVICE, device_index, dev); if (ret < 0) { errno = ENODEV; + goto out; } else if (ret > 0) { warning(ctx, "device %d already open\n", device_index); errno = EBUSY; ret = -EBUSY; + goto out; + } + + /* Philips/Sagemcom PicoPix projectors require that the DEVINFO packet + * is the first one to be sent to the device in order for it to + * successfully return the correct device information. + * + * So, if there is not a cached version of it (from a previous open), + * we ask for device info at open time, + */ + if ((*dev)->device_info == NULL) { + ret = am7xxx_get_device_info(*dev, NULL); + if (ret < 0) + error(ctx, "cannot get device info\n"); } +out: return ret; } @@ -744,6 +762,11 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev, }, }; + if (dev->device_info) { + memcpy(device_info, dev->device_info, sizeof(*device_info)); + return 0; + } + ret = send_header(dev, &h); if (ret < 0) return ret; @@ -759,12 +782,20 @@ AM7XXX_PUBLIC int am7xxx_get_device_info(am7xxx_device *dev, return -ENOTSUP; } - device_info->native_width = h.header_data.devinfo.native_width; - device_info->native_height = h.header_data.devinfo.native_height; + dev->device_info = malloc(sizeof(*dev->device_info)); + if (dev->device_info == NULL) { + error(dev->ctx, "cannot allocate a device info (%s)\n", + strerror(errno)); + return -ENOMEM; + } + memset(dev->device_info, 0, sizeof(*dev->device_info)); + + dev->device_info->native_width = h.header_data.devinfo.native_width; + dev->device_info->native_height = h.header_data.devinfo.native_height; #if 0 /* No reason to expose these in the public API until we know what they mean */ - device_info->unknown0 = h.header_data.devinfo.unknown0; - device_info->unknown1 = h.header_data.devinfo.unknown1; + dev->device_info->unknown0 = h.header_data.devinfo.unknown0; + dev->device_info->unknown1 = h.header_data.devinfo.unknown1; #endif return 0;