1*35393782SDavid du Colombier #define _WIN32_WINNT 0x0500
28ccd4a63SDavid du Colombier #include <windows.h>
38ccd4a63SDavid du Colombier
48ccd4a63SDavid du Colombier #undef Rectangle
58ccd4a63SDavid du Colombier #define Rectangle _Rectangle
68ccd4a63SDavid du Colombier
78ccd4a63SDavid du Colombier #include "u.h"
88ccd4a63SDavid du Colombier #include "lib.h"
98ccd4a63SDavid du Colombier #include "kern/dat.h"
108ccd4a63SDavid du Colombier #include "kern/fns.h"
118ccd4a63SDavid du Colombier #include "error.h"
128ccd4a63SDavid du Colombier #include "user.h"
138ccd4a63SDavid du Colombier #include <draw.h>
148ccd4a63SDavid du Colombier #include <memdraw.h>
158ccd4a63SDavid du Colombier #include "screen.h"
168ccd4a63SDavid du Colombier #include "keyboard.h"
178ccd4a63SDavid du Colombier
188ccd4a63SDavid du Colombier Memimage *gscreen;
198ccd4a63SDavid du Colombier Screeninfo screen;
208ccd4a63SDavid du Colombier
218ccd4a63SDavid du Colombier extern int mousequeue;
228ccd4a63SDavid du Colombier static int depth;
238ccd4a63SDavid du Colombier
248ccd4a63SDavid du Colombier static HINSTANCE inst;
258ccd4a63SDavid du Colombier static HWND window;
268ccd4a63SDavid du Colombier static HPALETTE palette;
278ccd4a63SDavid du Colombier static LOGPALETTE *logpal;
288ccd4a63SDavid du Colombier static Lock gdilock;
298ccd4a63SDavid du Colombier static BITMAPINFO *bmi;
308ccd4a63SDavid du Colombier static HCURSOR hcursor;
318ccd4a63SDavid du Colombier
328ccd4a63SDavid du Colombier static void winproc(void *);
338ccd4a63SDavid du Colombier static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
348ccd4a63SDavid du Colombier static void paletteinit(void);
358ccd4a63SDavid du Colombier static void bmiinit(void);
368ccd4a63SDavid du Colombier
378ccd4a63SDavid du Colombier static int readybit;
388ccd4a63SDavid du Colombier static Rendez rend;
398ccd4a63SDavid du Colombier
408ccd4a63SDavid du Colombier Point ZP;
418ccd4a63SDavid du Colombier
428ccd4a63SDavid du Colombier static int
isready(void * a)438ccd4a63SDavid du Colombier isready(void*a)
448ccd4a63SDavid du Colombier {
458ccd4a63SDavid du Colombier return readybit;
468ccd4a63SDavid du Colombier }
478ccd4a63SDavid du Colombier
488ccd4a63SDavid du Colombier void
screeninit(void)498ccd4a63SDavid du Colombier screeninit(void)
508ccd4a63SDavid du Colombier {
518ccd4a63SDavid du Colombier int fmt;
528ccd4a63SDavid du Colombier int dx, dy;
538ccd4a63SDavid du Colombier
548ccd4a63SDavid du Colombier memimageinit();
558ccd4a63SDavid du Colombier if(depth == 0)
568ccd4a63SDavid du Colombier depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL);
578ccd4a63SDavid du Colombier switch(depth){
588ccd4a63SDavid du Colombier case 32:
598ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS;
608ccd4a63SDavid du Colombier screen.depth = 32;
618ccd4a63SDavid du Colombier fmt = XRGB32;
628ccd4a63SDavid du Colombier break;
638ccd4a63SDavid du Colombier case 24:
648ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS;
658ccd4a63SDavid du Colombier screen.depth = 24;
668ccd4a63SDavid du Colombier fmt = RGB24;
678ccd4a63SDavid du Colombier break;
688ccd4a63SDavid du Colombier case 16:
698ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS;
708ccd4a63SDavid du Colombier screen.depth = 16;
718ccd4a63SDavid du Colombier fmt = RGB15; /* [sic] */
728ccd4a63SDavid du Colombier break;
738ccd4a63SDavid du Colombier case 8:
748ccd4a63SDavid du Colombier default:
758ccd4a63SDavid du Colombier screen.dibtype = DIB_PAL_COLORS;
768ccd4a63SDavid du Colombier screen.depth = 8;
778ccd4a63SDavid du Colombier depth = 8;
788ccd4a63SDavid du Colombier fmt = CMAP8;
798ccd4a63SDavid du Colombier break;
808ccd4a63SDavid du Colombier }
818ccd4a63SDavid du Colombier dx = GetDeviceCaps(GetDC(NULL), HORZRES);
828ccd4a63SDavid du Colombier dy = GetDeviceCaps(GetDC(NULL), VERTRES);
838ccd4a63SDavid du Colombier
848ccd4a63SDavid du Colombier gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);
858ccd4a63SDavid du Colombier kproc("winscreen", winproc, 0);
868ccd4a63SDavid du Colombier ksleep(&rend, isready, 0);
878ccd4a63SDavid du Colombier }
888ccd4a63SDavid du Colombier
898ccd4a63SDavid du Colombier uchar*
attachscreen(Rectangle * r,ulong * chan,int * depth,int * width,int * softscreen,void ** X)908ccd4a63SDavid du Colombier attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen, void **X)
918ccd4a63SDavid du Colombier {
928ccd4a63SDavid du Colombier *r = gscreen->r;
938ccd4a63SDavid du Colombier *chan = gscreen->chan;
948ccd4a63SDavid du Colombier *depth = gscreen->depth;
958ccd4a63SDavid du Colombier *width = gscreen->width;
968ccd4a63SDavid du Colombier *softscreen = 1;
978ccd4a63SDavid du Colombier
988ccd4a63SDavid du Colombier return gscreen->data->bdata;
998ccd4a63SDavid du Colombier }
1008ccd4a63SDavid du Colombier
1018ccd4a63SDavid du Colombier void
flushmemscreen(Rectangle r)1028ccd4a63SDavid du Colombier flushmemscreen(Rectangle r)
1038ccd4a63SDavid du Colombier {
1048ccd4a63SDavid du Colombier screenload(r, gscreen->depth, byteaddr(gscreen, ZP), ZP,
1058ccd4a63SDavid du Colombier gscreen->width*sizeof(ulong));
1068ccd4a63SDavid du Colombier // Sleep(100);
1078ccd4a63SDavid du Colombier }
1088ccd4a63SDavid du Colombier
1098ccd4a63SDavid du Colombier void
screenload(Rectangle r,int depth,uchar * p,Point pt,int step)1108ccd4a63SDavid du Colombier screenload(Rectangle r, int depth, uchar *p, Point pt, int step)
1118ccd4a63SDavid du Colombier {
1128ccd4a63SDavid du Colombier int dx, dy, delx;
1138ccd4a63SDavid du Colombier HDC hdc;
1148ccd4a63SDavid du Colombier RECT winr;
1158ccd4a63SDavid du Colombier
1168ccd4a63SDavid du Colombier if(depth != gscreen->depth)
1178ccd4a63SDavid du Colombier panic("screenload: bad ldepth");
1188ccd4a63SDavid du Colombier
1198ccd4a63SDavid du Colombier /*
1208ccd4a63SDavid du Colombier * Sometimes we do get rectangles that are off the
1218ccd4a63SDavid du Colombier * screen to the negative axes, for example, when
1228ccd4a63SDavid du Colombier * dragging around a window border in a Move operation.
1238ccd4a63SDavid du Colombier */
1248ccd4a63SDavid du Colombier if(rectclip(&r, gscreen->r) == 0)
1258ccd4a63SDavid du Colombier return;
1268ccd4a63SDavid du Colombier
1278ccd4a63SDavid du Colombier if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0)
1288ccd4a63SDavid du Colombier panic("screenload: bad params %d %d %ux", step, pt.x, p);
1298ccd4a63SDavid du Colombier dx = r.max.x - r.min.x;
1308ccd4a63SDavid du Colombier dy = r.max.y - r.min.y;
1318ccd4a63SDavid du Colombier
1328ccd4a63SDavid du Colombier if(dx <= 0 || dy <= 0)
1338ccd4a63SDavid du Colombier return;
1348ccd4a63SDavid du Colombier
1358ccd4a63SDavid du Colombier if(depth == 24)
1368ccd4a63SDavid du Colombier delx = r.min.x % 4;
1378ccd4a63SDavid du Colombier else
1388ccd4a63SDavid du Colombier delx = r.min.x & (31/depth);
1398ccd4a63SDavid du Colombier
1408ccd4a63SDavid du Colombier p += (r.min.y-pt.y)*step;
1418ccd4a63SDavid du Colombier p += ((r.min.x-delx-pt.x)*depth)>>3;
1428ccd4a63SDavid du Colombier
1438ccd4a63SDavid du Colombier if(GetWindowRect(window, &winr)==0)
1448ccd4a63SDavid du Colombier return;
1458ccd4a63SDavid du Colombier if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0)
1468ccd4a63SDavid du Colombier return;
1478ccd4a63SDavid du Colombier
1488ccd4a63SDavid du Colombier lock(&gdilock);
1498ccd4a63SDavid du Colombier
1508ccd4a63SDavid du Colombier hdc = GetDC(window);
1518ccd4a63SDavid du Colombier SelectPalette(hdc, palette, 0);
1528ccd4a63SDavid du Colombier RealizePalette(hdc);
1538ccd4a63SDavid du Colombier
1548ccd4a63SDavid du Colombier //FillRect(hdc,(void*)&r, GetStockObject(BLACK_BRUSH));
1558ccd4a63SDavid du Colombier //GdiFlush();
1568ccd4a63SDavid du Colombier //Sleep(100);
1578ccd4a63SDavid du Colombier
1588ccd4a63SDavid du Colombier bmi->bmiHeader.biWidth = (step*8)/depth;
1598ccd4a63SDavid du Colombier bmi->bmiHeader.biHeight = -dy; /* - => origin upper left */
1608ccd4a63SDavid du Colombier
1618ccd4a63SDavid du Colombier StretchDIBits(hdc, r.min.x, r.min.y, dx, dy,
1628ccd4a63SDavid du Colombier delx, 0, dx, dy, p, bmi, screen.dibtype, SRCCOPY);
1638ccd4a63SDavid du Colombier
1648ccd4a63SDavid du Colombier ReleaseDC(window, hdc);
1658ccd4a63SDavid du Colombier
1668ccd4a63SDavid du Colombier GdiFlush();
1678ccd4a63SDavid du Colombier
1688ccd4a63SDavid du Colombier unlock(&gdilock);
1698ccd4a63SDavid du Colombier }
1708ccd4a63SDavid du Colombier
1718ccd4a63SDavid du Colombier static void
winproc(void * a)1728ccd4a63SDavid du Colombier winproc(void *a)
1738ccd4a63SDavid du Colombier {
1748ccd4a63SDavid du Colombier WNDCLASS wc;
1758ccd4a63SDavid du Colombier MSG msg;
1768ccd4a63SDavid du Colombier
1778ccd4a63SDavid du Colombier inst = GetModuleHandle(NULL);
1788ccd4a63SDavid du Colombier
1798ccd4a63SDavid du Colombier paletteinit();
1808ccd4a63SDavid du Colombier bmiinit();
1818ccd4a63SDavid du Colombier terminit();
1828ccd4a63SDavid du Colombier
1838ccd4a63SDavid du Colombier wc.style = 0;
1848ccd4a63SDavid du Colombier wc.lpfnWndProc = WindowProc;
1858ccd4a63SDavid du Colombier wc.cbClsExtra = 0;
1868ccd4a63SDavid du Colombier wc.cbWndExtra = 0;
1878ccd4a63SDavid du Colombier wc.hInstance = inst;
1888ccd4a63SDavid du Colombier wc.hIcon = LoadIcon(inst, NULL);
1898ccd4a63SDavid du Colombier wc.hCursor = LoadCursor(NULL, IDC_ARROW);
1908ccd4a63SDavid du Colombier wc.hbrBackground = GetStockObject(WHITE_BRUSH);
1918ccd4a63SDavid du Colombier wc.lpszMenuName = 0;
192*35393782SDavid du Colombier wc.lpszClassName = L"9pmgraphics";
1938ccd4a63SDavid du Colombier RegisterClass(&wc);
1948ccd4a63SDavid du Colombier
1958ccd4a63SDavid du Colombier window = CreateWindowEx(
1968ccd4a63SDavid du Colombier 0, /* extended style */
197*35393782SDavid du Colombier L"9pmgraphics", /* class */
198*35393782SDavid du Colombier L"drawterm screen", /* caption */
1998ccd4a63SDavid du Colombier WS_OVERLAPPEDWINDOW, /* style */
2008ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. x pos */
2018ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. y pos */
2028ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. x size */
2038ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. y size */
2048ccd4a63SDavid du Colombier NULL, /* parent window (actually owner window for overlapped)*/
2058ccd4a63SDavid du Colombier NULL, /* menu handle */
2068ccd4a63SDavid du Colombier inst, /* program handle */
2078ccd4a63SDavid du Colombier NULL /* create parms */
2088ccd4a63SDavid du Colombier );
2098ccd4a63SDavid du Colombier
2108ccd4a63SDavid du Colombier if(window == nil)
2118ccd4a63SDavid du Colombier panic("can't make window\n");
2128ccd4a63SDavid du Colombier
2138ccd4a63SDavid du Colombier ShowWindow(window, SW_SHOWDEFAULT);
2148ccd4a63SDavid du Colombier UpdateWindow(window);
2158ccd4a63SDavid du Colombier
2168ccd4a63SDavid du Colombier readybit = 1;
2178ccd4a63SDavid du Colombier wakeup(&rend);
2188ccd4a63SDavid du Colombier
2198ccd4a63SDavid du Colombier screen.reshaped = 0;
2208ccd4a63SDavid du Colombier
2218ccd4a63SDavid du Colombier while(GetMessage(&msg, NULL, 0, 0)) {
2228ccd4a63SDavid du Colombier TranslateMessage(&msg);
2238ccd4a63SDavid du Colombier DispatchMessage(&msg);
2248ccd4a63SDavid du Colombier }
2258ccd4a63SDavid du Colombier // MessageBox(0, "winproc", "exits", MB_OK);
2268ccd4a63SDavid du Colombier ExitProcess(0);
2278ccd4a63SDavid du Colombier }
2288ccd4a63SDavid du Colombier
2298ccd4a63SDavid du Colombier int
col(int v,int n)2308ccd4a63SDavid du Colombier col(int v, int n)
2318ccd4a63SDavid du Colombier {
2328ccd4a63SDavid du Colombier int i, c;
2338ccd4a63SDavid du Colombier
2348ccd4a63SDavid du Colombier c = 0;
2358ccd4a63SDavid du Colombier for(i = 0; i < 8; i += n)
2368ccd4a63SDavid du Colombier c |= v << (16-(n+i));
2378ccd4a63SDavid du Colombier return c >> 8;
2388ccd4a63SDavid du Colombier }
2398ccd4a63SDavid du Colombier
2408ccd4a63SDavid du Colombier
2418ccd4a63SDavid du Colombier void
paletteinit(void)2428ccd4a63SDavid du Colombier paletteinit(void)
2438ccd4a63SDavid du Colombier {
2448ccd4a63SDavid du Colombier PALETTEENTRY *pal;
2458ccd4a63SDavid du Colombier int r, g, b, cr, cg, cb, v;
2468ccd4a63SDavid du Colombier int num, den;
2478ccd4a63SDavid du Colombier int i, j;
2488ccd4a63SDavid du Colombier
2498ccd4a63SDavid du Colombier logpal = mallocz(sizeof(LOGPALETTE) + 256*sizeof(PALETTEENTRY), 1);
2508ccd4a63SDavid du Colombier if(logpal == nil)
2518ccd4a63SDavid du Colombier panic("out of memory");
2528ccd4a63SDavid du Colombier logpal->palVersion = 0x300;
2538ccd4a63SDavid du Colombier logpal->palNumEntries = 256;
2548ccd4a63SDavid du Colombier pal = logpal->palPalEntry;
2558ccd4a63SDavid du Colombier
2568ccd4a63SDavid du Colombier for(r=0,i=0; r<4; r++) {
2578ccd4a63SDavid du Colombier for(v=0; v<4; v++,i+=16){
2588ccd4a63SDavid du Colombier for(g=0,j=v-r; g<4; g++) {
2598ccd4a63SDavid du Colombier for(b=0; b<4; b++,j++){
2608ccd4a63SDavid du Colombier den=r;
2618ccd4a63SDavid du Colombier if(g>den)
2628ccd4a63SDavid du Colombier den=g;
2638ccd4a63SDavid du Colombier if(b>den)
2648ccd4a63SDavid du Colombier den=b;
2658ccd4a63SDavid du Colombier /* divide check -- pick grey shades */
2668ccd4a63SDavid du Colombier if(den==0)
2678ccd4a63SDavid du Colombier cr=cg=cb=v*17;
2688ccd4a63SDavid du Colombier else{
2698ccd4a63SDavid du Colombier num=17*(4*den+v);
2708ccd4a63SDavid du Colombier cr=r*num/den;
2718ccd4a63SDavid du Colombier cg=g*num/den;
2728ccd4a63SDavid du Colombier cb=b*num/den;
2738ccd4a63SDavid du Colombier }
2748ccd4a63SDavid du Colombier pal[i+(j&15)].peRed = cr;
2758ccd4a63SDavid du Colombier pal[i+(j&15)].peGreen = cg;
2768ccd4a63SDavid du Colombier pal[i+(j&15)].peBlue = cb;
2778ccd4a63SDavid du Colombier pal[i+(j&15)].peFlags = 0;
2788ccd4a63SDavid du Colombier }
2798ccd4a63SDavid du Colombier }
2808ccd4a63SDavid du Colombier }
2818ccd4a63SDavid du Colombier }
2828ccd4a63SDavid du Colombier palette = CreatePalette(logpal);
2838ccd4a63SDavid du Colombier }
2848ccd4a63SDavid du Colombier
2858ccd4a63SDavid du Colombier
2868ccd4a63SDavid du Colombier void
getcolor(ulong i,ulong * r,ulong * g,ulong * b)2878ccd4a63SDavid du Colombier getcolor(ulong i, ulong *r, ulong *g, ulong *b)
2888ccd4a63SDavid du Colombier {
2898ccd4a63SDavid du Colombier PALETTEENTRY *pal;
2908ccd4a63SDavid du Colombier
2918ccd4a63SDavid du Colombier pal = logpal->palPalEntry;
2928ccd4a63SDavid du Colombier *r = pal[i].peRed;
2938ccd4a63SDavid du Colombier *g = pal[i].peGreen;
2948ccd4a63SDavid du Colombier *b = pal[i].peBlue;
2958ccd4a63SDavid du Colombier }
2968ccd4a63SDavid du Colombier
2978ccd4a63SDavid du Colombier void
bmiinit(void)2988ccd4a63SDavid du Colombier bmiinit(void)
2998ccd4a63SDavid du Colombier {
3008ccd4a63SDavid du Colombier ushort *p;
3018ccd4a63SDavid du Colombier int i;
3028ccd4a63SDavid du Colombier
3038ccd4a63SDavid du Colombier bmi = mallocz(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD), 1);
3048ccd4a63SDavid du Colombier if(bmi == 0)
3058ccd4a63SDavid du Colombier panic("out of memory");
3068ccd4a63SDavid du Colombier bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
3078ccd4a63SDavid du Colombier bmi->bmiHeader.biWidth = 0;
3088ccd4a63SDavid du Colombier bmi->bmiHeader.biHeight = 0; /* - => origin upper left */
3098ccd4a63SDavid du Colombier bmi->bmiHeader.biPlanes = 1;
3108ccd4a63SDavid du Colombier bmi->bmiHeader.biBitCount = depth;
3118ccd4a63SDavid du Colombier bmi->bmiHeader.biCompression = BI_RGB;
3128ccd4a63SDavid du Colombier bmi->bmiHeader.biSizeImage = 0;
3138ccd4a63SDavid du Colombier bmi->bmiHeader.biXPelsPerMeter = 0;
3148ccd4a63SDavid du Colombier bmi->bmiHeader.biYPelsPerMeter = 0;
3158ccd4a63SDavid du Colombier bmi->bmiHeader.biClrUsed = 0;
3168ccd4a63SDavid du Colombier bmi->bmiHeader.biClrImportant = 0; /* number of important colors: 0 means all */
3178ccd4a63SDavid du Colombier
3188ccd4a63SDavid du Colombier p = (ushort*)bmi->bmiColors;
3198ccd4a63SDavid du Colombier for(i = 0; i < 256; i++)
3208ccd4a63SDavid du Colombier p[i] = i;
3218ccd4a63SDavid du Colombier }
3228ccd4a63SDavid du Colombier
3238ccd4a63SDavid du Colombier LRESULT CALLBACK
WindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)3248ccd4a63SDavid du Colombier WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
3258ccd4a63SDavid du Colombier {
3268ccd4a63SDavid du Colombier PAINTSTRUCT paint;
3278ccd4a63SDavid du Colombier HDC hdc;
3288ccd4a63SDavid du Colombier LONG x, y, b;
3298ccd4a63SDavid du Colombier int i;
3308ccd4a63SDavid du Colombier Rectangle r;
3318ccd4a63SDavid du Colombier
3328ccd4a63SDavid du Colombier switch(msg) {
3338ccd4a63SDavid du Colombier case WM_CREATE:
3348ccd4a63SDavid du Colombier break;
3358ccd4a63SDavid du Colombier case WM_SETCURSOR:
3368ccd4a63SDavid du Colombier /* User set */
3378ccd4a63SDavid du Colombier if(hcursor != NULL) {
3388ccd4a63SDavid du Colombier SetCursor(hcursor);
3398ccd4a63SDavid du Colombier return 1;
3408ccd4a63SDavid du Colombier }
3418ccd4a63SDavid du Colombier return DefWindowProc(hwnd, msg, wparam, lparam);
342*35393782SDavid du Colombier case WM_MOUSEWHEEL:
343*35393782SDavid du Colombier if ((int)(wparam & 0xFFFF0000)>0)
344*35393782SDavid du Colombier b|=8;
345*35393782SDavid du Colombier else
346*35393782SDavid du Colombier b|=16;
3478ccd4a63SDavid du Colombier case WM_MOUSEMOVE:
3488ccd4a63SDavid du Colombier case WM_LBUTTONUP:
3498ccd4a63SDavid du Colombier case WM_MBUTTONUP:
3508ccd4a63SDavid du Colombier case WM_RBUTTONUP:
3518ccd4a63SDavid du Colombier case WM_LBUTTONDOWN:
3528ccd4a63SDavid du Colombier case WM_MBUTTONDOWN:
3538ccd4a63SDavid du Colombier case WM_RBUTTONDOWN:
3548ccd4a63SDavid du Colombier x = LOWORD(lparam);
3558ccd4a63SDavid du Colombier y = HIWORD(lparam);
3568ccd4a63SDavid du Colombier b = 0;
3578ccd4a63SDavid du Colombier if(wparam & MK_LBUTTON)
3588ccd4a63SDavid du Colombier b = 1;
3598ccd4a63SDavid du Colombier if(wparam & MK_MBUTTON)
3608ccd4a63SDavid du Colombier b |= 2;
3618ccd4a63SDavid du Colombier if(wparam & MK_RBUTTON) {
3628ccd4a63SDavid du Colombier if(wparam & MK_SHIFT)
3638ccd4a63SDavid du Colombier b |= 2;
3648ccd4a63SDavid du Colombier else
3658ccd4a63SDavid du Colombier b |= 4;
3668ccd4a63SDavid du Colombier }
3678ccd4a63SDavid du Colombier lock(&mouse.lk);
3688ccd4a63SDavid du Colombier i = mouse.wi;
3698ccd4a63SDavid du Colombier if(mousequeue) {
3708ccd4a63SDavid du Colombier if(i == mouse.ri || mouse.lastb != b || mouse.trans) {
3718ccd4a63SDavid du Colombier mouse.wi = (i+1)%Mousequeue;
3728ccd4a63SDavid du Colombier if(mouse.wi == mouse.ri)
3738ccd4a63SDavid du Colombier mouse.ri = (mouse.ri+1)%Mousequeue;
3748ccd4a63SDavid du Colombier mouse.trans = mouse.lastb != b;
3758ccd4a63SDavid du Colombier } else {
3768ccd4a63SDavid du Colombier i = (i-1+Mousequeue)%Mousequeue;
3778ccd4a63SDavid du Colombier }
3788ccd4a63SDavid du Colombier } else {
3798ccd4a63SDavid du Colombier mouse.wi = (i+1)%Mousequeue;
3808ccd4a63SDavid du Colombier mouse.ri = i;
3818ccd4a63SDavid du Colombier }
3828ccd4a63SDavid du Colombier mouse.queue[i].xy.x = x;
3838ccd4a63SDavid du Colombier mouse.queue[i].xy.y = y;
3848ccd4a63SDavid du Colombier mouse.queue[i].buttons = b;
3858ccd4a63SDavid du Colombier mouse.queue[i].msec = ticks();
3868ccd4a63SDavid du Colombier mouse.lastb = b;
3878ccd4a63SDavid du Colombier unlock(&mouse.lk);
3888ccd4a63SDavid du Colombier wakeup(&mouse.r);
3898ccd4a63SDavid du Colombier break;
3908ccd4a63SDavid du Colombier
3918ccd4a63SDavid du Colombier case WM_CHAR:
3928ccd4a63SDavid du Colombier /* repeat count is lparam & 0xf */
3938ccd4a63SDavid du Colombier switch(wparam){
3948ccd4a63SDavid du Colombier case '\n':
3958ccd4a63SDavid du Colombier wparam = '\r';
3968ccd4a63SDavid du Colombier break;
3978ccd4a63SDavid du Colombier case '\r':
3988ccd4a63SDavid du Colombier wparam = '\n';
3998ccd4a63SDavid du Colombier break;
4008ccd4a63SDavid du Colombier }
4018ccd4a63SDavid du Colombier kbdputc(kbdq, wparam);
4028ccd4a63SDavid du Colombier break;
4038ccd4a63SDavid du Colombier
4048ccd4a63SDavid du Colombier case WM_SYSKEYUP:
4058ccd4a63SDavid du Colombier break;
4068ccd4a63SDavid du Colombier case WM_SYSKEYDOWN:
4078ccd4a63SDavid du Colombier case WM_KEYDOWN:
4088ccd4a63SDavid du Colombier switch(wparam) {
4098ccd4a63SDavid du Colombier case VK_MENU:
4108ccd4a63SDavid du Colombier kbdputc(kbdq, Kalt);
4118ccd4a63SDavid du Colombier break;
4128ccd4a63SDavid du Colombier case VK_INSERT:
4138ccd4a63SDavid du Colombier kbdputc(kbdq, Kins);
4148ccd4a63SDavid du Colombier break;
4158ccd4a63SDavid du Colombier case VK_DELETE:
4168ccd4a63SDavid du Colombier // kbdputc(kbdq, Kdel);
4178ccd4a63SDavid du Colombier kbdputc(kbdq, 0x7f); // should have Kdel in keyboard.h
4188ccd4a63SDavid du Colombier break;
4198ccd4a63SDavid du Colombier case VK_UP:
4208ccd4a63SDavid du Colombier kbdputc(kbdq, Kup);
4218ccd4a63SDavid du Colombier break;
4228ccd4a63SDavid du Colombier case VK_DOWN:
4238ccd4a63SDavid du Colombier kbdputc(kbdq, Kdown);
4248ccd4a63SDavid du Colombier break;
4258ccd4a63SDavid du Colombier case VK_LEFT:
4268ccd4a63SDavid du Colombier kbdputc(kbdq, Kleft);
4278ccd4a63SDavid du Colombier break;
4288ccd4a63SDavid du Colombier case VK_RIGHT:
4298ccd4a63SDavid du Colombier kbdputc(kbdq, Kright);
4308ccd4a63SDavid du Colombier break;
4318ccd4a63SDavid du Colombier }
4328ccd4a63SDavid du Colombier break;
4338ccd4a63SDavid du Colombier
4348ccd4a63SDavid du Colombier case WM_CLOSE:
4358ccd4a63SDavid du Colombier DestroyWindow(hwnd);
4368ccd4a63SDavid du Colombier break;
4378ccd4a63SDavid du Colombier
4388ccd4a63SDavid du Colombier case WM_DESTROY:
4398ccd4a63SDavid du Colombier PostQuitMessage(0);
4408ccd4a63SDavid du Colombier break;
4418ccd4a63SDavid du Colombier
4428ccd4a63SDavid du Colombier case WM_PALETTECHANGED:
4438ccd4a63SDavid du Colombier if((HWND)wparam == hwnd)
4448ccd4a63SDavid du Colombier break;
4458ccd4a63SDavid du Colombier /* fall through */
4468ccd4a63SDavid du Colombier case WM_QUERYNEWPALETTE:
4478ccd4a63SDavid du Colombier hdc = GetDC(hwnd);
4488ccd4a63SDavid du Colombier SelectPalette(hdc, palette, 0);
4498ccd4a63SDavid du Colombier if(RealizePalette(hdc) != 0)
4508ccd4a63SDavid du Colombier InvalidateRect(hwnd, nil, 0);
4518ccd4a63SDavid du Colombier ReleaseDC(hwnd, hdc);
4528ccd4a63SDavid du Colombier break;
4538ccd4a63SDavid du Colombier
4548ccd4a63SDavid du Colombier case WM_PAINT:
4558ccd4a63SDavid du Colombier hdc = BeginPaint(hwnd, &paint);
4568ccd4a63SDavid du Colombier r.min.x = paint.rcPaint.left;
4578ccd4a63SDavid du Colombier r.min.y = paint.rcPaint.top;
4588ccd4a63SDavid du Colombier r.max.x = paint.rcPaint.right;
4598ccd4a63SDavid du Colombier r.max.y = paint.rcPaint.bottom;
4608ccd4a63SDavid du Colombier flushmemscreen(r);
4618ccd4a63SDavid du Colombier EndPaint(hwnd, &paint);
4628ccd4a63SDavid du Colombier break;
4638ccd4a63SDavid du Colombier case WM_COMMAND:
4648ccd4a63SDavid du Colombier case WM_SETFOCUS:
4658ccd4a63SDavid du Colombier case WM_DEVMODECHANGE:
4668ccd4a63SDavid du Colombier case WM_WININICHANGE:
4678ccd4a63SDavid du Colombier case WM_INITMENU:
4688ccd4a63SDavid du Colombier default:
4698ccd4a63SDavid du Colombier return DefWindowProc(hwnd, msg, wparam, lparam);
4708ccd4a63SDavid du Colombier }
4718ccd4a63SDavid du Colombier return 0;
4728ccd4a63SDavid du Colombier }
4738ccd4a63SDavid du Colombier
4748ccd4a63SDavid du Colombier void
mouseset(Point xy)4758ccd4a63SDavid du Colombier mouseset(Point xy)
4768ccd4a63SDavid du Colombier {
4778ccd4a63SDavid du Colombier POINT pt;
4788ccd4a63SDavid du Colombier
4798ccd4a63SDavid du Colombier pt.x = xy.x;
4808ccd4a63SDavid du Colombier pt.y = xy.y;
4818ccd4a63SDavid du Colombier MapWindowPoints(window, 0, &pt, 1);
4828ccd4a63SDavid du Colombier SetCursorPos(pt.x, pt.y);
4838ccd4a63SDavid du Colombier }
4848ccd4a63SDavid du Colombier
4858ccd4a63SDavid du Colombier void
setcursor(void)4868ccd4a63SDavid du Colombier setcursor(void)
4878ccd4a63SDavid du Colombier {
4888ccd4a63SDavid du Colombier HCURSOR nh;
4898ccd4a63SDavid du Colombier int x, y, h, w;
4908ccd4a63SDavid du Colombier uchar *sp, *cp;
4918ccd4a63SDavid du Colombier uchar *and, *xor;
4928ccd4a63SDavid du Colombier
4938ccd4a63SDavid du Colombier h = GetSystemMetrics(SM_CYCURSOR);
4948ccd4a63SDavid du Colombier w = (GetSystemMetrics(SM_CXCURSOR)+7)/8;
4958ccd4a63SDavid du Colombier
4968ccd4a63SDavid du Colombier and = mallocz(h*w, 1);
4978ccd4a63SDavid du Colombier memset(and, 0xff, h*w);
4988ccd4a63SDavid du Colombier xor = mallocz(h*w, 1);
4998ccd4a63SDavid du Colombier
5008ccd4a63SDavid du Colombier lock(&cursor.lk);
5018ccd4a63SDavid du Colombier for(y=0,sp=cursor.set,cp=cursor.clr; y<16; y++) {
5028ccd4a63SDavid du Colombier for(x=0; x<2; x++) {
5038ccd4a63SDavid du Colombier and[y*w+x] = ~(*sp|*cp);
5048ccd4a63SDavid du Colombier xor[y*w+x] = ~*sp & *cp;
5058ccd4a63SDavid du Colombier cp++;
5068ccd4a63SDavid du Colombier sp++;
5078ccd4a63SDavid du Colombier }
5088ccd4a63SDavid du Colombier }
5098ccd4a63SDavid du Colombier nh = CreateCursor(inst, -cursor.offset.x, -cursor.offset.y,
5108ccd4a63SDavid du Colombier GetSystemMetrics(SM_CXCURSOR), h,
5118ccd4a63SDavid du Colombier and, xor);
5128ccd4a63SDavid du Colombier if(nh != NULL) {
5138ccd4a63SDavid du Colombier SetCursor(nh);
5148ccd4a63SDavid du Colombier if(hcursor != NULL)
5158ccd4a63SDavid du Colombier DestroyCursor(hcursor);
5168ccd4a63SDavid du Colombier hcursor = nh;
5178ccd4a63SDavid du Colombier }
5188ccd4a63SDavid du Colombier unlock(&cursor.lk);
5198ccd4a63SDavid du Colombier
5208ccd4a63SDavid du Colombier free(and);
5218ccd4a63SDavid du Colombier free(xor);
5228ccd4a63SDavid du Colombier
5238ccd4a63SDavid du Colombier PostMessage(window, WM_SETCURSOR, (int)window, 0);
5248ccd4a63SDavid du Colombier }
5258ccd4a63SDavid du Colombier
5268ccd4a63SDavid du Colombier void
cursorarrow(void)5278ccd4a63SDavid du Colombier cursorarrow(void)
5288ccd4a63SDavid du Colombier {
5298ccd4a63SDavid du Colombier if(hcursor != 0) {
5308ccd4a63SDavid du Colombier DestroyCursor(hcursor);
5318ccd4a63SDavid du Colombier hcursor = 0;
5328ccd4a63SDavid du Colombier }
5338ccd4a63SDavid du Colombier SetCursor(LoadCursor(0, IDC_ARROW));
5348ccd4a63SDavid du Colombier PostMessage(window, WM_SETCURSOR, (int)window, 0);
5358ccd4a63SDavid du Colombier }
5368ccd4a63SDavid du Colombier
5378ccd4a63SDavid du Colombier
5388ccd4a63SDavid du Colombier void
setcolor(ulong index,ulong red,ulong green,ulong blue)5398ccd4a63SDavid du Colombier setcolor(ulong index, ulong red, ulong green, ulong blue)
5408ccd4a63SDavid du Colombier {
5418ccd4a63SDavid du Colombier }
5428ccd4a63SDavid du Colombier
5438ccd4a63SDavid du Colombier
5448ccd4a63SDavid du Colombier uchar*
clipreadunicode(HANDLE h)5458ccd4a63SDavid du Colombier clipreadunicode(HANDLE h)
5468ccd4a63SDavid du Colombier {
5478ccd4a63SDavid du Colombier Rune *p;
5488ccd4a63SDavid du Colombier int n;
5498ccd4a63SDavid du Colombier uchar *q;
5508ccd4a63SDavid du Colombier
5518ccd4a63SDavid du Colombier p = GlobalLock(h);
5528ccd4a63SDavid du Colombier n = wstrutflen(p)+1;
5538ccd4a63SDavid du Colombier q = malloc(n);
5548ccd4a63SDavid du Colombier wstrtoutf(q, p, n);
5558ccd4a63SDavid du Colombier GlobalUnlock(h);
5568ccd4a63SDavid du Colombier
5578ccd4a63SDavid du Colombier return q;
5588ccd4a63SDavid du Colombier }
5598ccd4a63SDavid du Colombier
5608ccd4a63SDavid du Colombier uchar *
clipreadutf(HANDLE h)5618ccd4a63SDavid du Colombier clipreadutf(HANDLE h)
5628ccd4a63SDavid du Colombier {
5638ccd4a63SDavid du Colombier uchar *p;
5648ccd4a63SDavid du Colombier
5658ccd4a63SDavid du Colombier p = GlobalLock(h);
5668ccd4a63SDavid du Colombier p = strdup(p);
5678ccd4a63SDavid du Colombier GlobalUnlock(h);
5688ccd4a63SDavid du Colombier
5698ccd4a63SDavid du Colombier return p;
5708ccd4a63SDavid du Colombier }
5718ccd4a63SDavid du Colombier
5728ccd4a63SDavid du Colombier char*
clipread(void)5738ccd4a63SDavid du Colombier clipread(void)
5748ccd4a63SDavid du Colombier {
5758ccd4a63SDavid du Colombier HANDLE h;
5768ccd4a63SDavid du Colombier uchar *p;
5778ccd4a63SDavid du Colombier
5788ccd4a63SDavid du Colombier if(!OpenClipboard(window)) {
5798ccd4a63SDavid du Colombier oserror();
5808ccd4a63SDavid du Colombier return strdup("");
5818ccd4a63SDavid du Colombier }
5828ccd4a63SDavid du Colombier
5838ccd4a63SDavid du Colombier if((h = GetClipboardData(CF_UNICODETEXT)))
5848ccd4a63SDavid du Colombier p = clipreadunicode(h);
5858ccd4a63SDavid du Colombier else if((h = GetClipboardData(CF_TEXT)))
5868ccd4a63SDavid du Colombier p = clipreadutf(h);
5878ccd4a63SDavid du Colombier else {
5888ccd4a63SDavid du Colombier oserror();
5898ccd4a63SDavid du Colombier p = strdup("");
5908ccd4a63SDavid du Colombier }
5918ccd4a63SDavid du Colombier
5928ccd4a63SDavid du Colombier CloseClipboard();
5938ccd4a63SDavid du Colombier return p;
5948ccd4a63SDavid du Colombier }
5958ccd4a63SDavid du Colombier
5968ccd4a63SDavid du Colombier int
clipwrite(char * buf)5978ccd4a63SDavid du Colombier clipwrite(char *buf)
5988ccd4a63SDavid du Colombier {
5998ccd4a63SDavid du Colombier HANDLE h;
6008ccd4a63SDavid du Colombier char *p, *e;
6018ccd4a63SDavid du Colombier Rune *rp;
6028ccd4a63SDavid du Colombier int n = strlen(buf);
6038ccd4a63SDavid du Colombier
6048ccd4a63SDavid du Colombier if(!OpenClipboard(window)) {
6058ccd4a63SDavid du Colombier oserror();
6068ccd4a63SDavid du Colombier return -1;
6078ccd4a63SDavid du Colombier }
6088ccd4a63SDavid du Colombier
6098ccd4a63SDavid du Colombier if(!EmptyClipboard()) {
6108ccd4a63SDavid du Colombier oserror();
6118ccd4a63SDavid du Colombier CloseClipboard();
6128ccd4a63SDavid du Colombier return -1;
6138ccd4a63SDavid du Colombier }
6148ccd4a63SDavid du Colombier
6158ccd4a63SDavid du Colombier h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, (n+1)*sizeof(Rune));
6168ccd4a63SDavid du Colombier if(h == NULL)
6178ccd4a63SDavid du Colombier panic("out of memory");
6188ccd4a63SDavid du Colombier rp = GlobalLock(h);
6198ccd4a63SDavid du Colombier p = buf;
6208ccd4a63SDavid du Colombier e = p+n;
6218ccd4a63SDavid du Colombier while(p<e)
6228ccd4a63SDavid du Colombier p += chartorune(rp++, p);
6238ccd4a63SDavid du Colombier *rp = 0;
6248ccd4a63SDavid du Colombier GlobalUnlock(h);
6258ccd4a63SDavid du Colombier
6268ccd4a63SDavid du Colombier SetClipboardData(CF_UNICODETEXT, h);
6278ccd4a63SDavid du Colombier
6288ccd4a63SDavid du Colombier h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, n+1);
6298ccd4a63SDavid du Colombier if(h == NULL)
6308ccd4a63SDavid du Colombier panic("out of memory");
6318ccd4a63SDavid du Colombier p = GlobalLock(h);
6328ccd4a63SDavid du Colombier memcpy(p, buf, n);
6338ccd4a63SDavid du Colombier p[n] = 0;
6348ccd4a63SDavid du Colombier GlobalUnlock(h);
6358ccd4a63SDavid du Colombier
6368ccd4a63SDavid du Colombier SetClipboardData(CF_TEXT, h);
6378ccd4a63SDavid du Colombier
6388ccd4a63SDavid du Colombier CloseClipboard();
6398ccd4a63SDavid du Colombier return n;
6408ccd4a63SDavid du Colombier }
6418ccd4a63SDavid du Colombier
6428ccd4a63SDavid du Colombier int
atlocalconsole(void)6438ccd4a63SDavid du Colombier atlocalconsole(void)
6448ccd4a63SDavid du Colombier {
6458ccd4a63SDavid du Colombier return 1;
6468ccd4a63SDavid du Colombier }
647