From 521d74c6f371ed974ec80908e564b8e7a3a87f90 Mon Sep 17 00:00:00 2001 From: Nathaniel van Diepen Date: Mon, 9 Sep 2024 22:11:37 -0600 Subject: [PATCH] Cleanup blight_client --- shared/libblight_client/main.cpp | 928 +++++++++++++++---------------- 1 file changed, 450 insertions(+), 478 deletions(-) diff --git a/shared/libblight_client/main.cpp b/shared/libblight_client/main.cpp index d08a67ca..e7031502 100644 --- a/shared/libblight_client/main.cpp +++ b/shared/libblight_client/main.cpp @@ -27,521 +27,493 @@ #include #include -static bool IS_INITIALIZED = false; -static bool FAILED_INIT = true; -static bool DO_HANDLE_FB = true; -static bool FAKE_RM1 = false; -static unsigned int INPUT_BATCH_SIZE = 16; -static Blight::shared_buf_t blightBuffer = Blight::buf_t::new_ptr(); -static Blight::Connection* blightConnection = nullptr; -static std::map inputFds; -static std::map inputDeviceMap; -static ssize_t(*func_write)(int, const void*, size_t); -static ssize_t(*func_writev)(int, const iovec*, int); -static ssize_t(*func_writev64)(int, const iovec*, int); -static ssize_t(*func_pwrite)(int, const void*, size_t, int); -static ssize_t(*func_pwrite64)(int, const void*, size_t, int); -static ssize_t(*func_pwritev)(int, const iovec*, int, int); -static ssize_t(*func_pwritev64)(int, const iovec*, int, int); -static int(*func_open)(const char*, int, ...); -static int(*func_ioctl)(int, unsigned long, ...); -static int(*func_close)(int); -static int(*func_msgget)(key_t, int); -static void*(*func_mmap)(void*, size_t, int, int, int, __off_t); -static int msgq = -1; +namespace { + static bool IS_INITIALIZED = false; + static bool FAILED_INIT = true; + static bool DO_HANDLE_FB = true; + static bool FAKE_RM1 = false; + static unsigned int INPUT_BATCH_SIZE = 16; + static Blight::shared_buf_t blightBuffer = Blight::buf_t::new_ptr(); + static Blight::Connection* blightConnection = nullptr; + static std::map inputFds; + static std::map inputDeviceMap; + static ssize_t(*func_write)(int, const void*, size_t); + static ssize_t(*func_writev)(int, const iovec*, int); + static ssize_t(*func_writev64)(int, const iovec*, int); + static ssize_t(*func_pwrite)(int, const void*, size_t, int); + static ssize_t(*func_pwrite64)(int, const void*, size_t, int); + static ssize_t(*func_pwritev)(int, const iovec*, int, int); + static ssize_t(*func_pwritev64)(int, const iovec*, int, int); + static int(*func_open)(const char*, int, ...); + static int(*func_ioctl)(int, unsigned long, ...); + static int(*func_close)(int); + static int(*func_msgget)(key_t, int); + static void*(*func_mmap)(void*, size_t, int, int, int, __off_t); + static int msgq = -1; -bool __is_fb(int fd){ return DO_HANDLE_FB && blightBuffer->fd > 0 && blightBuffer->fd == fd; } + bool __is_fb(int fd){ return DO_HANDLE_FB && blightBuffer->fd > 0 && blightBuffer->fd == fd; } -void __writeInputEvent(int fd, input_event* ie){ - if(!Blight::send_blocking( - fd, - reinterpret_cast(ie), - sizeof(input_event) - )){ - _WARN("Failed to write input event", strerror(errno)); - } -} - -void __writeInputEvent( - int fd, - timeval time, - short unsigned int type, - short unsigned int code, - int value -){ - input_event ie{ - .time = time, - .type = type, - .code = code, - .value = value - }; - __writeInputEvent(fd, &ie); -} - -int __open_input_socketpair(int flags, int fds[2]){ - int socketFlags = SOCK_STREAM; - if(flags & O_NONBLOCK || flags & O_NDELAY){ - socketFlags |= SOCK_NONBLOCK; - } - return ::socketpair(AF_UNIX, socketFlags, 0, fds); -} - - -void __sendEvents(unsigned int device, std::vector& queue){ - if(queue.empty()){ - return; - } - timeval time; - ::gettimeofday(&time, NULL); - std::vector data(queue.size()); - for(unsigned int i = 0; i < queue.size(); i++){ - auto& event = queue[i]; - data[i] = input_event{ - .time = time, - .type = event.type, - .code = event.code, - .value = event.value - }; - } - auto fd = inputFds[device][0]; -// if(!Blight::send_blocking( -// fd, -// reinterpret_cast(data.data()), -// sizeof(input_event) * data.size() -// )){ -// _CRIT("%d input events failed to send: %s", data.size(), std::strerror(errno)); -// }else{ -// _DEBUG("Sent %d input events", data.size()); -// } - auto res = func_write(fd, data.data(), sizeof(input_event) * data.size()); - if(res < 0){ - _CRIT("%d input events failed to send: %s", data.size(), std::strerror(errno)); - }else{ - _DEBUG("Sent %d input events", data.size()); + int __open_input_socketpair(int flags, int fds[2]){ + int socketFlags = SOCK_STREAM; + if(flags & O_NONBLOCK || flags & O_NDELAY){ + socketFlags |= SOCK_NONBLOCK; + } + return ::socketpair(AF_UNIX, socketFlags, 0, fds); } - queue.clear(); -} - -void __readInput(){ - _INFO("%s", "InputWorker starting"); - prctl(PR_SET_NAME, "InputWorker\0", 0, 0, 0); - nice(-10); - auto fd = blightConnection->input_handle(); - std::map> events; - while(blightConnection != nullptr && getenv("OXIDE_PRELOAD_DISABLE_INPUT") == nullptr){ - auto maybe = blightConnection->read_event(); - if(!maybe.has_value()){ - if(errno != EAGAIN && errno != EINTR){ - _WARN("[InputWorker] Failed to read message %s", std::strerror(errno)); - break; - } - for(auto& item : events){ - __sendEvents(item.first, item.second); - } - _DEBUG("Waiting for next input event"); - if(!Blight::wait_for_read(fd) && errno != EAGAIN){ - _WARN("[InputWorker] Failed to wait for next input event %s", std::strerror(errno)); - break; - } - continue; - } - const auto& device = maybe.value().device; - if(!inputFds.contains(device)){ - _INFO("Ignoring event for unopened device: %d", device); - continue; + void __sendEvents(unsigned int device, std::vector& queue){ + if(queue.empty()){ + return; } - if(inputFds[device][0] < 0){ - _INFO("Ignoring event for invalid device: %d", device); - continue; + timeval time; + ::gettimeofday(&time, NULL); + std::vector data(queue.size()); + for(unsigned int i = 0; i < queue.size(); i++){ + auto& event = queue[i]; + data[i] = input_event{ + .time = time, + .type = event.type, + .code = event.code, + .value = event.value + }; } - auto& event = maybe.value().event; - auto& queue = events[device]; - queue.push_back(event); - if( - ( - INPUT_BATCH_SIZE - && queue.size() >= INPUT_BATCH_SIZE - ) - || ( - !INPUT_BATCH_SIZE - && event.type == EV_SYN - && event.code == SYN_REPORT - ) - ){ - __sendEvents(device, queue); + auto fd = inputFds[device][0]; + // if(!Blight::send_blocking( + // fd, + // reinterpret_cast(data.data()), + // sizeof(input_event) * data.size() + // )){ + // _CRIT("%d input events failed to send: %s", data.size(), std::strerror(errno)); + // }else{ + // _DEBUG("Sent %d input events", data.size()); + // } + auto res = func_write(fd, data.data(), sizeof(input_event) * data.size()); + if(res < 0){ + _CRIT("%d input events failed to send: %s", data.size(), std::strerror(errno)); + }else{ + _DEBUG("Sent %d input events", data.size()); } + queue.clear(); } - _INFO("%s", "InputWorker quitting"); -} - -int __fb_ioctl(unsigned long request, char* ptr){ - switch(request){ - // Look at linux/fb.h and mxcfb.h for more possible request types - // https://www.kernel.org/doc/html/latest/fb/api.html - case MXCFB_SEND_UPDATE:{ - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SEND_UPDATE") - Blight::ClockWatch cw; - if(!blightBuffer->surface){ - Blight::addSurface(blightBuffer); + void __readInput(){ + _INFO("%s", "InputWorker starting"); + prctl(PR_SET_NAME, "InputWorker\0", 0, 0, 0); + nice(-10); + auto fd = blightConnection->input_handle(); + std::map> events; + while(blightConnection != nullptr && getenv("OXIDE_PRELOAD_DISABLE_INPUT") == nullptr){ + auto maybe = blightConnection->read_event(); + if(!maybe.has_value()){ + if(errno != EAGAIN && errno != EINTR){ + _WARN("[InputWorker] Failed to read message %s", std::strerror(errno)); + break; + } + for(auto& item : events){ + __sendEvents(item.first, item.second); + } + _DEBUG("Waiting for next input event"); + if(!Blight::wait_for_read(fd) && errno != EAGAIN){ + _WARN("[InputWorker] Failed to wait for next input event %s", std::strerror(errno)); + break; + } + continue; } - if(!blightBuffer->surface){ - _CRIT("Failed to create surface: %s", std::strerror(errno)); - std::exit(errno); + const auto& device = maybe.value().device; + if(!inputFds.contains(device)){ + _INFO("Ignoring event for unopened device: %d", device); + continue; } - auto update = reinterpret_cast(ptr); - auto region = update->update_region; - auto maybe = blightConnection->repaint( - blightBuffer, - region.left, - region.top, - region.width, - region.height, - (Blight::WaveformMode)update->waveform_mode, - update->update_marker - ); - if(maybe.has_value()){ - maybe.value()->wait(); + if(inputFds[device][0] < 0){ + _INFO("Ignoring event for invalid device: %d", device); + continue; + } + auto& event = maybe.value().event; + auto& queue = events[device]; + queue.push_back(event); + if( + ( + INPUT_BATCH_SIZE + && queue.size() >= INPUT_BATCH_SIZE + ) + || ( + !INPUT_BATCH_SIZE + && event.type == EV_SYN + && event.code == SYN_REPORT + ) + ){ + __sendEvents(device, queue); } - _DEBUG("ioctl /dev/fb0 MXCFB_SEND_UPDATE done: %f", cw.elapsed()) - // TODO - notify on rM2 for screensharing - return 0; - } - case MXCFB_WAIT_FOR_UPDATE_COMPLETE:{ - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE"); - Blight::ClockWatch cw; - auto update = reinterpret_cast(ptr); - blightConnection->waitForMarker(update->update_marker); - _DEBUG("ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE done: %f", cw.elapsed()); - return 0; } - case FBIOGET_VSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_VSCREENINFO"); - auto screenInfo = reinterpret_cast(ptr); - int fd = func_open("/dev/fb0", O_RDONLY, 0); - if(fd == -1){ - return -1; + _INFO("%s", "InputWorker quitting"); + } + + int __fb_ioctl(unsigned long request, char* ptr){ + switch(request){ + // Look at linux/fb.h and mxcfb.h for more possible request types + // https://www.kernel.org/doc/html/latest/fb/api.html + case MXCFB_SEND_UPDATE:{ + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SEND_UPDATE") + Blight::ClockWatch cw; + if(!blightBuffer->surface){ + Blight::addSurface(blightBuffer); + } + if(!blightBuffer->surface){ + _CRIT("Failed to create surface: %s", std::strerror(errno)); + std::exit(errno); + } + auto update = reinterpret_cast(ptr); + auto region = update->update_region; + auto maybe = blightConnection->repaint( + blightBuffer, + region.left, + region.top, + region.width, + region.height, + (Blight::WaveformMode)update->waveform_mode, + update->update_marker + ); + if(maybe.has_value()){ + maybe.value()->wait(); + } + _DEBUG("ioctl /dev/fb0 MXCFB_SEND_UPDATE done: %f", cw.elapsed()) + // TODO - notify on rM2 for screensharing + return 0; } - if(func_ioctl(fd, request, ptr) == -1){ - return -1; + case MXCFB_WAIT_FOR_UPDATE_COMPLETE:{ + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE"); + Blight::ClockWatch cw; + auto update = reinterpret_cast(ptr); + blightConnection->waitForMarker(update->update_marker); + _DEBUG("ioctl /dev/fb0 MXCFB_WAIT_FOR_UPDATE_COMPLETE done: %f", cw.elapsed()); + return 0; } - screenInfo->xres = blightBuffer->width; - screenInfo->yres = blightBuffer->height; - screenInfo->xoffset = 0; - screenInfo->yoffset = 0; - screenInfo->xres_virtual = blightBuffer->width; - screenInfo->yres_virtual = blightBuffer->height; - screenInfo->bits_per_pixel = blightBuffer->stride / blightBuffer->width * 8; - // TODO - determine the following from the buffer format - // Format_RGB16 / RGB565 - screenInfo->grayscale = 0; - screenInfo->red.offset = 11; - screenInfo->red.length = 5; - screenInfo->red.msb_right = 0; - screenInfo->green.offset = 5; - screenInfo->green.length = 6; - screenInfo->green.msb_right = 0; - screenInfo->blue.offset = 0; - screenInfo->blue.length = 5; - screenInfo->blue.msb_right = 0; - // TODO what should this even be? - screenInfo->nonstd = 0; - screenInfo->activate = 0; - // It would be cool to have the actual mm width/height here - screenInfo->height = 0; - screenInfo->width = 0; - screenInfo->accel_flags = 0; - // screenInfo->pixclock = 28800; // Stick with what is reported - screenInfo->left_margin = 0; - screenInfo->right_margin = 0; - screenInfo->upper_margin = 0; - screenInfo->lower_margin = 0; - screenInfo->hsync_len = 0; - screenInfo->vsync_len = 2; - screenInfo->sync = 0; - screenInfo->vmode = 0; - screenInfo->rotate = 0; - screenInfo->colorspace = 0; - screenInfo->reserved[0] = 0; - screenInfo->reserved[1] = 0; - screenInfo->reserved[2] = 0; - screenInfo->reserved[3] = 0; - return 0; - } - case FBIOGET_FSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_FSCREENINFO"); - auto screenInfo = reinterpret_cast(ptr); - int fd = func_open("/dev/fb0", O_RDONLY, 0); - if(fd == -1){ - return -1; + case FBIOGET_VSCREENINFO:{ + _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_VSCREENINFO"); + auto screenInfo = reinterpret_cast(ptr); + int fd = func_open("/dev/fb0", O_RDONLY, 0); + if(fd == -1){ + return -1; + } + if(func_ioctl(fd, request, ptr) == -1){ + return -1; + } + screenInfo->xres = blightBuffer->width; + screenInfo->yres = blightBuffer->height; + screenInfo->xoffset = 0; + screenInfo->yoffset = 0; + screenInfo->xres_virtual = blightBuffer->width; + screenInfo->yres_virtual = blightBuffer->height; + screenInfo->bits_per_pixel = blightBuffer->stride / blightBuffer->width * 8; + // TODO - determine the following from the buffer format + // Format_RGB16 / RGB565 + screenInfo->grayscale = 0; + screenInfo->red.offset = 11; + screenInfo->red.length = 5; + screenInfo->red.msb_right = 0; + screenInfo->green.offset = 5; + screenInfo->green.length = 6; + screenInfo->green.msb_right = 0; + screenInfo->blue.offset = 0; + screenInfo->blue.length = 5; + screenInfo->blue.msb_right = 0; + // TODO what should this even be? + screenInfo->nonstd = 0; + screenInfo->activate = 0; + // It would be cool to have the actual mm width/height here + screenInfo->height = 0; + screenInfo->width = 0; + screenInfo->accel_flags = 0; + // screenInfo->pixclock = 28800; // Stick with what is reported + screenInfo->left_margin = 0; + screenInfo->right_margin = 0; + screenInfo->upper_margin = 0; + screenInfo->lower_margin = 0; + screenInfo->hsync_len = 0; + screenInfo->vsync_len = 2; + screenInfo->sync = 0; + screenInfo->vmode = 0; + screenInfo->rotate = 0; + screenInfo->colorspace = 0; + screenInfo->reserved[0] = 0; + screenInfo->reserved[1] = 0; + screenInfo->reserved[2] = 0; + screenInfo->reserved[3] = 0; + return 0; } - if(func_ioctl(fd, request, ptr) == -1){ - return -1; + case FBIOGET_FSCREENINFO:{ + _DEBUG("%s", "ioctl /dev/fb0 FBIOGET_FSCREENINFO"); + auto screenInfo = reinterpret_cast(ptr); + int fd = func_open("/dev/fb0", O_RDONLY, 0); + if(fd == -1){ + return -1; + } + if(func_ioctl(fd, request, ptr) == -1){ + return -1; + } + // TODO determine all the values dynamically + screenInfo->smem_len = blightBuffer->size(); + screenInfo->smem_start = (unsigned long)blightBuffer->data; + screenInfo->type = 0; + screenInfo->type_aux = 0; + screenInfo->visual = 0; + screenInfo->xpanstep = 8; + screenInfo->ypanstep = 0; + screenInfo->ywrapstep = 5772; + screenInfo->line_length = blightBuffer->stride; + screenInfo->mmio_start = 0; + screenInfo->mmio_len = 0; + screenInfo->accel = 0; + screenInfo->reserved[0] = 0; + screenInfo->reserved[1] = 0; + return 0; } - // TODO determine all the values dynamically - screenInfo->smem_len = blightBuffer->size(); - screenInfo->smem_start = (unsigned long)blightBuffer->data; - screenInfo->type = 0; - screenInfo->type_aux = 0; - screenInfo->visual = 0; - screenInfo->xpanstep = 8; - screenInfo->ypanstep = 0; - screenInfo->ywrapstep = 5772; - screenInfo->line_length = blightBuffer->stride; - screenInfo->mmio_start = 0; - screenInfo->mmio_len = 0; - screenInfo->accel = 0; - screenInfo->reserved[0] = 0; - screenInfo->reserved[1] = 0; - return 0; - } - case FBIOPUT_VSCREENINFO:{ - _DEBUG("%s", "ioctl /dev/fb0 FBIOPUT_VSCREENINFO"); - // TODO - Explore allowing some screen info updating - auto screenInfo = reinterpret_cast(ptr); - _DEBUG( - "\n" - "res: %dx%d\n" - "res_virtual: %dx%d\n" - "offset: %d, %d\n" - "bits_per_pixel: %d\n" - "grayscale: %d\n" - "red: %d, %d, %d\n" - "green: %d, %d, %d\n" - "blue: %d, %d, %d\n" - "tansp: %d, %d, %d\n" - "nonstd: %d\n" - "activate: %d\n" - "size: %dx%dmm\n" - "accel_flags: %d\n" - "pixclock: %d\n" - "margins: %d %d %d %d\n" - "hsync_len: %d\n" - "vsync_len: %d\n" - "sync: %d\n" - "vmode: %d\n" - "rotate: %d\n" - "colorspace: %d\n" - "reserved: %d, %d, %d, %d\n", - screenInfo->xres, - screenInfo->yres, - screenInfo->xres_virtual, - screenInfo->yres_virtual, - screenInfo->xoffset, - screenInfo->yoffset, - screenInfo->bits_per_pixel, - screenInfo->grayscale, - screenInfo->red.offset, - screenInfo->red.length, - screenInfo->red.msb_right, - screenInfo->green.offset, - screenInfo->green.length, - screenInfo->green.msb_right, - screenInfo->blue.offset, - screenInfo->blue.length, - screenInfo->blue.msb_right, - screenInfo->transp.offset, - screenInfo->transp.length, - screenInfo->transp.msb_right, - screenInfo->nonstd, - screenInfo->activate, - screenInfo->height, - screenInfo->width, - screenInfo->accel_flags, - screenInfo->pixclock, - screenInfo->left_margin, - screenInfo->right_margin, - screenInfo->upper_margin, - screenInfo->lower_margin, - screenInfo->hsync_len, - screenInfo->vsync_len, - screenInfo->sync, - screenInfo->vmode, - screenInfo->rotate, - screenInfo->colorspace, - screenInfo->reserved[0], - screenInfo->reserved[1], - screenInfo->reserved[2], - screenInfo->reserved[3] - ); - // TODO allow resizing? - return 0; + case FBIOPUT_VSCREENINFO:{ + _DEBUG("%s", "ioctl /dev/fb0 FBIOPUT_VSCREENINFO"); + // TODO - Explore allowing some screen info updating + auto screenInfo = reinterpret_cast(ptr); + _DEBUG( + "\n" + "res: %dx%d\n" + "res_virtual: %dx%d\n" + "offset: %d, %d\n" + "bits_per_pixel: %d\n" + "grayscale: %d\n" + "red: %d, %d, %d\n" + "green: %d, %d, %d\n" + "blue: %d, %d, %d\n" + "tansp: %d, %d, %d\n" + "nonstd: %d\n" + "activate: %d\n" + "size: %dx%dmm\n" + "accel_flags: %d\n" + "pixclock: %d\n" + "margins: %d %d %d %d\n" + "hsync_len: %d\n" + "vsync_len: %d\n" + "sync: %d\n" + "vmode: %d\n" + "rotate: %d\n" + "colorspace: %d\n" + "reserved: %d, %d, %d, %d\n", + screenInfo->xres, + screenInfo->yres, + screenInfo->xres_virtual, + screenInfo->yres_virtual, + screenInfo->xoffset, + screenInfo->yoffset, + screenInfo->bits_per_pixel, + screenInfo->grayscale, + screenInfo->red.offset, + screenInfo->red.length, + screenInfo->red.msb_right, + screenInfo->green.offset, + screenInfo->green.length, + screenInfo->green.msb_right, + screenInfo->blue.offset, + screenInfo->blue.length, + screenInfo->blue.msb_right, + screenInfo->transp.offset, + screenInfo->transp.length, + screenInfo->transp.msb_right, + screenInfo->nonstd, + screenInfo->activate, + screenInfo->height, + screenInfo->width, + screenInfo->accel_flags, + screenInfo->pixclock, + screenInfo->left_margin, + screenInfo->right_margin, + screenInfo->upper_margin, + screenInfo->lower_margin, + screenInfo->hsync_len, + screenInfo->vsync_len, + screenInfo->sync, + screenInfo->vmode, + screenInfo->rotate, + screenInfo->colorspace, + screenInfo->reserved[0], + screenInfo->reserved[1], + screenInfo->reserved[2], + screenInfo->reserved[3] + ); + // TODO allow resizing? + return 0; + } + case MXCFB_SET_AUTO_UPDATE_MODE: + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SET_AUTO_UPDATE_MODE"); + return 0; + case MXCFB_SET_UPDATE_SCHEME: + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SET_UPDATE_SCHEME"); + return 0; + case MXCFB_ENABLE_EPDC_ACCESS: + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_ENABLE_EPDC_ACCESS"); + return 0; + case MXCFB_DISABLE_EPDC_ACCESS: + _DEBUG("%s", "ioctl /dev/fb0 MXCFB_DISABLE_EPDC_ACCESS"); + return 0; + default: + _WARN( + "UNHANDLED Fb IOCTL %lu %c %lu %lu %lu", + _IOC_DIR(request), + (char)_IOC_TYPE(request), + _IOC_NR(request), + _IOC_SIZE(request), + request + ); + return 0; } - case MXCFB_SET_AUTO_UPDATE_MODE: - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SET_AUTO_UPDATE_MODE"); - return 0; - case MXCFB_SET_UPDATE_SCHEME: - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_SET_UPDATE_SCHEME"); - return 0; - case MXCFB_ENABLE_EPDC_ACCESS: - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_ENABLE_EPDC_ACCESS"); - return 0; - case MXCFB_DISABLE_EPDC_ACCESS: - _DEBUG("%s", "ioctl /dev/fb0 MXCFB_DISABLE_EPDC_ACCESS"); - return 0; - default: - _WARN( - "UNHANDLED Fb IOCTL %lu %c %lu %lu %lu", - _IOC_DIR(request), - (char)_IOC_TYPE(request), - _IOC_NR(request), - _IOC_SIZE(request), - request - ); - return 0; } -} -int __input_ioctlv(int fd, unsigned long request, char* ptr){ - switch(request){ - case EVIOCGRAB: return 0; - case EVIOCREVOKE: return 0; - default: - return func_ioctl(fd, request, ptr); + int __input_ioctlv(int fd, unsigned long request, char* ptr){ + switch(request){ + case EVIOCGRAB: return 0; + case EVIOCREVOKE: return 0; + default: + return func_ioctl(fd, request, ptr); + } } -} - -void __realpath(const char* pathname, std::string& path){ - auto absolutepath = realpath(pathname, NULL); - path = absolutepath; - free(absolutepath); -} -int __open(const char* pathname, int flags){ - if(!IS_INITIALIZED){ - return -2; + void __realpath(const char* pathname, std::string& path){ + auto absolutepath = realpath(pathname, NULL); + path = absolutepath; + free(absolutepath); } - std::string actualpath(pathname); - if(std::filesystem::exists(actualpath)){ - __realpath(pathname, actualpath); - } - int res = -2; - if(FAKE_RM1 && actualpath == "/sys/devices/soc0/machine"){ - int fd = memfd_create("machine", MFD_ALLOW_SEALING); - std::string data("reMarkable 1.0"); - // Don't include trailing null - func_write(fd, data.data(), data.size()); - fcntl( - fd, - F_ADD_SEALS, - F_SEAL_SEAL - | F_SEAL_SHRINK - | F_SEAL_GROW - | F_SEAL_WRITE - | F_SEAL_FUTURE_WRITE - ); - lseek(fd, 0, SEEK_SET); - return fd; - }else if( - DO_HANDLE_FB - && ( - actualpath == "/dev/fb0" - || actualpath == "/dev/shm/swtfb.01" - ) - ){ - if(blightBuffer->format != Blight::Format::Format_Invalid){ - return blightBuffer->fd; + + int __open(const char* pathname, int flags){ + if(!IS_INITIALIZED){ + return -2; } - auto surfaceIds = blightConnection->surfaces(); - if(!surfaceIds.empty()){ - for(auto& identifier : surfaceIds){ - auto maybe = blightConnection->getBuffer(identifier); - if(!maybe.has_value()){ - continue; - } - auto buffer = maybe.value(); - if(buffer->data == nullptr){ - continue; - } - if( - buffer->x != 0 - || buffer->y != 0 - || buffer->width != 1404 - || buffer->height != 1872 - || buffer->stride != 2808 - || buffer->format != Blight::Format::Format_RGB16 - ){ - continue; - } - _INFO("Reusing existing surface: %s", identifier); - blightBuffer = buffer; - break; - } + std::string actualpath(pathname); + if(std::filesystem::exists(actualpath)){ + __realpath(pathname, actualpath); } - if(blightBuffer->format == Blight::Format::Format_Invalid){ - /// Emulate rM1 screen - auto maybe = Blight::createBuffer( - 0, - 0, - 1404, - 1872, - 2808, - Blight::Format::Format_RGB16 - ); - if(!maybe.has_value()){ - return -1; - } - blightBuffer = maybe.value(); - // We don't ever plan on resizing, and we shouldn't let anything try - int flags = fcntl(blightBuffer->fd, F_GET_SEALS); + int res = -2; + if(FAKE_RM1 && actualpath == "/sys/devices/soc0/machine"){ + int fd = memfd_create("machine", MFD_ALLOW_SEALING); + std::string data("reMarkable 1.0"); + // Don't include trailing null + func_write(fd, data.data(), data.size()); fcntl( - blightBuffer->fd, - F_ADD_SEALS, flags | F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW + fd, + F_ADD_SEALS, + F_SEAL_SEAL + | F_SEAL_SHRINK + | F_SEAL_GROW + | F_SEAL_WRITE + | F_SEAL_FUTURE_WRITE ); - res = blightBuffer->fd; - if(res < 0){ - _CRIT("Failed to create buffer: %s", std::strerror(errno)); - std::exit(errno); - } - // Initialize the buffer with white - memset((std::uint16_t*)blightBuffer->data, std::uint16_t(0xFFFFFFFF), 2808 * 1872); - _INFO("Created buffer %s on fd %d", blightBuffer->uuid.c_str(), blightBuffer->fd); - return res; - } - }else if(actualpath.starts_with("/dev/input/event")){ - _INFO("Opening event device: %s", actualpath.c_str()); - if(blightConnection->input_handle() > 0){ - if(inputFds.empty() && getenv("OXIDE_PRELOAD_DISABLE_INPUT") == nullptr){ - new std::thread(__readInput); + lseek(fd, 0, SEEK_SET); + return fd; + }else if( + DO_HANDLE_FB + && ( + actualpath == "/dev/fb0" + || actualpath == "/dev/shm/swtfb.01" + ) + ){ + if(blightBuffer->format != Blight::Format::Format_Invalid){ + return blightBuffer->fd; } - std::string path(basename(actualpath.c_str())); - try{ - unsigned int device = stol(path.substr(5)); - if(inputFds.contains(device)){ - res = inputFds[device][1]; - }else{ - int fds[2]; - // TODO - what if they open it a second time with different flags? - res = __open_input_socketpair(flags, fds); - if(res < 0){ - _WARN("Failed to open event socket stream %s", std::strerror(errno)); - }else{ - inputFds[device][0] = fds[0]; - res = inputFds[device][1] = fds[1]; - inputDeviceMap[res] = func_open(actualpath.c_str(), O_RDWR, 0); + auto surfaceIds = blightConnection->surfaces(); + if(!surfaceIds.empty()){ + for(auto& identifier : surfaceIds){ + auto maybe = blightConnection->getBuffer(identifier); + if(!maybe.has_value()){ + continue; + } + auto buffer = maybe.value(); + if(buffer->data == nullptr){ + continue; } + if( + buffer->x != 0 + || buffer->y != 0 + || buffer->width != 1404 + || buffer->height != 1872 + || buffer->stride != 2808 + || buffer->format != Blight::Format::Format_RGB16 + ){ + continue; + } + _INFO("Reusing existing surface: %s", identifier); + blightBuffer = buffer; + break; } } - catch(std::invalid_argument&){ - _WARN("Resolved event device name invalid: %s", path.c_str()); - res = -1; + if(blightBuffer->format == Blight::Format::Format_Invalid){ + /// Emulate rM1 screen + auto maybe = Blight::createBuffer( + 0, + 0, + 1404, + 1872, + 2808, + Blight::Format::Format_RGB16 + ); + if(!maybe.has_value()){ + return -1; + } + blightBuffer = maybe.value(); + // We don't ever plan on resizing, and we shouldn't let anything try + int flags = fcntl(blightBuffer->fd, F_GET_SEALS); + fcntl( + blightBuffer->fd, + F_ADD_SEALS, flags | F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW + ); + res = blightBuffer->fd; + if(res < 0){ + _CRIT("Failed to create buffer: %s", std::strerror(errno)); + std::exit(errno); + } + // Initialize the buffer with white + memset((std::uint16_t*)blightBuffer->data, std::uint16_t(0xFFFFFFFF), 2808 * 1872); + _INFO("Created buffer %s on fd %d", blightBuffer->uuid.c_str(), blightBuffer->fd); + return res; } - catch(std::out_of_range&){ - _WARN("Resolved event device number out of range: %s", path.c_str()); + }else if(actualpath.starts_with("/dev/input/event")){ + _INFO("Opening event device: %s", actualpath.c_str()); + if(blightConnection->input_handle() > 0){ + if(inputFds.empty() && getenv("OXIDE_PRELOAD_DISABLE_INPUT") == nullptr){ + new std::thread(__readInput); + } + std::string path(basename(actualpath.c_str())); + try{ + unsigned int device = stol(path.substr(5)); + if(inputFds.contains(device)){ + res = inputFds[device][1]; + }else{ + int fds[2]; + // TODO - what if they open it a second time with different flags? + res = __open_input_socketpair(flags, fds); + if(res < 0){ + _WARN("Failed to open event socket stream %s", std::strerror(errno)); + }else{ + inputFds[device][0] = fds[0]; + res = inputFds[device][1] = fds[1]; + inputDeviceMap[res] = func_open(actualpath.c_str(), O_RDWR, 0); + } + } + } + catch(std::invalid_argument&){ + _WARN("Resolved event device name invalid: %s", path.c_str()); + res = -1; + } + catch(std::out_of_range&){ + _WARN("Resolved event device number out of range: %s", path.c_str()); + res = -1; + } + }else{ + _WARN("Could not open connection input stream", ""); res = -1; } - }else{ - _WARN("Could not open connection input stream", ""); - res = -1; } + if(res == -1){ + errno = EIO; + } + return res; } - if(res == -1){ - errno = EIO; - } - return res; } - namespace swtfb { struct xochitl_data { int x1;