From ccc06bca4b712fc2f3c5711fb0dae301ebafda7b Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Tue, 14 Oct 2025 13:09:15 +0000 Subject: [PATCH] now works with 16bpp display git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@323 b9cfdab3-6d41-4d17-bbe4-086880011989 --- src/backend/x11.c | 104 +++++++++++++++++++++++++++++++--------------- src/backend/x11.h | 23 +++++----- 2 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/backend/x11.c b/src/backend/x11.c index 55a3e3a..1df8425 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -38,6 +38,36 @@ static void destroy_pixmap(MwLL handle) { XFreePixmap(handle->display, handle->pixmap); } +static unsigned long generate_color(XVisualInfo* xvi, unsigned long r, unsigned long g, unsigned long b) { + int i; + unsigned long n = 1; + unsigned long c = 0; + + i = 0; + while(!((n << i) & xvi->red_mask)) i++; + c |= (r * (xvi->red_mask >> i) / 255) << i; + + i = 0; + while(!((n << i) & xvi->green_mask)) i++; + c |= (g * (xvi->green_mask >> i) / 255) << i; + + i = 0; + while(!((n << i) & xvi->blue_mask)) i++; + c |= (b * (xvi->blue_mask >> i) / 255) << i; + + return c; +} + +static XVisualInfo* get_visual_info(Display* display) { + XVisualInfo xvi; + int n; + Visual* visual = DefaultVisual(display, DefaultScreen(display)); + + xvi.visualid = XVisualIDFromVisual(visual); + + return XGetVisualInfo(display, VisualIDMask, &xvi, &n); +} + MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { MwLL r; Window p; @@ -60,6 +90,8 @@ MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) { } r->window = XCreateSimpleWindow(r->display, p, x, y, width, height, 0, 0, WhitePixel(r->display, XDefaultScreen(r->display))); + r->visual = get_visual_info(r->display); + XSetLocaleModifiers(""); if((r->xim = XOpenIM(r->display, 0, 0, 0)) == NULL) { XSetLocaleModifiers("@im=none"); @@ -101,6 +133,7 @@ void MwLLDestroy(MwLL handle) { XCloseIM(handle->xim); destroy_pixmap(handle); + XFree(handle->visual); XFreeGC(handle->display, handle->gc); XUnmapWindow(handle->display, handle->window); XDestroyWindow(handle->display, handle->window); @@ -133,19 +166,23 @@ MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) { MwLLColor c = malloc(sizeof(*c)); XColor xc; - if(r > 255) r = 255; - if(g > 255) g = 255; - if(b > 255) b = 255; - if(r < 0) r = 0; - if(g < 0) g = 0; - if(b < 0) b = 0; + if(handle->visual->red_mask == 0) { + if(r > 255) r = 255; + if(g > 255) g = 255; + if(b > 255) b = 255; + if(r < 0) r = 0; + if(g < 0) g = 0; + if(b < 0) b = 0; - xc.red = 256 * r; - xc.green = 256 * g; - xc.blue = 256 * b; - XAllocColor(handle->display, handle->colormap, &xc); + xc.red = 256 * r; + xc.green = 256 * g; + xc.blue = 256 * b; + XAllocColor(handle->display, handle->colormap, &xc); - c->pixel = xc.pixel; + c->pixel = xc.pixel; + } else { + c->pixel = generate_color(handle->visual, r, g, b); + } c->red = r; c->green = g; c->blue = b; @@ -315,24 +352,29 @@ void MwLLSetTitle(MwLL handle, const char* title) { } MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int height) { - MwLLPixmap r = malloc(sizeof(*r)); - char* d = malloc(4 * width * height); - int y, x; - int evbase, erbase; + MwLLPixmap r = malloc(sizeof(*r)); + char* d = malloc(4 * width * height); + int y, x; + int evbase, erbase; + XWindowAttributes attr; + XGetWindowAttributes(handle->display, handle->window, &attr); + + r->depth = attr.depth; r->width = width; r->height = height; r->display = handle->display; r->use_shm = XShmQueryExtension(handle->display) ? 1 : 0; r->data = malloc(sizeof(unsigned long) * width * height); - r->use_render = XRenderQueryExtension(handle->display, &evbase, &erbase) ? 1 : 0; + r->use_render = 0; + XRenderQueryExtension(handle->display, &evbase, &erbase) ? 1 : 0; /* FIXME */ r->use_shm = 0; if(r->use_shm) { - r->image = XShmCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, ZPixmap, NULL, &r->shm, width, height); + r->image = XShmCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), r->depth, ZPixmap, NULL, &r->shm, width, height); r->shm.shmid = shmget(IPC_PRIVATE, r->image->bytes_per_line * height, IPC_CREAT | 0777); if(r->shm.shmid == -1) { @@ -346,21 +388,17 @@ MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int hei } } if(!r->use_shm) { - r->image = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, ZPixmap, 0, d, width, height, 32, width * 4); + r->image = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), r->depth, ZPixmap, 0, d, width, height, 32, width * 4); } for(y = 0; y < height; y++) { for(x = 0; x < width; x++) { unsigned char* px = &data[(y * width + x) * 4]; - unsigned long p = 0; - p <<= 8; - p |= px[3]; - p <<= 8; - p |= px[0]; - p <<= 8; - p |= px[1]; - p <<= 8; - p |= px[2]; + MwLLColor c = MwLLAllocColor(handle, px[0], px[1], px[2]); + unsigned long p = c->pixel; + + MwLLFreeColor(c); + XPutPixel(r->image, x, y, p); *(unsigned long*)(&r->data[(y * width + x) * sizeof(unsigned long)]) = p; } @@ -387,7 +425,7 @@ void MwLLDestroyPixmap(MwLLPixmap pixmap) { void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { if(pixmap->image != NULL && pixmap->use_render) { - Pixmap px = XCreatePixmap(handle->display, handle->window, pixmap->width, pixmap->height, 24); + Pixmap px = XCreatePixmap(handle->display, handle->window, pixmap->width, pixmap->height, pixmap->depth); XRenderPictFormat* format = XRenderFindStandardFormat(handle->display, PictStandardRGB24); XRenderPictureAttributes attr; Picture src, dest; @@ -444,14 +482,14 @@ void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { sy = (int)sy; sx = (int)sx; - ipx = &pixmap->image->data[(int)(pixmap->width * sy + sx) * 4]; - opx = &d[(rect->width * y + x) * 4]; - memcpy(opx, ipx, 4); + ipx = &pixmap->image->data[(int)(pixmap->width * sy + sx) * (pixmap->image->bitmap_unit / 8)]; + opx = &d[(rect->width * y + x) * (pixmap->image->bitmap_unit / 8)]; + memcpy(opx, ipx, pixmap->image->bitmap_unit / 8); } } if(use_shm) { - dest = XShmCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, ZPixmap, NULL, &shm, rect->width, rect->height); + dest = XShmCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), pixmap->depth, ZPixmap, NULL, &shm, rect->width, rect->height); shm.shmid = shmget(IPC_PRIVATE, dest->bytes_per_line * rect->height, IPC_CREAT | 0777); if(shm.shmid == -1) { XDestroyImage(dest); @@ -464,7 +502,7 @@ void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { } } if(!use_shm) { - dest = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, ZPixmap, 0, d, rect->width, rect->height, 32, rect->width * 4); + dest = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), pixmap->depth, ZPixmap, 0, d, rect->width, rect->height, 32, rect->width * 4); } if(use_shm) { diff --git a/src/backend/x11.h b/src/backend/x11.h index 79d2c74..2958d8f 100644 --- a/src/backend/x11.h +++ b/src/backend/x11.h @@ -14,16 +14,17 @@ #include struct _MwLL { - Display* display; - Window window; - Pixmap pixmap; - GC gc; - Colormap colormap; - void* user; - Atom wm_delete; - int copy_buffer; - XIM xim; - XIC xic; + Display* display; + Window window; + Pixmap pixmap; + GC gc; + Colormap colormap; + void* user; + Atom wm_delete; + int copy_buffer; + XIM xim; + XIC xic; + XVisualInfo* visual; unsigned int width; unsigned int height; @@ -43,6 +44,8 @@ struct _MwLLPixmap { int height; unsigned char* data; + int depth; + int use_shm; int use_render; XShmSegmentInfo shm;