123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- #include <windows.h>
- #undef Rectangle
- #define Rectangle _Rectangle
- #include "lib9.h"
- #include "sys.h"
- #include "error.h"
- #include "libdraw/draw.h"
- #include "libmemdraw/memdraw.h"
- #include "screen.h"
- #include "keyboard.h"
- Memimage *gscreen;
- Screeninfo screen;
- extern int mousequeue;
- extern 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);
- static void screenload2(Rectangle r, int ldepth, uchar *p, Point pt, int step);
- static int ready;
- static Rendez rend;
- Point ZP;
- static
- isready(void*a)
- {
- return ready;
- }
- void
- screeninit(void)
- {
- int fmt;
- int dx, dy;
- 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;
- }
- dx = GetDeviceCaps(GetDC(NULL), HORZRES);
- dy = GetDeviceCaps(GetDC(NULL), VERTRES);
- gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);
- thread("winscreen", winproc, 0);
- rendsleep(&rend, isready, 0);
- }
- 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)
- panic("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)
- panic("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 *a)
- {
- WNDCLASS wc;
- MSG msg;
- 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, NULL);
- 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 */
- "drawterm screen", /* caption */
- WS_OVERLAPPEDWINDOW, /* style */
- CW_USEDEFAULT, /* init. x pos */
- CW_USEDEFAULT, /* init. y pos */
- CW_USEDEFAULT, /* init. x size */
- CW_USEDEFAULT, /* init. y size */
- NULL, /* parent window (actually owner window for overlapped)*/
- NULL, /* menu handle */
- inst, /* program handle */
- NULL /* create parms */
- );
- if(window == nil)
- panic("can't make window\n");
- ShowWindow(window, SW_SHOWDEFAULT);
- UpdateWindow(window);
- ready = 1;
- rendwakeup(&rend);
- screen.reshaped = 0;
- while(GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- // MessageBox(0, "winproc", "exits", MB_OK);
- ExitProcess(0);
- }
- 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));
- if(logpal == nil)
- panic("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));
- if(bmi == 0)
- panic("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 i;
- Rectangle r;
- 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_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);
- b = 0;
- 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;
- }
- lock(&mouse.lk);
- i = mouse.wi;
- if(mousequeue) {
- if(i == mouse.ri || mouse.lastb != b || mouse.trans) {
- mouse.wi = (i+1)%Mousequeue;
- if(mouse.wi == mouse.ri)
- mouse.ri = (mouse.ri+1)%Mousequeue;
- mouse.trans = mouse.lastb != b;
- } else {
- i = (i-1+Mousequeue)%Mousequeue;
- }
- } else {
- mouse.wi = (i+1)%Mousequeue;
- mouse.ri = i;
- }
- mouse.queue[i].xy.x = x;
- mouse.queue[i].xy.y = y;
- mouse.queue[i].buttons = b;
- mouse.queue[i].msec = ticks();
- mouse.lastb = b;
- unlock(&mouse.lk);
- rendwakeup(&mouse.r);
- 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_MENU:
- kbdputc(Kalt);
- break;
- case VK_INSERT:
- kbdputc(Kins);
- break;
- case VK_DELETE:
- kbdputc(Kdel);
- break;
- case VK_UP:
- kbdputc(Kup);
- break;
- case VK_DOWN:
- kbdputc(Kdown);
- break;
- case VK_LEFT:
- kbdputc(Kleft);
- break;
- case VK_RIGHT:
- kbdputc(Kright);
- break;
- }
- break;
- case WM_CLOSE:
- DestroyWindow(hwnd);
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- case WM_PALETTECHANGED:
- if((HWND)wparam == hwnd)
- break;
- /* fall through */
- case WM_QUERYNEWPALETTE:
- hdc = GetDC(hwnd);
- SelectPalette(hdc, palette, 0);
- if(RealizePalette(hdc) != 0)
- InvalidateRect(hwnd, nil, 0);
- ReleaseDC(hwnd, hdc);
- break;
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &paint);
- r.min.x = paint.rcPaint.left;
- r.min.y = paint.rcPaint.top;
- r.max.x = paint.rcPaint.right;
- r.max.y = paint.rcPaint.bottom;
- flushmemscreen(r);
- EndPaint(hwnd, &paint);
- break;
- case WM_COMMAND:
- case WM_SETFOCUS:
- case WM_DEVMODECHANGE:
- case WM_WININICHANGE:
- case WM_INITMENU:
- default:
- return DefWindowProc(hwnd, msg, wparam, lparam);
- }
- return 0;
- }
- void
- mouseset(Point xy)
- {
- POINT pt;
- pt.x = xy.x;
- pt.y = xy.y;
- MapWindowPoints(window, 0, &pt, 1);
- SetCursorPos(pt.x, pt.y);
- }
- void
- setcursor(void)
- {
- HCURSOR nh;
- int x, y, h, w;
- uchar *sp, *cp;
- uchar *and, *xor;
- h = GetSystemMetrics(SM_CYCURSOR);
- w = (GetSystemMetrics(SM_CXCURSOR)+7)/8;
- and = mallocz(h*w);
- memset(and, 0xff, h*w);
- xor = mallocz(h*w);
-
- lock(&cursor.lk);
- for(y=0,sp=cursor.set,cp=cursor.clr; y<16; y++) {
- for(x=0; x<2; x++) {
- and[y*w+x] = ~(*sp|*cp);
- xor[y*w+x] = ~*sp & *cp;
- cp++;
- sp++;
- }
- }
- nh = CreateCursor(inst, -cursor.offset.x, -cursor.offset.y,
- GetSystemMetrics(SM_CXCURSOR), h,
- and, xor);
- if(nh != NULL) {
- SetCursor(nh);
- if(hcursor != NULL)
- DestroyCursor(hcursor);
- hcursor = nh;
- }
- unlock(&cursor.lk);
- free(and);
- free(xor);
- PostMessage(window, WM_SETCURSOR, (int)window, 0);
- }
- void
- cursorarrow(void)
- {
- if(hcursor != 0) {
- DestroyCursor(hcursor);
- hcursor = 0;
- }
- SetCursor(LoadCursor(0, IDC_ARROW));
- PostMessage(window, WM_SETCURSOR, (int)window, 0);
- }
- void
- setcolor(ulong index, ulong red, ulong green, ulong blue)
- {
- }
- uchar*
- clipreadunicode(HANDLE h)
- {
- Rune *p;
- int n;
- uchar *q;
-
- p = GlobalLock(h);
- n = wstrutflen(p)+1;
- q = malloc(n);
- wstrtoutf(q, p, n);
- GlobalUnlock(h);
- return q;
- }
- uchar *
- clipreadutf(HANDLE h)
- {
- uchar *p;
- p = GlobalLock(h);
- p = strdup(p);
- GlobalUnlock(h);
-
- return p;
- }
- uchar*
- clipread()
- {
- HANDLE h;
- uchar *p;
- if(!OpenClipboard(window)) {
- oserror();
- return strdup("");
- }
- if(h = GetClipboardData(CF_UNICODETEXT))
- p = clipreadunicode(h);
- else if(h = GetClipboardData(CF_TEXT))
- p = clipreadutf(h);
- else {
- oserror();
- p = strdup("");
- }
-
- CloseClipboard();
- return p;
- }
- int
- clipwrite(uchar *buf, int n)
- {
- HANDLE h;
- char *p, *e;
- Rune *rp;
- if(!OpenClipboard(window)) {
- oserror();
- return -1;
- }
- if(!EmptyClipboard()) {
- oserror();
- CloseClipboard();
- return -1;
- }
- h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, (n+1)*sizeof(Rune));
- if(h == NULL)
- panic("out of memory");
- rp = GlobalLock(h);
- p = (char*)buf;
- e = p+n;
- while(p<e)
- p += chartorune(rp++, p);
- *rp = 0;
- GlobalUnlock(h);
- SetClipboardData(CF_UNICODETEXT, h);
- h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, n+1);
- if(h == NULL)
- panic("out of memory");
- p = GlobalLock(h);
- memcpy(p, buf, n);
- p[n] = 0;
- GlobalUnlock(h);
-
- SetClipboardData(CF_TEXT, h);
- CloseClipboard();
- return n;
- }
- int
- atlocalconsole(void)
- {
- return 1;
- }
|