--- a/glcddrivers/ax206dpf.c +++ b/glcddrivers/ax206dpf.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include "common.h" #include "config.h" @@ -76,6 +76,8 @@ dh[i]->address[0] = 0; dh[i]->dpfh = NULL; dh[i]->LCD = NULL; + dh[i]->PRE = NULL; + dh[i]->justCleared = false; } lastbrightness = config->brightness ? config->brightness : 100; @@ -155,7 +157,9 @@ width /= zoom; } +#if 0 ResetMinMax(); +#endif *oldConfig = *config; @@ -177,8 +181,8 @@ bool cDriverAX206DPF::RescanUSB() { bool ret = false; - usb_find_busses(); - if (usb_find_devices() > 0) + libusb_device **list; + if (libusb_get_device_list(NULL, &list) > 0) { unsigned int a = 0, b = 0; for (unsigned int i = 0; i < numdisplays; i++) @@ -192,6 +196,8 @@ if (dh[i]->attached) b |= 0x01 << i; } ret = a != b; + + libusb_free_device_list(list, 1); } return ret; } @@ -212,15 +218,11 @@ { dh[di]->dpfh = NULL; dh[di]->attached = false; - return 0; + return error; } dh[di]->attached = true; - struct usb_device *dev = usb_device(dh[di]->dpfh->dev.udev); - char *s1 = dev->bus->dirname; - char *s2 = dev->filename; - if (strlen(s1) > 3) s1 = (char *) "???"; - if (strlen(s2) > 3) s2 = (char *) "???"; - sprintf(dh[di]->address, "%s:%s", s1, s2); + struct libusb_device *dev = libusb_get_device(dh[di]->dpfh->dev.udev); + sprintf(dh[di]->address, "%03u:%03u", libusb_get_bus_number(dev), libusb_get_device_address(dev)); // See, if we have to rotate the display dh[di]->isPortrait = dh[di]->dpfh->width < dh[di]->dpfh->height; @@ -250,6 +252,7 @@ } // setup physical lcd arrays dh[di]->LCD = (unsigned char *) malloc(dh[di]->dpfh->height * dh[di]->dpfh->width * dh[di]->dpfh->bpp); + dh[di]->PRE= (unsigned char *) malloc(dh[di]->dpfh->height * dh[di]->dpfh->width * dh[di]->dpfh->bpp); ClearSingleDisplay(di); // Set Display Brightness @@ -257,7 +260,9 @@ // Reorder displays +#if 0 bool changed = false; +#endif for (unsigned int i = 0; i < MAX_DPFS - 1; i++) { for (unsigned int j = i + 1; j < MAX_DPFS; j++) @@ -267,7 +272,9 @@ DISPLAYHANDLE *h = dh[i]; dh[i] = dh[j]; dh[j] = h; +#if 0 changed = true; +#endif } } } @@ -291,6 +298,10 @@ if (dh[di]->LCD != NULL) free(dh[di]->LCD); dh[di]->LCD = NULL; + + if (dh[di]->PRE != NULL) + free(dh[di]->PRE); + dh[di]->PRE = NULL; dh[di]->attached = false; dh[di]->address[0] = 0; @@ -353,7 +364,9 @@ { if (dh[di]->attached) { + dh[di]->justCleared = true; memset(dh[di]->LCD, 0, dh[di]->dpfh->width * dh[di]->dpfh->height * dh[di]->dpfh->bpp); //Black + memset(dh[di]->PRE, 1, dh[di]->dpfh->width * dh[di]->dpfh->height * dh[di]->dpfh->bpp); //whatever dh[di]->minx = 0; dh[di]->maxx = dh[di]->dpfh->width - 1; dh[di]->miny = 0; @@ -374,7 +387,9 @@ void cDriverAX206DPF::SetPixel(int x, int y, uint32_t data) { +#if 0 bool changed = false; +#endif if (config->upsideDown) { @@ -419,12 +434,16 @@ if (zoom == 1) { unsigned int i = (ly * dh[di]->dpfh->width + lx) * dh[di]->dpfh->bpp; +#if 0 if (dh[di]->LCD[i] != c1 || dh[di]->LCD[i+1] != c2) { +#endif dh[di]->LCD[i] = c1; dh[di]->LCD[i+1] = c2; +#if 0 changed = true; } +#endif } else { @@ -433,16 +452,21 @@ unsigned int i = ((ly + dy) * dh[di]->dpfh->width + lx) * dh[di]->dpfh->bpp; for (int dx = 0; dx < zoom * dh[di]->dpfh->bpp; dx += dh[di]->dpfh->bpp) { +#if 0 if (dh[di]->LCD[i+dx] != c1 || dh[di]->LCD[i+dx+1] != c2) { +#endif dh[di]->LCD[i+dx] = c1; dh[di]->LCD[i+dx+1] = c2; +#if 0 changed = true; } +#endif } } } +#if 0 if (changed) { if (lx < dh[di]->minx) dh[di]->minx = lx; @@ -450,6 +474,7 @@ if (ly < dh[di]->miny) dh[di]->miny = ly; if (ly > dh[di]->maxy) dh[di]->maxy = ly; } +#endif } void cDriverAX206DPF::Refresh(bool refreshAll) @@ -480,6 +505,60 @@ dh[di]->minx = 0; dh[di]->miny = 0; dh[di]->maxx = dh[di]->dpfh->width - 1; dh[di]->maxy = dh[di]->dpfh->height - 1; } + else if (dh[di]->justCleared) { + dh[di]->justCleared = false; + + int height = dh[di]->dpfh->height; + int width = dh[di]->dpfh->width; + int y_min = height; + + uint16_t *b0 = (uint16_t *) dh[di]->LCD; + uint16_t *b1 = (uint16_t *) dh[di]->PRE; + for (int y = 0; y < height && y_min == height; y++) + for (int x = 0; x < width; x++, b0++, b1++) + if (b0 != b1) { + y_min = y; + break; + } + + int y_max = y_min; + b1 = (uint16_t *) dh[di]->LCD + height * width - 1; + b0 = (uint16_t *) dh[di]->PRE + height * width - 1; + for (int y = height - 1; y_min < y && y_max == y_min; y--) + for (int x = 0; x < width; x++, b0--, b1--) + if (b0 != b1) { + y_max = y; + break; + } + + int x_min = width; + for (int x = 0; x < width && x_min == width; x++) { + b0 = (uint16_t *) dh[di]->LCD + x + y_min * width; + b1 = (uint16_t *) dh[di]->PRE + x + y_min * width; + for (int y = y_min; y < y_max; y++, b0 += width, b1 += width) + if (*b0 != *b1) { + x_min = x; + break; + } + } + + int x_max = x_min; + for (int x = width - 1; x_min < x && x_max == x_min; x--) { + b0 = (uint16_t *) dh[di]->LCD + x + y_min * width; + b1 = (uint16_t *) dh[di]->PRE + x + y_min * width; + for (int y = y_min; y < y_max; y++, b0 += width, b1 += width) + if (*b0 != *b1) { + x_max = x; + break; + } + } + + dh[di]->minx = x_min; + dh[di]->maxx = x_max; + dh[di]->miny = y_min; + dh[di]->maxy = y_max; + } + //fprintf(stderr, "%d: (%d,%d)-(%d,%d) ", di, dh[di]->minx, dh[di]->miny, dh[di]->maxx, dh[di]->maxy); if (dh[di]->minx > dh[di]->maxx || dh[di]->miny > dh[di]->maxy) continue; @@ -506,9 +585,12 @@ RescanUSB(); lastscan = time(NULL); } - } - + memcpy(dh[di]->PRE, dh[di]->LCD, dh[di]->dpfh->height * dh[di]->dpfh->width * dh[di]->dpfh->bpp); + } + +#if 0 ResetMinMax(); +#endif //fprintf(stderr, "\n"); } @@ -674,7 +756,7 @@ int error = 0; DPFContext *dpf; int i; - usb_dev_handle *u; + libusb_device_handle *u; //int fd; @@ -722,8 +804,8 @@ // close(h->dev.fd); // break; // case MODE_USB: - usb_release_interface(h->dev.udev, 0); - usb_close(h->dev.udev); + libusb_release_interface(h->dev.udev, 0); + libusb_close(h->dev.udev); // break; //} free(h); @@ -841,19 +923,24 @@ return -1; } -void usb_flush(usb_dev_handle *dev) -{ - char buf[20]; - usb_bulk_read(dev, ENDPT_IN, buf, 3, 1000); -} - -int check_known_device(struct usb_device *d) +void usb_flush(libusb_device_handle *dev) +{ + unsigned char buf[20]; + int transferred; + libusb_bulk_transfer(dev, ENDPT_IN, buf, 3, &transferred, 1000); +} + +int check_known_device(struct libusb_device *d) { struct known_device *dev = g_known_devices; + libusb_device_descriptor desc; + int r = libusb_get_device_descriptor(d, &desc); + if (r < 0) + return 0; while (dev->desc) { - if ((d->descriptor.idVendor == dev->vid) && - (d->descriptor.idProduct == dev->pid)) { + if ((desc.idVendor == dev->vid) && + (desc.idProduct == dev->pid)) { //fprintf(stderr, "Found %s at %s:%s\n", dev->desc, d->bus->dirname, d->filename); return 1; } @@ -862,32 +949,35 @@ return 0; } -static struct usb_device *find_dev(int index) -{ - struct usb_bus *b; - struct usb_device *d; +static struct libusb_device *find_dev(int index) +{ + struct libusb_device **list; + struct libusb_device *found = NULL; int enumeration = 0; - b = usb_get_busses(); - - while (b) { - d = b->devices; - while (d) { - if (check_known_device(d)) { - if (enumeration == index) return d; - else enumeration++; + ssize_t cnt = libusb_get_device_list(NULL, &list); + + for (int i = 0; i < cnt; i++) { + struct libusb_device *d = list[i]; + if (check_known_device(d)) { + if (enumeration == index) { + found = d; + break; } + else enumeration++; + } #ifdef HAVE_DEBUG - printf("%04x %04x\n", - d->descriptor.idVendor, - d->descriptor.idProduct); -#endif - d = d->next; - } - b = b->next; - } - return NULL; + printf("%04x %04x\n", + d->descriptor.idVendor, + d->descriptor.idProduct); +#endif + } + + if (cnt > 0) + libusb_free_device_list(list, 0); + + return found; } unsigned char g_buf[] = { @@ -905,12 +995,13 @@ 0x00, 0x00, 0x00, 0x00, }; -int emulate_scsi(usb_dev_handle *dev, unsigned char *cmd, int cmdlen, char out, +int emulate_scsi(libusb_device_handle *dev, unsigned char *cmd, int cmdlen, char out, unsigned char *data, unsigned long block_len) { int len; int ret; static unsigned char ansbuf[13]; // Do not change size. + int transferred, received; g_buf[14] = cmdlen; memcpy(&g_buf[15], cmd, cmdlen); @@ -920,21 +1011,21 @@ g_buf[10] = block_len >> 16; g_buf[11] = block_len >> 24; - ret = usb_bulk_write(dev, ENDPT_OUT, (char*)g_buf, sizeof(g_buf), 1000); + ret = libusb_bulk_transfer(dev, ENDPT_OUT, g_buf, sizeof(g_buf), &transferred, 1000); if (ret < 0) return ret; if (out == DIR_OUT) { if (data) { - ret = usb_bulk_write(dev, ENDPT_OUT, (char* )data, - block_len, 3000); - if (ret != (int) block_len) { + ret = libusb_bulk_transfer(dev, ENDPT_OUT, data, + block_len, &transferred, 3000); + if (transferred != (int) block_len) { perror("bulk write"); return ret; } } } else if (data) { - ret = usb_bulk_read(dev, ENDPT_IN, (char *) data, block_len, 4000); - if (ret != (int) block_len) { + ret = libusb_bulk_transfer(dev, ENDPT_IN, data, block_len, &received, 4000); + if (received != (int) block_len) { perror("bulk data read"); } } @@ -942,8 +1033,8 @@ len = sizeof(ansbuf); int retry = 0; do { - ret = usb_bulk_read(dev, ENDPT_IN, (char *) ansbuf, len, 5000); - if (ret != len) { + ret = libusb_bulk_transfer(dev, ENDPT_IN, ansbuf, len, &received, 5000); + if (received != len) { perror("bulk ACK read"); ret = DEVERR_TIMEOUT; } @@ -956,14 +1047,22 @@ return ansbuf[12]; } -usb_dev_handle *dpf_usb_open(int index) -{ - struct usb_device *d; - usb_dev_handle *usb_dev; - - usb_init(); - usb_find_busses(); - usb_find_devices(); +libusb_device_handle *dpf_usb_open(int index) +{ + int r; + struct libusb_device *d; + struct libusb_device_handle *usb_dev; + + r = libusb_init(NULL); + if (r < 0) { + handle_error("Could not initialise libusb!"); + return NULL; + } +#if LIBUSB_API_VERSION >= 0x01000106 + libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, 3); +#else + libusb_set_debug(NULL, 3); +#endif d = find_dev(index); if (!d) { @@ -971,12 +1070,12 @@ return NULL; } - usb_dev = usb_open(d); + libusb_open(d, &usb_dev); if (usb_dev == NULL) { handle_error("Failed to open usb device!"); return NULL; } - usb_claim_interface(usb_dev, 0); + libusb_claim_interface(usb_dev, 0); return usb_dev; } --- a/glcddrivers/ax206dpf.h +++ b/glcddrivers/ax206dpf.h @@ -53,10 +53,12 @@ bool isPortrait; bool rotate90; bool flip; + bool justCleared; int minx, maxx; int miny, maxy; LIBDPF::DPFContext *dpfh; unsigned char * LCD; + unsigned char * PRE; } DISPLAYHANDLE; @@ -131,7 +133,7 @@ // START SELECTIVE COPY & PASTE "usbuser.h" // ------------------------------------------------------------------- -#include +#include namespace LIBDPF { @@ -193,7 +195,7 @@ unsigned char mode; unsigned char flags; union { - usb_dev_handle *udev; + libusb_device_handle *udev; int fd; } dev; unsigned int width; @@ -251,13 +253,13 @@ /* USB raw */ -int emulate_scsi(usb_dev_handle *d, unsigned char *cmd, int cmdlen, char out, +int emulate_scsi(libusb_device_handle *d, unsigned char *cmd, int cmdlen, char out, unsigned char *data, unsigned long block_len); const char *dev_errstr(int err); // Private stuff: -usb_dev_handle *dpf_usb_open(int index); +libusb_device_handle *dpf_usb_open(int index); int sgdev_open(const char *portname, int *fd); #ifdef __cplusplus --- a/glcddrivers/Makefile +++ b/glcddrivers/Makefile @@ -26,18 +26,18 @@ endif -ifeq ($(shell pkg-config --exists libusb && echo 1), 1) +ifeq ($(shell pkg-config --exists libusb-1.0 && echo 1), 1) DEFINES += -DHAVE_LIBUSB ifdef HAVE_DRIVER_AX206DPF OBJS += ax206dpf.o - INCLUDES += $(shell pkg-config --cflags libusb) - LIBS += $(shell pkg-config --libs libusb) + INCLUDES += $(shell pkg-config --cflags libusb-1.0) + LIBS += $(shell pkg-config --libs libusb-1.0) DEFINES += -DHAVE_DRIVER_AX206DPF endif ifdef HAVE_DRIVER_picoLCD_256x64 OBJS += picoLCD_256x64.o - INCLUDES += $(shell pkg-config --cflags libusb) - LIBS += $(shell pkg-config --libs libusb) + INCLUDES += $(shell pkg-config --cflags libusb-1.0) + LIBS += $(shell pkg-config --libs libusb-1.0) DEFINES += -DHAVE_DRIVER_picoLCD_256x64 endif endif --- a/glcddrivers/port.c +++ b/glcddrivers/port.c @@ -22,6 +22,26 @@ #include +#if !defined(i386) && !defined(__x86_64__) +/* konfetti: those are currently only dummy. not tested, not really + * thinking on it. it needs revise for the params etc. also we need + * to revise the assembler code below. but for now its ok because + * I (we) only want the peal lcd to be running ;) + */ + +#define __NR_ioperm 101 +#define __NR_iopl 110 + +static inline int ioperm(int port, unsigned long int from, unsigned long int num) +{ + return syscall(__NR_ioperm, port, from, num); +} + +static inline int iopl(int level) +{ + return syscall(__NR_iopl, level); +} +#endif #include "port.h" --- a/glcdgraphics/Makefile +++ b/glcdgraphics/Makefile @@ -44,6 +44,8 @@ DEFINES += -DHAVE_FREETYPE2 INCLUDES += $(shell pkg-config freetype2 --cflags) LIBS += $(shell pkg-config freetype2 --libs) + INCLUDES += -I$(DESTDIR)/include/ + LIBS += -L$(DESTDIR)/lib -liconv endif # two ifdef/endif are used because older installations may not support 'else ifdef' --- a/Make.config +++ b/Make.config @@ -59,7 +59,7 @@ HAVE_FREETYPE2=1 # comment this variable out if you don't want to use fontconfig font names -HAVE_FONTCONFIG=1 +#HAVE_FONTCONFIG=1 # comment this variable out if you want binaries to be stripped when installing (for production-level binaries or packages) #HAVE_STRIP = -s @@ -69,13 +69,13 @@ #HAVE_GRAPHICSMAGICK=1 # comment this variable or set to 0 if you do not want to build the vncserver driver, even if requirements (libvncserver) are fullfilled on the system -HAVE_DRIVER_VNCSERVER=1 +#HAVE_DRIVER_VNCSERVER=1 ### Experimental drivers # uncomment this variable if you want to enable the experimental AX 206 based digital photo frame driver # Read DRIVER.ax206dpf before use! -#HAVE_DRIVER_AX206DPF=1 +HAVE_DRIVER_AX206DPF=1 # uncomment this variable if you want to enable the experimental support for picoLCD 256x64 #HAVE_DRIVER_picoLCD_256x64=1