mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2026-01-17 06:34:08 +00:00
move
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@110 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
310
src/backend/gdi.c
Normal file
310
src/backend/gdi.c
Normal file
@@ -0,0 +1,310 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
typedef struct userdata {
|
||||
MwLL ll;
|
||||
WNDPROC old;
|
||||
} userdata_t;
|
||||
|
||||
static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
|
||||
userdata_t* u = (userdata_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
|
||||
if(u == NULL) return DefWindowProc(hWnd, msg, wp, lp);
|
||||
|
||||
if(msg == WM_PAINT) {
|
||||
PAINTSTRUCT ps;
|
||||
RECT rc;
|
||||
HBITMAP hbmp;
|
||||
HDC dc, hbdc;
|
||||
|
||||
if(u->ll->copy_buffer) {
|
||||
GetClientRect(hWnd, &rc);
|
||||
|
||||
dc = GetDC(hWnd);
|
||||
hbmp = CreateCompatibleBitmap(dc, rc.right - rc.left, rc.bottom - rc.top);
|
||||
hbdc = CreateCompatibleDC(dc);
|
||||
SelectObject(hbdc, hbmp);
|
||||
ReleaseDC(hWnd, dc);
|
||||
|
||||
u->ll->hDC = hbdc;
|
||||
MwLLDispatch(u->ll, draw, NULL);
|
||||
|
||||
dc = BeginPaint(hWnd, &ps);
|
||||
StretchBlt(dc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, hbdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SRCCOPY);
|
||||
EndPaint(hWnd, &ps);
|
||||
|
||||
DeleteDC(hbdc);
|
||||
DeleteObject(hbmp);
|
||||
} else {
|
||||
u->ll->hDC = BeginPaint(hWnd, &ps);
|
||||
MwLLDispatch(u->ll, draw, NULL);
|
||||
EndPaint(hWnd, &ps);
|
||||
}
|
||||
} else if(msg == WM_LBUTTONDOWN) {
|
||||
MwPoint p;
|
||||
p.x = LOWORD(lp);
|
||||
p.y = HIWORD(lp);
|
||||
|
||||
SetCapture(hWnd);
|
||||
MwLLDispatch(u->ll, down, &p);
|
||||
InvalidateRect(hWnd, NULL, FALSE);
|
||||
} else if(msg == WM_LBUTTONUP) {
|
||||
MwPoint p;
|
||||
p.x = LOWORD(lp);
|
||||
p.y = HIWORD(lp);
|
||||
|
||||
SetCapture(NULL);
|
||||
MwLLDispatch(u->ll, up, &p);
|
||||
InvalidateRect(hWnd, NULL, FALSE);
|
||||
} else if(msg == WM_SIZE) {
|
||||
MwLLDispatch(u->ll, resize, NULL);
|
||||
} else if(msg == WM_ERASEBKGND) {
|
||||
return 1;
|
||||
} else if(msg == WM_NCHITTEST) {
|
||||
return HTCLIENT;
|
||||
} else if(msg == WM_DESTROY) {
|
||||
MwLLDispatch(u->ll, close, NULL);
|
||||
PostQuitMessage(0);
|
||||
} else if(msg == WM_CLOSE) {
|
||||
DestroyWindow(hWnd);
|
||||
} else {
|
||||
return (u->old == NULL) ? DefWindowProc(hWnd, msg, wp, lp) : CallWindowProc(u->old, hWnd, msg, wp, lp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) {
|
||||
MwLL r = malloc(sizeof(*r));
|
||||
userdata_t* u = malloc(sizeof(*u));
|
||||
WNDCLASSEX wc;
|
||||
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = wndproc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
|
||||
wc.lpszClassName = "milsko";
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_MENU);
|
||||
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
||||
wc.hIconSm = NULL;
|
||||
|
||||
MwLLCreateCommon(r);
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
r->copy_buffer = 1;
|
||||
r->hWnd = CreateWindow(parent == NULL ? "milsko" : "STATIC", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE), x, y, width, height, parent == NULL ? NULL : parent->hWnd, 0, wc.hInstance, NULL);
|
||||
|
||||
u->ll = r;
|
||||
if(parent == NULL) {
|
||||
u->old = NULL;
|
||||
} else {
|
||||
u->old = (WNDPROC)SetWindowLongPtr(r->hWnd, GWLP_WNDPROC, (LONG_PTR)wndproc);
|
||||
}
|
||||
SetWindowLongPtr(r->hWnd, GWLP_USERDATA, (LONG_PTR)u);
|
||||
|
||||
if(parent == NULL) {
|
||||
RECT rc;
|
||||
|
||||
rc.left = 0;
|
||||
rc.top = 0;
|
||||
rc.right = width;
|
||||
rc.bottom = height;
|
||||
AdjustWindowRect(&rc, GetWindowLongPtr(r->hWnd, GWL_STYLE), FALSE);
|
||||
SetWindowPos(r->hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE);
|
||||
|
||||
ShowWindow(r->hWnd, SW_NORMAL);
|
||||
UpdateWindow(r->hWnd);
|
||||
|
||||
InvalidateRect(r->hWnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroy(MwLL handle) {
|
||||
MwLLDestroyCommon(handle);
|
||||
|
||||
DestroyWindow(handle->hWnd);
|
||||
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void MwLLPolygon(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
POINT* p = malloc(sizeof(*p) * points_count);
|
||||
HPEN pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0));
|
||||
int i;
|
||||
|
||||
for(i = 0; i < points_count; i++) {
|
||||
p[i].x = points[i].x;
|
||||
p[i].y = points[i].y;
|
||||
}
|
||||
SelectObject(handle->hDC, color->brush);
|
||||
SelectObject(handle->hDC, pen);
|
||||
SetPolyFillMode(handle->hDC, ALTERNATE);
|
||||
Polygon(handle->hDC, p, points_count);
|
||||
|
||||
DeleteObject(pen);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
MwLLColor MwLLAllocColor(MwLL handle, int r, int g, int b) {
|
||||
MwLLColor c = malloc(sizeof(*c));
|
||||
HDC dc = GetDC(handle->hWnd);
|
||||
|
||||
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;
|
||||
|
||||
c->brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b)));
|
||||
c->red = r;
|
||||
c->green = g;
|
||||
c->blue = b;
|
||||
|
||||
ReleaseDC(handle->hWnd, dc);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void MwLLFreeColor(MwLLColor color) {
|
||||
DeleteObject(color->brush);
|
||||
|
||||
free(color);
|
||||
}
|
||||
|
||||
void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
||||
RECT rc;
|
||||
|
||||
GetClientRect(handle->hWnd, &rc);
|
||||
MapWindowPoints(handle->hWnd, GetParent(handle->hWnd), (LPPOINT)&rc, 2);
|
||||
|
||||
*x = rc.left;
|
||||
*y = rc.top;
|
||||
*w = rc.right - rc.left;
|
||||
*h = rc.bottom - rc.top;
|
||||
}
|
||||
|
||||
void MwLLSetXY(MwLL handle, int x, int y) {
|
||||
SetWindowPos(handle->hWnd, NULL, x, y, 0, 0, SWP_NOSIZE);
|
||||
InvalidateRect(handle->hWnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
void MwLLSetWH(MwLL handle, int w, int h) {
|
||||
SetWindowPos(handle->hWnd, NULL, 0, 0, w, h, SWP_NOMOVE);
|
||||
InvalidateRect(handle->hWnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
void MwLLSetTitle(MwLL handle, const char* title) {
|
||||
SetWindowText(handle->hWnd, title);
|
||||
}
|
||||
|
||||
int MwLLPending(MwLL handle) {
|
||||
MSG msg;
|
||||
|
||||
(void)handle;
|
||||
|
||||
return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) ? 1 : 0;
|
||||
}
|
||||
|
||||
void MwLLNextEvent(MwLL handle) {
|
||||
MSG msg;
|
||||
|
||||
(void)handle;
|
||||
|
||||
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
|
||||
GetMessage(&msg, NULL, 0, 0);
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
void MwLLSleep(int ms) {
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
MwLLPixmap MwLLCreatePixmap(MwLL handle, unsigned char* data, int width, int height) {
|
||||
MwLLPixmap r = malloc(sizeof(*r));
|
||||
HDC dc = GetDC(handle->hWnd);
|
||||
BITMAPINFOHEADER bmih;
|
||||
RGBQUAD* quad = NULL;
|
||||
int y, x;
|
||||
|
||||
r->width = width;
|
||||
r->height = height;
|
||||
|
||||
bmih.biSize = sizeof(bmih);
|
||||
bmih.biWidth = width;
|
||||
bmih.biHeight = -(LONG)height;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = 32;
|
||||
bmih.biCompression = BI_RGB;
|
||||
bmih.biSizeImage = 0;
|
||||
bmih.biXPelsPerMeter = 0;
|
||||
bmih.biYPelsPerMeter = 0;
|
||||
bmih.biClrUsed = 0;
|
||||
bmih.biClrImportant = 0;
|
||||
|
||||
r->hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&quad, NULL, (DWORD)0);
|
||||
|
||||
for(y = 0; y < height; y++) {
|
||||
for(x = 0; x < width; x++) {
|
||||
RGBQUAD* q = &quad[y * width + x];
|
||||
unsigned char* px = &data[(y * width + x) * 4];
|
||||
q->rgbRed = px[0];
|
||||
q->rgbGreen = px[1];
|
||||
q->rgbBlue = px[2];
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseDC(handle->hWnd, dc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||
DeleteObject(pixmap->hBitmap);
|
||||
|
||||
free(pixmap);
|
||||
}
|
||||
|
||||
void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||
HDC hmdc = CreateCompatibleDC(handle->hDC);
|
||||
|
||||
SelectObject(hmdc, pixmap->hBitmap);
|
||||
|
||||
SetStretchBltMode(handle->hDC, HALFTONE);
|
||||
StretchBlt(handle->hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->width, pixmap->height, SRCCOPY);
|
||||
|
||||
DeleteDC(hmdc);
|
||||
}
|
||||
|
||||
void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) {
|
||||
ICONINFO ii;
|
||||
HICON ico;
|
||||
HBITMAP mask;
|
||||
|
||||
mask = CreateBitmap(pixmap->width, pixmap->height, 1, 1, NULL);
|
||||
|
||||
memset(&ii, 0, sizeof(ii));
|
||||
ii.fIcon = TRUE;
|
||||
ii.xHotspot = 0;
|
||||
ii.yHotspot = 0;
|
||||
ii.hbmMask = mask;
|
||||
ii.hbmColor = pixmap->hBitmap;
|
||||
|
||||
ico = CreateIconIndirect(&ii);
|
||||
|
||||
DeleteObject(mask);
|
||||
|
||||
SetClassLongPtr(handle->hWnd, GCLP_HICON, (LPARAM)ico);
|
||||
|
||||
DestroyIcon(ico);
|
||||
}
|
||||
323
src/backend/x11.c
Normal file
323
src/backend/x11.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/* $Id$ */
|
||||
#include <Mw/Milsko.h>
|
||||
|
||||
static unsigned long mask = ExposureMask | StructureNotifyMask | ButtonPressMask | ButtonReleaseMask;
|
||||
|
||||
static void create_pixmap(MwLL handle) {
|
||||
XWindowAttributes attr;
|
||||
int x, y;
|
||||
unsigned int w, h;
|
||||
|
||||
MwLLGetXYWH(handle, &x, &y, &w, &h);
|
||||
|
||||
XGetWindowAttributes(handle->display, handle->window, &attr);
|
||||
|
||||
handle->pixmap = XCreatePixmap(handle->display, handle->window, w, h, attr.depth);
|
||||
}
|
||||
|
||||
static void destroy_pixmap(MwLL handle) {
|
||||
XFreePixmap(handle->display, handle->pixmap);
|
||||
}
|
||||
|
||||
MwLL MwLLCreate(MwLL parent, int x, int y, int width, int height) {
|
||||
MwLL r;
|
||||
Window p;
|
||||
|
||||
r = malloc(sizeof(*r));
|
||||
|
||||
MwLLCreateCommon(r);
|
||||
|
||||
if(width < 1) width = 1;
|
||||
if(height < 1) height = 1;
|
||||
|
||||
if(parent == NULL) {
|
||||
r->display = XOpenDisplay(NULL);
|
||||
p = XRootWindow(r->display, XDefaultScreen(r->display));
|
||||
} else {
|
||||
r->display = parent->display;
|
||||
p = parent->window;
|
||||
}
|
||||
r->window = XCreateSimpleWindow(r->display, p, x, y, width, height, 0, 0, WhitePixel(r->display, XDefaultScreen(r->display)));
|
||||
r->copy_buffer = 1;
|
||||
|
||||
r->width = width;
|
||||
r->height = height;
|
||||
|
||||
r->colormap = DefaultColormap(r->display, XDefaultScreen(r->display));
|
||||
r->wm_delete = XInternAtom(r->display, "WM_DELETE_WINDOW", False);
|
||||
XSetWMProtocols(r->display, r->window, &r->wm_delete, 1);
|
||||
|
||||
r->gc = XCreateGC(r->display, r->window, 0, 0);
|
||||
|
||||
create_pixmap(r);
|
||||
|
||||
XSetGraphicsExposures(r->display, r->gc, False);
|
||||
|
||||
XSelectInput(r->display, r->window, mask);
|
||||
XMapWindow(r->display, r->window);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroy(MwLL handle) {
|
||||
MwLLDestroyCommon(handle);
|
||||
|
||||
destroy_pixmap(handle);
|
||||
XFreeGC(handle->display, handle->gc);
|
||||
XDestroyWindow(handle->display, handle->window);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
void MwLLPolygon(MwLL handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
int i;
|
||||
XPoint* p = malloc(sizeof(*p) * points_count);
|
||||
|
||||
XSetForeground(handle->display, handle->gc, color->pixel);
|
||||
|
||||
for(i = 0; i < points_count; i++) {
|
||||
p[i].x = points[i].x;
|
||||
p[i].y = points[i].y;
|
||||
}
|
||||
XFillPolygon(handle->display, handle->pixmap, handle->gc, p, points_count, Convex, CoordModeOrigin);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
xc.red = 256 * r;
|
||||
xc.green = 256 * g;
|
||||
xc.blue = 256 * b;
|
||||
XAllocColor(handle->display, handle->colormap, &xc);
|
||||
|
||||
c->pixel = xc.pixel;
|
||||
c->red = r;
|
||||
c->green = g;
|
||||
c->blue = b;
|
||||
return c;
|
||||
}
|
||||
|
||||
void MwLLGetXYWH(MwLL handle, int* x, int* y, unsigned int* w, unsigned int* h) {
|
||||
Window root;
|
||||
unsigned int border, depth;
|
||||
|
||||
XGetGeometry(handle->display, handle->window, &root, x, y, w, h, &border, &depth);
|
||||
}
|
||||
|
||||
void MwLLSetXY(MwLL handle, int x, int y) {
|
||||
XMoveWindow(handle->display, handle->window, x, y);
|
||||
}
|
||||
|
||||
void MwLLSetWH(MwLL handle, int w, int h) {
|
||||
if(w < 1) w = 1;
|
||||
if(h < 1) h = 1;
|
||||
|
||||
XResizeWindow(handle->display, handle->window, w, h);
|
||||
}
|
||||
|
||||
void MwLLFreeColor(MwLLColor color) {
|
||||
free(color);
|
||||
}
|
||||
|
||||
int MwLLPending(MwLL handle) {
|
||||
XEvent ev;
|
||||
if(XCheckTypedWindowEvent(handle->display, handle->window, ClientMessage, &ev) || XCheckWindowEvent(handle->display, handle->window, mask, &ev)) {
|
||||
XPutBackEvent(handle->display, &ev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MwLLNextEvent(MwLL handle) {
|
||||
XEvent ev;
|
||||
while(XCheckTypedWindowEvent(handle->display, handle->window, ClientMessage, &ev) || XCheckWindowEvent(handle->display, handle->window, mask, &ev)) {
|
||||
int render = 0;
|
||||
if(ev.type == Expose) {
|
||||
render = 1;
|
||||
} else if(ev.type == ButtonPress) {
|
||||
if(ev.xbutton.button == Button1) {
|
||||
MwPoint p;
|
||||
p.x = ev.xbutton.x;
|
||||
p.y = ev.xbutton.y;
|
||||
|
||||
MwLLDispatch(handle, down, &p);
|
||||
render = 1;
|
||||
}
|
||||
} else if(ev.type == ButtonRelease) {
|
||||
if(ev.xbutton.button == Button1) {
|
||||
MwPoint p;
|
||||
p.x = ev.xbutton.x;
|
||||
p.y = ev.xbutton.y;
|
||||
|
||||
MwLLDispatch(handle, up, &p);
|
||||
render = 1;
|
||||
}
|
||||
} else if(ev.type == ConfigureNotify) {
|
||||
MwLLDispatch(handle, resize, NULL);
|
||||
|
||||
if(handle->width != (unsigned int)ev.xconfigure.width || handle->height != (unsigned int)ev.xconfigure.height) {
|
||||
destroy_pixmap(handle);
|
||||
create_pixmap(handle);
|
||||
render = 1;
|
||||
}
|
||||
handle->width = ev.xconfigure.width;
|
||||
handle->height = ev.xconfigure.height;
|
||||
} else if(ev.type == ClientMessage) {
|
||||
if(ev.xclient.data.l[0] == (long)handle->wm_delete) {
|
||||
MwLLDispatch(handle, close, NULL);
|
||||
}
|
||||
}
|
||||
if(render) {
|
||||
int x, y;
|
||||
unsigned int w, h;
|
||||
|
||||
MwLLGetXYWH(handle, &x, &y, &w, &h);
|
||||
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
if(handle->copy_buffer) XCopyArea(handle->display, handle->pixmap, handle->window, handle->gc, 0, 0, w, h, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MwLLSleep(int ms) {
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
void MwLLSetTitle(MwLL handle, const char* title) {
|
||||
XSetStandardProperties(handle->display, handle->window, title, title, None, (char**)NULL, 0, NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
r->width = width;
|
||||
r->height = height;
|
||||
r->display = handle->display;
|
||||
r->use_shm = XShmQueryExtension(handle->display) ? 1 : 0;
|
||||
r->data = malloc(width * height * 4);
|
||||
|
||||
if(!XRenderQueryExtension(handle->display, &evbase, &erbase)) {
|
||||
fprintf(stderr, "XRender missing - cannot proceed pixmap creation\n");
|
||||
r->image = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
if(r->use_shm) {
|
||||
r->image = XShmCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, ZPixmap, NULL, &r->shm, width, height);
|
||||
free(d);
|
||||
|
||||
r->shm.shmid = shmget(IPC_PRIVATE, r->image->bytes_per_line * height, IPC_CREAT | 0777);
|
||||
r->shm.shmaddr = d = r->image->data = shmat(r->shm.shmid, 0, 0);
|
||||
r->shm.readOnly = False;
|
||||
XShmAttach(handle->display, &r->shm);
|
||||
} else {
|
||||
r->image = XCreateImage(handle->display, DefaultVisual(handle->display, DefaultScreen(handle->display)), 24, 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];
|
||||
XPutPixel(r->image, x, y, p);
|
||||
*(unsigned long*)(&r->data[(x + y * width) * 4]) = p;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void MwLLDestroyPixmap(MwLLPixmap pixmap) {
|
||||
if(pixmap->image != NULL) {
|
||||
if(pixmap->use_shm) {
|
||||
XShmDetach(pixmap->display, &pixmap->shm);
|
||||
}
|
||||
XDestroyImage(pixmap->image);
|
||||
if(pixmap->use_shm) {
|
||||
shmdt(pixmap->shm.shmaddr);
|
||||
shmctl(pixmap->shm.shmid, IPC_RMID, 0);
|
||||
}
|
||||
free(pixmap->data);
|
||||
}
|
||||
|
||||
free(pixmap);
|
||||
}
|
||||
|
||||
void MwLLDrawPixmap(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||
if(pixmap->image != NULL) {
|
||||
Pixmap px = XCreatePixmap(handle->display, handle->window, pixmap->width, pixmap->height, 24);
|
||||
XRenderPictFormat* format = XRenderFindStandardFormat(handle->display, PictStandardRGB24);
|
||||
XRenderPictureAttributes attr;
|
||||
Picture src, dest;
|
||||
XTransform m;
|
||||
double xsc = (double)pixmap->width / rect->width;
|
||||
double ysc = (double)pixmap->height / rect->height;
|
||||
|
||||
m.matrix[0][0] = XDoubleToFixed(xsc);
|
||||
m.matrix[0][1] = XDoubleToFixed(0);
|
||||
m.matrix[0][2] = XDoubleToFixed(0);
|
||||
|
||||
m.matrix[1][0] = XDoubleToFixed(0);
|
||||
m.matrix[1][1] = XDoubleToFixed(ysc);
|
||||
m.matrix[1][2] = XDoubleToFixed(0);
|
||||
|
||||
m.matrix[2][0] = XDoubleToFixed(0);
|
||||
m.matrix[2][1] = XDoubleToFixed(0);
|
||||
m.matrix[2][2] = XDoubleToFixed(1.0);
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
|
||||
if(pixmap->use_shm) {
|
||||
XShmPutImage(handle->display, px, handle->gc, pixmap->image, 0, 0, 0, 0, pixmap->width, pixmap->height, False);
|
||||
} else {
|
||||
XPutImage(handle->display, px, handle->gc, pixmap->image, 0, 0, 0, 0, pixmap->width, pixmap->height);
|
||||
}
|
||||
|
||||
src = XRenderCreatePicture(handle->display, px, format, 0, &attr);
|
||||
dest = XRenderCreatePicture(handle->display, handle->pixmap, format, 0, &attr);
|
||||
|
||||
XRenderSetPictureTransform(handle->display, src, &m);
|
||||
XRenderComposite(handle->display, PictOpSrc, src, 0, dest, 0, 0, 0, 0, rect->x, rect->y, rect->width, rect->height);
|
||||
|
||||
XRenderFreePicture(handle->display, src);
|
||||
XRenderFreePicture(handle->display, dest);
|
||||
|
||||
XFreePixmap(handle->display, px);
|
||||
}
|
||||
}
|
||||
|
||||
void MwLLSetIcon(MwLL handle, MwLLPixmap pixmap) {
|
||||
unsigned long* icon = malloc((2 + pixmap->width * pixmap->height) * sizeof(*icon));
|
||||
int i;
|
||||
Atom atom = XInternAtom(handle->display, "_NET_WM_ICON", False);
|
||||
|
||||
icon[0] = pixmap->width;
|
||||
icon[1] = pixmap->height;
|
||||
|
||||
for(i = 0; i < pixmap->width * pixmap->height; i++) {
|
||||
icon[2 + i] = *(unsigned long*)(&pixmap->data[i * 4]);
|
||||
}
|
||||
|
||||
XChangeProperty(handle->display, handle->window, atom, 6, 32, PropModeReplace, (unsigned char*)icon, 2 + pixmap->width * pixmap->height);
|
||||
|
||||
free(icon);
|
||||
}
|
||||
Reference in New Issue
Block a user