#include <u.h>#include <mingw32.h>#include <mingwutil.h>#include <libc.h>#include <thread.h>#include <draw.h>#include <mouse.h>#include <cursor.h>#include <memdraw.h>#include "screen.h"#include "fns.h"#include "keyboard.h"#include "if.h" enum { STACK = 32768,}; extern int parsewinsize(char*, Rectangle*, int*); Memimage *gscreen;Screeninfo screen; static int depth; static HINSTANCE inst;static HWND window;static HPALETTE palette;static LOGPALETTE *logpal;static Lock gdilock;static BITMAPINFO *bmi;static HCURSOR hcursor; static void winproc(void *);static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);static void paletteinit(void);static void bmiinit(void); Point ZP; extern int mresized;extern Channel *cmouse;extern Channel *ckbd;static voidkbdputc(ulong c){ static int wasctl; switch (c) { case Kctl: wasctl = 1; return; case Kalt: if (wasctl) break; /* ignore AltGr key */ default:// fprint(2, "taste: %ld 0x%04lux\n", c, c); sendul(ckbd, c); } wasctl = 0;} static voidoserror(void){} static uintmsec(void){ return nsec()/1000000;} static int fmt;static voidmkgscreen(void){ RECT r; int dx, dy; if(!GetClientRect(window, &r)){ oserror(); sysfatal("GetClientRect: %r"); } dx = r.right - r.left; dy = r.bottom - r.top; gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);} static voidresizescreenimage(void){ mkgscreen(); _drawreplacescreenimage(gscreen);} typedefstruct Winarg{ int x, y, dx, dy; Channel *csync; char label[1];} Winarg;Memimage*_xattach(char *label, char *winsize){ Winarg *a; Rectangle r; int havemin; memimageinit(); if(depth == 0) depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL); switch(depth){ case 32: screen.dibtype = DIB_RGB_COLORS; screen.depth = 32; fmt = XRGB32; break; case 24: screen.dibtype = DIB_RGB_COLORS; screen.depth = 24; fmt = RGB24; break; case 16: screen.dibtype = DIB_RGB_COLORS; screen.depth = 16; fmt = RGB15; /* [sic] */ break; case 8: default: screen.dibtype = DIB_PAL_COLORS; screen.depth = 8; depth = 8; fmt = CMAP8; break; } if(label == nil) label = "pjw-face-here"; a = malloc(sizeof(Winarg)+strlen(label)); if (a==nil) sysfatal("out of memory"); strcpy(a->label, label); a->dx = CW_USEDEFAULT; a->dy = CW_USEDEFAULT; havemin = 0; if(winsize && winsize[0]){ if(parsewinsize(winsize, &r, &havemin) < 0) sysfatal("%r"); a->dx = Dx(r); a->dy = Dy(r); } if (havemin) { a->x = r.min.x; a->y = r.min.y; } else { a->x = CW_USEDEFAULT; a->y = CW_USEDEFAULT; } // fprint(2, "%d %d %d %d\n", a->x, a->y, a->dx, a->dy); a->csync = chancreate(sizeof(ulong), 0); proccreate(winproc, a, STACK); recvul(a->csync); mkgscreen(); sendul(a->csync, 1); recvul(a->csync); return gscreen;} uchar*attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen, void **X){ *r = gscreen->r; *chan = gscreen->chan; *depth = gscreen->depth; *width = gscreen->width; *softscreen = 1; return gscreen->data->bdata;} void_flushmemscreen(Rectangle r){ screenload(r, gscreen->depth, byteaddr(gscreen, ZP), ZP, gscreen->width*sizeof(ulong));// Sleep(100);} voidscreenload(Rectangle r, int depth, uchar *p, Point pt, int step){ int dx, dy, delx; HDC hdc; RECT winr; if(depth != gscreen->depth) sysfatal("screenload: bad ldepth"); /* * Sometimes we do get rectangles that are off the * screen to the negative axes, for example, when * dragging around a window border in a Move operation. */ if(rectclip(&r, gscreen->r) == 0) return; if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0) sysfatal("screenload: bad params %d %d %ux", step, pt.x, p); dx = r.max.x - r.min.x; dy = r.max.y - r.min.y; if(dx <= 0 || dy <= 0) return; if(depth == 24) delx = r.min.x % 4; else delx = r.min.x & (31/depth); p += (r.min.y-pt.y)*step; p += ((r.min.x-delx-pt.x)*depth)>>3; if(GetWindowRect(window, &winr)==0) return; if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0) return; lock(&gdilock); hdc = GetDC(window); SelectPalette(hdc, palette, 0); RealizePalette(hdc); //FillRect(hdc,(void*)&r, GetStockObject(BLACK_BRUSH));//GdiFlush();//Sleep(100); bmi->bmiHeader.biWidth = (step*8)/depth; bmi->bmiHeader.biHeight = -dy; /* - => origin upper left */ StretchDIBits(hdc, r.min.x, r.min.y, dx, dy, delx, 0, dx, dy, p, bmi, screen.dibtype, SRCCOPY); ReleaseDC(window, hdc); GdiFlush(); unlock(&gdilock);} static voidwinproc(void *v){ WNDCLASS wc; MSG msg; Winarg *a; a = v; inst = GetModuleHandle(NULL); paletteinit(); bmiinit();// terminit(); wc.style = 0; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = inst; wc.hIcon = LoadIcon(inst, "IDI_ICON1"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = "9pmgraphics"; RegisterClass(&wc); window = CreateWindowEx( 0, /* extended style */ "9pmgraphics", /* class */ a->label, /* caption */ WS_OVERLAPPEDWINDOW, /* style */ a->x, /* init. x pos */ a->y, /* init. y pos */ a->dx, /* init. x size */ a->dy, /* init. y size */ NULL, /* parent window (actually owner window for overlapped)*/ NULL, /* menu handle */ inst, /* program handle */ NULL /* create parms */ ); if(window == nil) sysfatal("can't make window\n"); sendul(a->csync, 1); /* window is ready */ recvul(a->csync); /* wait for gscreen */ ShowWindow(window, SW_SHOWDEFAULT); sendul(a->csync, 1); /* window is ready */ chanfree(a->csync); // free(a); screen.reshaped = 0; for(;;){ switch(GetMessage(&msg, NULL, 0, 0)){ case -1: winerror("GetMessage"); sysfatal("%r\n"); case 0: goto quit; default: TranslateMessage(&msg); DispatchMessage(&msg); } }quit:// MessageBox(0, "winproc", "exits", MB_OK); threadexitsall(nil);} intcol(int v, int n){ int i, c; c = 0; for(i = 0; i < 8; i += n) c |= v << (16-(n+i)); return c >> 8;} voidpaletteinit(void){ PALETTEENTRY *pal; int r, g, b, cr, cg, cb, v; int num, den; int i, j; logpal = mallocz(sizeof(LOGPALETTE) + 256*sizeof(PALETTEENTRY), 1); if(logpal == nil) sysfatal("out of memory"); logpal->palVersion = 0x300; logpal->palNumEntries = 256; pal = logpal->palPalEntry; for(r=0,i=0; r<4; r++) { for(v=0; v<4; v++,i+=16){ for(g=0,j=v-r; g<4; g++) { for(b=0; b<4; b++,j++){ den=r; if(g>den) den=g; if(b>den) den=b; /* divide check -- pick grey shades */ if(den==0) cr=cg=cb=v*17; else{ num=17*(4*den+v); cr=r*num/den; cg=g*num/den; cb=b*num/den; } pal[i+(j&15)].peRed = cr; pal[i+(j&15)].peGreen = cg; pal[i+(j&15)].peBlue = cb; pal[i+(j&15)].peFlags = 0; } } } } palette = CreatePalette(logpal);} voidgetcolor(ulong i, ulong *r, ulong *g, ulong *b){ PALETTEENTRY *pal; pal = logpal->palPalEntry; *r = pal[i].peRed; *g = pal[i].peGreen; *b = pal[i].peBlue;} voidbmiinit(void){ ushort *p; int i; bmi = mallocz(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD), 1); if(bmi == 0) sysfatal("out of memory"); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = 0; bmi->bmiHeader.biHeight = 0; /* - => origin upper left */ bmi->bmiHeader.biPlanes = 1; bmi->bmiHeader.biBitCount = depth; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biSizeImage = 0; bmi->bmiHeader.biXPelsPerMeter = 0; bmi->bmiHeader.biYPelsPerMeter = 0; bmi->bmiHeader.biClrUsed = 0; bmi->bmiHeader.biClrImportant = 0; /* number of important colors: 0 means all */ p = (ushort*)bmi->bmiColors; for(i = 0; i < 256; i++) p[i] = i;} LRESULT CALLBACKWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){ PAINTSTRUCT paint; HDC hdc; LONG x, y, b; int wid, ht; Rectangle r; static Mouse m; b = 0; switch(msg) { case WM_CREATE: break; case WM_SETCURSOR: /* User set */ if(hcursor != NULL) { SetCursor(hcursor); return 1; } return DefWindowProc(hwnd, msg, wparam, lparam); case WM_MOUSEWHEEL: if ((int)(wparam & 0xFFFF0000)>0) b|=8; else b|=16; case WM_MOUSEMOVE: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: x = LOWORD(lparam); y = HIWORD(lparam); if(wparam & MK_LBUTTON) b = 1; if(wparam & MK_MBUTTON) b |= 2; if(wparam & MK_RBUTTON) { if(wparam & MK_SHIFT) b |= 2; else b |= 4; } m.xy.x = x; m.xy.y = y; m.buttons = b; m.msec = msec(); send(cmouse, &m); break; case WM_CHAR: /* repeat count is lparam & 0xf */ switch(wparam){ case '\n': wparam = '\r'; break; case '\r': wparam = '\n'; break; } kbdputc(wparam); break; case WM_SYSKEYUP: break; case WM_SYSKEYDOWN: case WM_KEYDOWN: switch(wparam) { case VK_CONTROL: kbdputc(Kctl); break; case VK_MENU: kbdputc(Kalt); break; case VK_INSERT: kbdputc(Kins); break;Lines 1–500 of 760. Load more
#include <u.h> #include <mingw32.h> #include <mingwutil.h> #include <libc.h> #include <thread.h> #include <draw.h> #include <mouse.h> #include <cursor.h> #include <memdraw.h> #include "screen.h" #include "fns.h" #include "keyboard.h" #include "if.h" enum { STACK = 32768, }; extern int parsewinsize(char*, Rectangle*, int*); Memimage *gscreen; Screeninfo screen; static int depth; static HINSTANCE inst; static HWND window; static HPALETTE palette; static LOGPALETTE *logpal; static Lock gdilock; static BITMAPINFO *bmi; static HCURSOR hcursor; static void winproc(void *); static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); static void paletteinit(void); static void bmiinit(void); Point ZP; extern int mresized; extern Channel *cmouse; extern Channel *ckbd; static void kbdputc(ulong c) { static int wasctl; switch (c) { case Kctl: wasctl = 1; return; case Kalt: if (wasctl) break; /* ignore AltGr key */ default: // fprint(2, "taste: %ld 0x%04lux\n", c, c); sendul(ckbd, c); } wasctl = 0; } static void oserror(void) { } static uint msec(void) { return nsec()/1000000; } static int fmt; static void mkgscreen(void) { RECT r; int dx, dy; if(!GetClientRect(window, &r)){ oserror(); sysfatal("GetClientRect: %r"); } dx = r.right - r.left; dy = r.bottom - r.top; gscreen = allocmemimage(Rect(0,0,dx,dy), fmt); } static void resizescreenimage(void) { mkgscreen(); _drawreplacescreenimage(gscreen); } typedef struct Winarg { int x, y, dx, dy; Channel *csync; char label[1]; } Winarg; Memimage* _xattach(char *label, char *winsize) { Winarg *a; Rectangle r; int havemin; memimageinit(); if(depth == 0) depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL); switch(depth){ case 32: screen.dibtype = DIB_RGB_COLORS; screen.depth = 32; fmt = XRGB32; break; case 24: screen.dibtype = DIB_RGB_COLORS; screen.depth = 24; fmt = RGB24; break; case 16: screen.dibtype = DIB_RGB_COLORS; screen.depth = 16; fmt = RGB15; /* [sic] */ break; case 8: default: screen.dibtype = DIB_PAL_COLORS; screen.depth = 8; depth = 8; fmt = CMAP8; break; } if(label == nil) label = "pjw-face-here"; a = malloc(sizeof(Winarg)+strlen(label)); if (a==nil) sysfatal("out of memory"); strcpy(a->label, label); a->dx = CW_USEDEFAULT; a->dy = CW_USEDEFAULT; havemin = 0; if(winsize && winsize[0]){ if(parsewinsize(winsize, &r, &havemin) < 0) sysfatal("%r"); a->dx = Dx(r); a->dy = Dy(r); } if (havemin) { a->x = r.min.x; a->y = r.min.y; } else { a->x = CW_USEDEFAULT; a->y = CW_USEDEFAULT; } // fprint(2, "%d %d %d %d\n", a->x, a->y, a->dx, a->dy); a->csync = chancreate(sizeof(ulong), 0); proccreate(winproc, a, STACK); recvul(a->csync); mkgscreen(); sendul(a->csync, 1); recvul(a->csync); return gscreen; } uchar* attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen, void **X) { *r = gscreen->r; *chan = gscreen->chan; *depth = gscreen->depth; *width = gscreen->width; *softscreen = 1; return gscreen->data->bdata; } void _flushmemscreen(Rectangle r) { screenload(r, gscreen->depth, byteaddr(gscreen, ZP), ZP, gscreen->width*sizeof(ulong)); // Sleep(100); } void screenload(Rectangle r, int depth, uchar *p, Point pt, int step) { int dx, dy, delx; HDC hdc; RECT winr; if(depth != gscreen->depth) sysfatal("screenload: bad ldepth"); /* * Sometimes we do get rectangles that are off the * screen to the negative axes, for example, when * dragging around a window border in a Move operation. */ if(rectclip(&r, gscreen->r) == 0) return; if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0) sysfatal("screenload: bad params %d %d %ux", step, pt.x, p); dx = r.max.x - r.min.x; dy = r.max.y - r.min.y; if(dx <= 0 || dy <= 0) return; if(depth == 24) delx = r.min.x % 4; else delx = r.min.x & (31/depth); p += (r.min.y-pt.y)*step; p += ((r.min.x-delx-pt.x)*depth)>>3; if(GetWindowRect(window, &winr)==0) return; if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0) return; lock(&gdilock); hdc = GetDC(window); SelectPalette(hdc, palette, 0); RealizePalette(hdc); //FillRect(hdc,(void*)&r, GetStockObject(BLACK_BRUSH)); //GdiFlush(); //Sleep(100); bmi->bmiHeader.biWidth = (step*8)/depth; bmi->bmiHeader.biHeight = -dy; /* - => origin upper left */ StretchDIBits(hdc, r.min.x, r.min.y, dx, dy, delx, 0, dx, dy, p, bmi, screen.dibtype, SRCCOPY); ReleaseDC(window, hdc); GdiFlush(); unlock(&gdilock); } static void winproc(void *v) { WNDCLASS wc; MSG msg; Winarg *a; a = v; inst = GetModuleHandle(NULL); paletteinit(); bmiinit(); // terminit(); wc.style = 0; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = inst; wc.hIcon = LoadIcon(inst, "IDI_ICON1"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = 0; wc.lpszClassName = "9pmgraphics"; RegisterClass(&wc); window = CreateWindowEx( 0, /* extended style */ "9pmgraphics", /* class */ a->label, /* caption */ WS_OVERLAPPEDWINDOW, /* style */ a->x, /* init. x pos */ a->y, /* init. y pos */ a->dx, /* init. x size */ a->dy, /* init. y size */ NULL, /* parent window (actually owner window for overlapped)*/ NULL, /* menu handle */ inst, /* program handle */ NULL /* create parms */ ); if(window == nil) sysfatal("can't make window\n"); sendul(a->csync, 1); /* window is ready */ recvul(a->csync); /* wait for gscreen */ ShowWindow(window, SW_SHOWDEFAULT); sendul(a->csync, 1); /* window is ready */ chanfree(a->csync); // free(a); screen.reshaped = 0; for(;;){ switch(GetMessage(&msg, NULL, 0, 0)){ case -1: winerror("GetMessage"); sysfatal("%r\n"); case 0: goto quit; default: TranslateMessage(&msg); DispatchMessage(&msg); } } quit: // MessageBox(0, "winproc", "exits", MB_OK); threadexitsall(nil); } int col(int v, int n) { int i, c; c = 0; for(i = 0; i < 8; i += n) c |= v << (16-(n+i)); return c >> 8; } void paletteinit(void) { PALETTEENTRY *pal; int r, g, b, cr, cg, cb, v; int num, den; int i, j; logpal = mallocz(sizeof(LOGPALETTE) + 256*sizeof(PALETTEENTRY), 1); if(logpal == nil) sysfatal("out of memory"); logpal->palVersion = 0x300; logpal->palNumEntries = 256; pal = logpal->palPalEntry; for(r=0,i=0; r<4; r++) { for(v=0; v<4; v++,i+=16){ for(g=0,j=v-r; g<4; g++) { for(b=0; b<4; b++,j++){ den=r; if(g>den) den=g; if(b>den) den=b; /* divide check -- pick grey shades */ if(den==0) cr=cg=cb=v*17; else{ num=17*(4*den+v); cr=r*num/den; cg=g*num/den; cb=b*num/den; } pal[i+(j&15)].peRed = cr; pal[i+(j&15)].peGreen = cg; pal[i+(j&15)].peBlue = cb; pal[i+(j&15)].peFlags = 0; } } } } palette = CreatePalette(logpal); } void getcolor(ulong i, ulong *r, ulong *g, ulong *b) { PALETTEENTRY *pal; pal = logpal->palPalEntry; *r = pal[i].peRed; *g = pal[i].peGreen; *b = pal[i].peBlue; } void bmiinit(void) { ushort *p; int i; bmi = mallocz(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD), 1); if(bmi == 0) sysfatal("out of memory"); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = 0; bmi->bmiHeader.biHeight = 0; /* - => origin upper left */ bmi->bmiHeader.biPlanes = 1; bmi->bmiHeader.biBitCount = depth; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biSizeImage = 0; bmi->bmiHeader.biXPelsPerMeter = 0; bmi->bmiHeader.biYPelsPerMeter = 0; bmi->bmiHeader.biClrUsed = 0; bmi->bmiHeader.biClrImportant = 0; /* number of important colors: 0 means all */ p = (ushort*)bmi->bmiColors; for(i = 0; i < 256; i++) p[i] = i; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT paint; HDC hdc; LONG x, y, b; int wid, ht; Rectangle r; static Mouse m; b = 0; switch(msg) { case WM_CREATE: break; case WM_SETCURSOR: /* User set */ if(hcursor != NULL) { SetCursor(hcursor); return 1; } return DefWindowProc(hwnd, msg, wparam, lparam); case WM_MOUSEWHEEL: if ((int)(wparam & 0xFFFF0000)>0) b|=8; else b|=16; case WM_MOUSEMOVE: case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: x = LOWORD(lparam); y = HIWORD(lparam); if(wparam & MK_LBUTTON) b = 1; if(wparam & MK_MBUTTON) b |= 2; if(wparam & MK_RBUTTON) { if(wparam & MK_SHIFT) b |= 2; else b |= 4; } m.xy.x = x; m.xy.y = y; m.buttons = b; m.msec = msec(); send(cmouse, &m); break; case WM_CHAR: /* repeat count is lparam & 0xf */ switch(wparam){ case '\n': wparam = '\r'; break; case '\r': wparam = '\n'; break; } kbdputc(wparam); break; case WM_SYSKEYUP: break; case WM_SYSKEYDOWN: case WM_KEYDOWN: switch(wparam) { case VK_CONTROL: kbdputc(Kctl); break; case VK_MENU: kbdputc(Kalt); break; case VK_INSERT: kbdputc(Kins); break;