1*8ccd4a63SDavid du Colombier #include <windows.h> 2*8ccd4a63SDavid du Colombier 3*8ccd4a63SDavid du Colombier #undef Rectangle 4*8ccd4a63SDavid du Colombier #define Rectangle _Rectangle 5*8ccd4a63SDavid du Colombier 6*8ccd4a63SDavid du Colombier #include "u.h" 7*8ccd4a63SDavid du Colombier #include "lib.h" 8*8ccd4a63SDavid du Colombier #include "kern/dat.h" 9*8ccd4a63SDavid du Colombier #include "kern/fns.h" 10*8ccd4a63SDavid du Colombier #include "error.h" 11*8ccd4a63SDavid du Colombier #include "user.h" 12*8ccd4a63SDavid du Colombier #include <draw.h> 13*8ccd4a63SDavid du Colombier #include <memdraw.h> 14*8ccd4a63SDavid du Colombier #include "screen.h" 15*8ccd4a63SDavid du Colombier #include "keyboard.h" 16*8ccd4a63SDavid du Colombier 17*8ccd4a63SDavid du Colombier Memimage *gscreen; 18*8ccd4a63SDavid du Colombier Screeninfo screen; 19*8ccd4a63SDavid du Colombier 20*8ccd4a63SDavid du Colombier extern int mousequeue; 21*8ccd4a63SDavid du Colombier static int depth; 22*8ccd4a63SDavid du Colombier 23*8ccd4a63SDavid du Colombier static HINSTANCE inst; 24*8ccd4a63SDavid du Colombier static HWND window; 25*8ccd4a63SDavid du Colombier static HPALETTE palette; 26*8ccd4a63SDavid du Colombier static LOGPALETTE *logpal; 27*8ccd4a63SDavid du Colombier static Lock gdilock; 28*8ccd4a63SDavid du Colombier static BITMAPINFO *bmi; 29*8ccd4a63SDavid du Colombier static HCURSOR hcursor; 30*8ccd4a63SDavid du Colombier 31*8ccd4a63SDavid du Colombier static void winproc(void *); 32*8ccd4a63SDavid du Colombier static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 33*8ccd4a63SDavid du Colombier static void paletteinit(void); 34*8ccd4a63SDavid du Colombier static void bmiinit(void); 35*8ccd4a63SDavid du Colombier 36*8ccd4a63SDavid du Colombier static int readybit; 37*8ccd4a63SDavid du Colombier static Rendez rend; 38*8ccd4a63SDavid du Colombier 39*8ccd4a63SDavid du Colombier Point ZP; 40*8ccd4a63SDavid du Colombier 41*8ccd4a63SDavid du Colombier static int 42*8ccd4a63SDavid du Colombier isready(void*a) 43*8ccd4a63SDavid du Colombier { 44*8ccd4a63SDavid du Colombier return readybit; 45*8ccd4a63SDavid du Colombier } 46*8ccd4a63SDavid du Colombier 47*8ccd4a63SDavid du Colombier void 48*8ccd4a63SDavid du Colombier screeninit(void) 49*8ccd4a63SDavid du Colombier { 50*8ccd4a63SDavid du Colombier int fmt; 51*8ccd4a63SDavid du Colombier int dx, dy; 52*8ccd4a63SDavid du Colombier 53*8ccd4a63SDavid du Colombier memimageinit(); 54*8ccd4a63SDavid du Colombier if(depth == 0) 55*8ccd4a63SDavid du Colombier depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL); 56*8ccd4a63SDavid du Colombier switch(depth){ 57*8ccd4a63SDavid du Colombier case 32: 58*8ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS; 59*8ccd4a63SDavid du Colombier screen.depth = 32; 60*8ccd4a63SDavid du Colombier fmt = XRGB32; 61*8ccd4a63SDavid du Colombier break; 62*8ccd4a63SDavid du Colombier case 24: 63*8ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS; 64*8ccd4a63SDavid du Colombier screen.depth = 24; 65*8ccd4a63SDavid du Colombier fmt = RGB24; 66*8ccd4a63SDavid du Colombier break; 67*8ccd4a63SDavid du Colombier case 16: 68*8ccd4a63SDavid du Colombier screen.dibtype = DIB_RGB_COLORS; 69*8ccd4a63SDavid du Colombier screen.depth = 16; 70*8ccd4a63SDavid du Colombier fmt = RGB15; /* [sic] */ 71*8ccd4a63SDavid du Colombier break; 72*8ccd4a63SDavid du Colombier case 8: 73*8ccd4a63SDavid du Colombier default: 74*8ccd4a63SDavid du Colombier screen.dibtype = DIB_PAL_COLORS; 75*8ccd4a63SDavid du Colombier screen.depth = 8; 76*8ccd4a63SDavid du Colombier depth = 8; 77*8ccd4a63SDavid du Colombier fmt = CMAP8; 78*8ccd4a63SDavid du Colombier break; 79*8ccd4a63SDavid du Colombier } 80*8ccd4a63SDavid du Colombier dx = GetDeviceCaps(GetDC(NULL), HORZRES); 81*8ccd4a63SDavid du Colombier dy = GetDeviceCaps(GetDC(NULL), VERTRES); 82*8ccd4a63SDavid du Colombier 83*8ccd4a63SDavid du Colombier gscreen = allocmemimage(Rect(0,0,dx,dy), fmt); 84*8ccd4a63SDavid du Colombier kproc("winscreen", winproc, 0); 85*8ccd4a63SDavid du Colombier ksleep(&rend, isready, 0); 86*8ccd4a63SDavid du Colombier } 87*8ccd4a63SDavid du Colombier 88*8ccd4a63SDavid du Colombier uchar* 89*8ccd4a63SDavid du Colombier attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen, void **X) 90*8ccd4a63SDavid du Colombier { 91*8ccd4a63SDavid du Colombier *r = gscreen->r; 92*8ccd4a63SDavid du Colombier *chan = gscreen->chan; 93*8ccd4a63SDavid du Colombier *depth = gscreen->depth; 94*8ccd4a63SDavid du Colombier *width = gscreen->width; 95*8ccd4a63SDavid du Colombier *softscreen = 1; 96*8ccd4a63SDavid du Colombier 97*8ccd4a63SDavid du Colombier return gscreen->data->bdata; 98*8ccd4a63SDavid du Colombier } 99*8ccd4a63SDavid du Colombier 100*8ccd4a63SDavid du Colombier void 101*8ccd4a63SDavid du Colombier flushmemscreen(Rectangle r) 102*8ccd4a63SDavid du Colombier { 103*8ccd4a63SDavid du Colombier screenload(r, gscreen->depth, byteaddr(gscreen, ZP), ZP, 104*8ccd4a63SDavid du Colombier gscreen->width*sizeof(ulong)); 105*8ccd4a63SDavid du Colombier // Sleep(100); 106*8ccd4a63SDavid du Colombier } 107*8ccd4a63SDavid du Colombier 108*8ccd4a63SDavid du Colombier void 109*8ccd4a63SDavid du Colombier screenload(Rectangle r, int depth, uchar *p, Point pt, int step) 110*8ccd4a63SDavid du Colombier { 111*8ccd4a63SDavid du Colombier int dx, dy, delx; 112*8ccd4a63SDavid du Colombier HDC hdc; 113*8ccd4a63SDavid du Colombier RECT winr; 114*8ccd4a63SDavid du Colombier 115*8ccd4a63SDavid du Colombier if(depth != gscreen->depth) 116*8ccd4a63SDavid du Colombier panic("screenload: bad ldepth"); 117*8ccd4a63SDavid du Colombier 118*8ccd4a63SDavid du Colombier /* 119*8ccd4a63SDavid du Colombier * Sometimes we do get rectangles that are off the 120*8ccd4a63SDavid du Colombier * screen to the negative axes, for example, when 121*8ccd4a63SDavid du Colombier * dragging around a window border in a Move operation. 122*8ccd4a63SDavid du Colombier */ 123*8ccd4a63SDavid du Colombier if(rectclip(&r, gscreen->r) == 0) 124*8ccd4a63SDavid du Colombier return; 125*8ccd4a63SDavid du Colombier 126*8ccd4a63SDavid du Colombier if((step&3) != 0 || ((pt.x*depth)%32) != 0 || ((ulong)p&3) != 0) 127*8ccd4a63SDavid du Colombier panic("screenload: bad params %d %d %ux", step, pt.x, p); 128*8ccd4a63SDavid du Colombier dx = r.max.x - r.min.x; 129*8ccd4a63SDavid du Colombier dy = r.max.y - r.min.y; 130*8ccd4a63SDavid du Colombier 131*8ccd4a63SDavid du Colombier if(dx <= 0 || dy <= 0) 132*8ccd4a63SDavid du Colombier return; 133*8ccd4a63SDavid du Colombier 134*8ccd4a63SDavid du Colombier if(depth == 24) 135*8ccd4a63SDavid du Colombier delx = r.min.x % 4; 136*8ccd4a63SDavid du Colombier else 137*8ccd4a63SDavid du Colombier delx = r.min.x & (31/depth); 138*8ccd4a63SDavid du Colombier 139*8ccd4a63SDavid du Colombier p += (r.min.y-pt.y)*step; 140*8ccd4a63SDavid du Colombier p += ((r.min.x-delx-pt.x)*depth)>>3; 141*8ccd4a63SDavid du Colombier 142*8ccd4a63SDavid du Colombier if(GetWindowRect(window, &winr)==0) 143*8ccd4a63SDavid du Colombier return; 144*8ccd4a63SDavid du Colombier if(rectclip(&r, Rect(0, 0, winr.right-winr.left, winr.bottom-winr.top))==0) 145*8ccd4a63SDavid du Colombier return; 146*8ccd4a63SDavid du Colombier 147*8ccd4a63SDavid du Colombier lock(&gdilock); 148*8ccd4a63SDavid du Colombier 149*8ccd4a63SDavid du Colombier hdc = GetDC(window); 150*8ccd4a63SDavid du Colombier SelectPalette(hdc, palette, 0); 151*8ccd4a63SDavid du Colombier RealizePalette(hdc); 152*8ccd4a63SDavid du Colombier 153*8ccd4a63SDavid du Colombier //FillRect(hdc,(void*)&r, GetStockObject(BLACK_BRUSH)); 154*8ccd4a63SDavid du Colombier //GdiFlush(); 155*8ccd4a63SDavid du Colombier //Sleep(100); 156*8ccd4a63SDavid du Colombier 157*8ccd4a63SDavid du Colombier bmi->bmiHeader.biWidth = (step*8)/depth; 158*8ccd4a63SDavid du Colombier bmi->bmiHeader.biHeight = -dy; /* - => origin upper left */ 159*8ccd4a63SDavid du Colombier 160*8ccd4a63SDavid du Colombier StretchDIBits(hdc, r.min.x, r.min.y, dx, dy, 161*8ccd4a63SDavid du Colombier delx, 0, dx, dy, p, bmi, screen.dibtype, SRCCOPY); 162*8ccd4a63SDavid du Colombier 163*8ccd4a63SDavid du Colombier ReleaseDC(window, hdc); 164*8ccd4a63SDavid du Colombier 165*8ccd4a63SDavid du Colombier GdiFlush(); 166*8ccd4a63SDavid du Colombier 167*8ccd4a63SDavid du Colombier unlock(&gdilock); 168*8ccd4a63SDavid du Colombier } 169*8ccd4a63SDavid du Colombier 170*8ccd4a63SDavid du Colombier static void 171*8ccd4a63SDavid du Colombier winproc(void *a) 172*8ccd4a63SDavid du Colombier { 173*8ccd4a63SDavid du Colombier WNDCLASS wc; 174*8ccd4a63SDavid du Colombier MSG msg; 175*8ccd4a63SDavid du Colombier 176*8ccd4a63SDavid du Colombier inst = GetModuleHandle(NULL); 177*8ccd4a63SDavid du Colombier 178*8ccd4a63SDavid du Colombier paletteinit(); 179*8ccd4a63SDavid du Colombier bmiinit(); 180*8ccd4a63SDavid du Colombier terminit(); 181*8ccd4a63SDavid du Colombier 182*8ccd4a63SDavid du Colombier wc.style = 0; 183*8ccd4a63SDavid du Colombier wc.lpfnWndProc = WindowProc; 184*8ccd4a63SDavid du Colombier wc.cbClsExtra = 0; 185*8ccd4a63SDavid du Colombier wc.cbWndExtra = 0; 186*8ccd4a63SDavid du Colombier wc.hInstance = inst; 187*8ccd4a63SDavid du Colombier wc.hIcon = LoadIcon(inst, NULL); 188*8ccd4a63SDavid du Colombier wc.hCursor = LoadCursor(NULL, IDC_ARROW); 189*8ccd4a63SDavid du Colombier wc.hbrBackground = GetStockObject(WHITE_BRUSH); 190*8ccd4a63SDavid du Colombier wc.lpszMenuName = 0; 191*8ccd4a63SDavid du Colombier wc.lpszClassName = "9pmgraphics"; 192*8ccd4a63SDavid du Colombier RegisterClass(&wc); 193*8ccd4a63SDavid du Colombier 194*8ccd4a63SDavid du Colombier window = CreateWindowEx( 195*8ccd4a63SDavid du Colombier 0, /* extended style */ 196*8ccd4a63SDavid du Colombier "9pmgraphics", /* class */ 197*8ccd4a63SDavid du Colombier "drawterm screen", /* caption */ 198*8ccd4a63SDavid du Colombier WS_OVERLAPPEDWINDOW, /* style */ 199*8ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. x pos */ 200*8ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. y pos */ 201*8ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. x size */ 202*8ccd4a63SDavid du Colombier CW_USEDEFAULT, /* init. y size */ 203*8ccd4a63SDavid du Colombier NULL, /* parent window (actually owner window for overlapped)*/ 204*8ccd4a63SDavid du Colombier NULL, /* menu handle */ 205*8ccd4a63SDavid du Colombier inst, /* program handle */ 206*8ccd4a63SDavid du Colombier NULL /* create parms */ 207*8ccd4a63SDavid du Colombier ); 208*8ccd4a63SDavid du Colombier 209*8ccd4a63SDavid du Colombier if(window == nil) 210*8ccd4a63SDavid du Colombier panic("can't make window\n"); 211*8ccd4a63SDavid du Colombier 212*8ccd4a63SDavid du Colombier ShowWindow(window, SW_SHOWDEFAULT); 213*8ccd4a63SDavid du Colombier UpdateWindow(window); 214*8ccd4a63SDavid du Colombier 215*8ccd4a63SDavid du Colombier readybit = 1; 216*8ccd4a63SDavid du Colombier wakeup(&rend); 217*8ccd4a63SDavid du Colombier 218*8ccd4a63SDavid du Colombier screen.reshaped = 0; 219*8ccd4a63SDavid du Colombier 220*8ccd4a63SDavid du Colombier while(GetMessage(&msg, NULL, 0, 0)) { 221*8ccd4a63SDavid du Colombier TranslateMessage(&msg); 222*8ccd4a63SDavid du Colombier DispatchMessage(&msg); 223*8ccd4a63SDavid du Colombier } 224*8ccd4a63SDavid du Colombier // MessageBox(0, "winproc", "exits", MB_OK); 225*8ccd4a63SDavid du Colombier ExitProcess(0); 226*8ccd4a63SDavid du Colombier } 227*8ccd4a63SDavid du Colombier 228*8ccd4a63SDavid du Colombier int 229*8ccd4a63SDavid du Colombier col(int v, int n) 230*8ccd4a63SDavid du Colombier { 231*8ccd4a63SDavid du Colombier int i, c; 232*8ccd4a63SDavid du Colombier 233*8ccd4a63SDavid du Colombier c = 0; 234*8ccd4a63SDavid du Colombier for(i = 0; i < 8; i += n) 235*8ccd4a63SDavid du Colombier c |= v << (16-(n+i)); 236*8ccd4a63SDavid du Colombier return c >> 8; 237*8ccd4a63SDavid du Colombier } 238*8ccd4a63SDavid du Colombier 239*8ccd4a63SDavid du Colombier 240*8ccd4a63SDavid du Colombier void 241*8ccd4a63SDavid du Colombier paletteinit(void) 242*8ccd4a63SDavid du Colombier { 243*8ccd4a63SDavid du Colombier PALETTEENTRY *pal; 244*8ccd4a63SDavid du Colombier int r, g, b, cr, cg, cb, v; 245*8ccd4a63SDavid du Colombier int num, den; 246*8ccd4a63SDavid du Colombier int i, j; 247*8ccd4a63SDavid du Colombier 248*8ccd4a63SDavid du Colombier logpal = mallocz(sizeof(LOGPALETTE) + 256*sizeof(PALETTEENTRY), 1); 249*8ccd4a63SDavid du Colombier if(logpal == nil) 250*8ccd4a63SDavid du Colombier panic("out of memory"); 251*8ccd4a63SDavid du Colombier logpal->palVersion = 0x300; 252*8ccd4a63SDavid du Colombier logpal->palNumEntries = 256; 253*8ccd4a63SDavid du Colombier pal = logpal->palPalEntry; 254*8ccd4a63SDavid du Colombier 255*8ccd4a63SDavid du Colombier for(r=0,i=0; r<4; r++) { 256*8ccd4a63SDavid du Colombier for(v=0; v<4; v++,i+=16){ 257*8ccd4a63SDavid du Colombier for(g=0,j=v-r; g<4; g++) { 258*8ccd4a63SDavid du Colombier for(b=0; b<4; b++,j++){ 259*8ccd4a63SDavid du Colombier den=r; 260*8ccd4a63SDavid du Colombier if(g>den) 261*8ccd4a63SDavid du Colombier den=g; 262*8ccd4a63SDavid du Colombier if(b>den) 263*8ccd4a63SDavid du Colombier den=b; 264*8ccd4a63SDavid du Colombier /* divide check -- pick grey shades */ 265*8ccd4a63SDavid du Colombier if(den==0) 266*8ccd4a63SDavid du Colombier cr=cg=cb=v*17; 267*8ccd4a63SDavid du Colombier else{ 268*8ccd4a63SDavid du Colombier num=17*(4*den+v); 269*8ccd4a63SDavid du Colombier cr=r*num/den; 270*8ccd4a63SDavid du Colombier cg=g*num/den; 271*8ccd4a63SDavid du Colombier cb=b*num/den; 272*8ccd4a63SDavid du Colombier } 273*8ccd4a63SDavid du Colombier pal[i+(j&15)].peRed = cr; 274*8ccd4a63SDavid du Colombier pal[i+(j&15)].peGreen = cg; 275*8ccd4a63SDavid du Colombier pal[i+(j&15)].peBlue = cb; 276*8ccd4a63SDavid du Colombier pal[i+(j&15)].peFlags = 0; 277*8ccd4a63SDavid du Colombier } 278*8ccd4a63SDavid du Colombier } 279*8ccd4a63SDavid du Colombier } 280*8ccd4a63SDavid du Colombier } 281*8ccd4a63SDavid du Colombier palette = CreatePalette(logpal); 282*8ccd4a63SDavid du Colombier } 283*8ccd4a63SDavid du Colombier 284*8ccd4a63SDavid du Colombier 285*8ccd4a63SDavid du Colombier void 286*8ccd4a63SDavid du Colombier getcolor(ulong i, ulong *r, ulong *g, ulong *b) 287*8ccd4a63SDavid du Colombier { 288*8ccd4a63SDavid du Colombier PALETTEENTRY *pal; 289*8ccd4a63SDavid du Colombier 290*8ccd4a63SDavid du Colombier pal = logpal->palPalEntry; 291*8ccd4a63SDavid du Colombier *r = pal[i].peRed; 292*8ccd4a63SDavid du Colombier *g = pal[i].peGreen; 293*8ccd4a63SDavid du Colombier *b = pal[i].peBlue; 294*8ccd4a63SDavid du Colombier } 295*8ccd4a63SDavid du Colombier 296*8ccd4a63SDavid du Colombier void 297*8ccd4a63SDavid du Colombier bmiinit(void) 298*8ccd4a63SDavid du Colombier { 299*8ccd4a63SDavid du Colombier ushort *p; 300*8ccd4a63SDavid du Colombier int i; 301*8ccd4a63SDavid du Colombier 302*8ccd4a63SDavid du Colombier bmi = mallocz(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD), 1); 303*8ccd4a63SDavid du Colombier if(bmi == 0) 304*8ccd4a63SDavid du Colombier panic("out of memory"); 305*8ccd4a63SDavid du Colombier bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 306*8ccd4a63SDavid du Colombier bmi->bmiHeader.biWidth = 0; 307*8ccd4a63SDavid du Colombier bmi->bmiHeader.biHeight = 0; /* - => origin upper left */ 308*8ccd4a63SDavid du Colombier bmi->bmiHeader.biPlanes = 1; 309*8ccd4a63SDavid du Colombier bmi->bmiHeader.biBitCount = depth; 310*8ccd4a63SDavid du Colombier bmi->bmiHeader.biCompression = BI_RGB; 311*8ccd4a63SDavid du Colombier bmi->bmiHeader.biSizeImage = 0; 312*8ccd4a63SDavid du Colombier bmi->bmiHeader.biXPelsPerMeter = 0; 313*8ccd4a63SDavid du Colombier bmi->bmiHeader.biYPelsPerMeter = 0; 314*8ccd4a63SDavid du Colombier bmi->bmiHeader.biClrUsed = 0; 315*8ccd4a63SDavid du Colombier bmi->bmiHeader.biClrImportant = 0; /* number of important colors: 0 means all */ 316*8ccd4a63SDavid du Colombier 317*8ccd4a63SDavid du Colombier p = (ushort*)bmi->bmiColors; 318*8ccd4a63SDavid du Colombier for(i = 0; i < 256; i++) 319*8ccd4a63SDavid du Colombier p[i] = i; 320*8ccd4a63SDavid du Colombier } 321*8ccd4a63SDavid du Colombier 322*8ccd4a63SDavid du Colombier LRESULT CALLBACK 323*8ccd4a63SDavid du Colombier WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 324*8ccd4a63SDavid du Colombier { 325*8ccd4a63SDavid du Colombier PAINTSTRUCT paint; 326*8ccd4a63SDavid du Colombier HDC hdc; 327*8ccd4a63SDavid du Colombier LONG x, y, b; 328*8ccd4a63SDavid du Colombier int i; 329*8ccd4a63SDavid du Colombier Rectangle r; 330*8ccd4a63SDavid du Colombier 331*8ccd4a63SDavid du Colombier switch(msg) { 332*8ccd4a63SDavid du Colombier case WM_CREATE: 333*8ccd4a63SDavid du Colombier break; 334*8ccd4a63SDavid du Colombier case WM_SETCURSOR: 335*8ccd4a63SDavid du Colombier /* User set */ 336*8ccd4a63SDavid du Colombier if(hcursor != NULL) { 337*8ccd4a63SDavid du Colombier SetCursor(hcursor); 338*8ccd4a63SDavid du Colombier return 1; 339*8ccd4a63SDavid du Colombier } 340*8ccd4a63SDavid du Colombier return DefWindowProc(hwnd, msg, wparam, lparam); 341*8ccd4a63SDavid du Colombier case WM_MOUSEMOVE: 342*8ccd4a63SDavid du Colombier case WM_LBUTTONUP: 343*8ccd4a63SDavid du Colombier case WM_MBUTTONUP: 344*8ccd4a63SDavid du Colombier case WM_RBUTTONUP: 345*8ccd4a63SDavid du Colombier case WM_LBUTTONDOWN: 346*8ccd4a63SDavid du Colombier case WM_MBUTTONDOWN: 347*8ccd4a63SDavid du Colombier case WM_RBUTTONDOWN: 348*8ccd4a63SDavid du Colombier x = LOWORD(lparam); 349*8ccd4a63SDavid du Colombier y = HIWORD(lparam); 350*8ccd4a63SDavid du Colombier b = 0; 351*8ccd4a63SDavid du Colombier if(wparam & MK_LBUTTON) 352*8ccd4a63SDavid du Colombier b = 1; 353*8ccd4a63SDavid du Colombier if(wparam & MK_MBUTTON) 354*8ccd4a63SDavid du Colombier b |= 2; 355*8ccd4a63SDavid du Colombier if(wparam & MK_RBUTTON) { 356*8ccd4a63SDavid du Colombier if(wparam & MK_SHIFT) 357*8ccd4a63SDavid du Colombier b |= 2; 358*8ccd4a63SDavid du Colombier else 359*8ccd4a63SDavid du Colombier b |= 4; 360*8ccd4a63SDavid du Colombier } 361*8ccd4a63SDavid du Colombier lock(&mouse.lk); 362*8ccd4a63SDavid du Colombier i = mouse.wi; 363*8ccd4a63SDavid du Colombier if(mousequeue) { 364*8ccd4a63SDavid du Colombier if(i == mouse.ri || mouse.lastb != b || mouse.trans) { 365*8ccd4a63SDavid du Colombier mouse.wi = (i+1)%Mousequeue; 366*8ccd4a63SDavid du Colombier if(mouse.wi == mouse.ri) 367*8ccd4a63SDavid du Colombier mouse.ri = (mouse.ri+1)%Mousequeue; 368*8ccd4a63SDavid du Colombier mouse.trans = mouse.lastb != b; 369*8ccd4a63SDavid du Colombier } else { 370*8ccd4a63SDavid du Colombier i = (i-1+Mousequeue)%Mousequeue; 371*8ccd4a63SDavid du Colombier } 372*8ccd4a63SDavid du Colombier } else { 373*8ccd4a63SDavid du Colombier mouse.wi = (i+1)%Mousequeue; 374*8ccd4a63SDavid du Colombier mouse.ri = i; 375*8ccd4a63SDavid du Colombier } 376*8ccd4a63SDavid du Colombier mouse.queue[i].xy.x = x; 377*8ccd4a63SDavid du Colombier mouse.queue[i].xy.y = y; 378*8ccd4a63SDavid du Colombier mouse.queue[i].buttons = b; 379*8ccd4a63SDavid du Colombier mouse.queue[i].msec = ticks(); 380*8ccd4a63SDavid du Colombier mouse.lastb = b; 381*8ccd4a63SDavid du Colombier unlock(&mouse.lk); 382*8ccd4a63SDavid du Colombier wakeup(&mouse.r); 383*8ccd4a63SDavid du Colombier break; 384*8ccd4a63SDavid du Colombier 385*8ccd4a63SDavid du Colombier case WM_CHAR: 386*8ccd4a63SDavid du Colombier /* repeat count is lparam & 0xf */ 387*8ccd4a63SDavid du Colombier switch(wparam){ 388*8ccd4a63SDavid du Colombier case '\n': 389*8ccd4a63SDavid du Colombier wparam = '\r'; 390*8ccd4a63SDavid du Colombier break; 391*8ccd4a63SDavid du Colombier case '\r': 392*8ccd4a63SDavid du Colombier wparam = '\n'; 393*8ccd4a63SDavid du Colombier break; 394*8ccd4a63SDavid du Colombier } 395*8ccd4a63SDavid du Colombier kbdputc(kbdq, wparam); 396*8ccd4a63SDavid du Colombier break; 397*8ccd4a63SDavid du Colombier 398*8ccd4a63SDavid du Colombier case WM_SYSKEYUP: 399*8ccd4a63SDavid du Colombier break; 400*8ccd4a63SDavid du Colombier case WM_SYSKEYDOWN: 401*8ccd4a63SDavid du Colombier case WM_KEYDOWN: 402*8ccd4a63SDavid du Colombier switch(wparam) { 403*8ccd4a63SDavid du Colombier case VK_MENU: 404*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kalt); 405*8ccd4a63SDavid du Colombier break; 406*8ccd4a63SDavid du Colombier case VK_INSERT: 407*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kins); 408*8ccd4a63SDavid du Colombier break; 409*8ccd4a63SDavid du Colombier case VK_DELETE: 410*8ccd4a63SDavid du Colombier // kbdputc(kbdq, Kdel); 411*8ccd4a63SDavid du Colombier kbdputc(kbdq, 0x7f); // should have Kdel in keyboard.h 412*8ccd4a63SDavid du Colombier break; 413*8ccd4a63SDavid du Colombier case VK_UP: 414*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kup); 415*8ccd4a63SDavid du Colombier break; 416*8ccd4a63SDavid du Colombier case VK_DOWN: 417*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kdown); 418*8ccd4a63SDavid du Colombier break; 419*8ccd4a63SDavid du Colombier case VK_LEFT: 420*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kleft); 421*8ccd4a63SDavid du Colombier break; 422*8ccd4a63SDavid du Colombier case VK_RIGHT: 423*8ccd4a63SDavid du Colombier kbdputc(kbdq, Kright); 424*8ccd4a63SDavid du Colombier break; 425*8ccd4a63SDavid du Colombier } 426*8ccd4a63SDavid du Colombier break; 427*8ccd4a63SDavid du Colombier 428*8ccd4a63SDavid du Colombier case WM_CLOSE: 429*8ccd4a63SDavid du Colombier DestroyWindow(hwnd); 430*8ccd4a63SDavid du Colombier break; 431*8ccd4a63SDavid du Colombier 432*8ccd4a63SDavid du Colombier case WM_DESTROY: 433*8ccd4a63SDavid du Colombier PostQuitMessage(0); 434*8ccd4a63SDavid du Colombier break; 435*8ccd4a63SDavid du Colombier 436*8ccd4a63SDavid du Colombier case WM_PALETTECHANGED: 437*8ccd4a63SDavid du Colombier if((HWND)wparam == hwnd) 438*8ccd4a63SDavid du Colombier break; 439*8ccd4a63SDavid du Colombier /* fall through */ 440*8ccd4a63SDavid du Colombier case WM_QUERYNEWPALETTE: 441*8ccd4a63SDavid du Colombier hdc = GetDC(hwnd); 442*8ccd4a63SDavid du Colombier SelectPalette(hdc, palette, 0); 443*8ccd4a63SDavid du Colombier if(RealizePalette(hdc) != 0) 444*8ccd4a63SDavid du Colombier InvalidateRect(hwnd, nil, 0); 445*8ccd4a63SDavid du Colombier ReleaseDC(hwnd, hdc); 446*8ccd4a63SDavid du Colombier break; 447*8ccd4a63SDavid du Colombier 448*8ccd4a63SDavid du Colombier case WM_PAINT: 449*8ccd4a63SDavid du Colombier hdc = BeginPaint(hwnd, &paint); 450*8ccd4a63SDavid du Colombier r.min.x = paint.rcPaint.left; 451*8ccd4a63SDavid du Colombier r.min.y = paint.rcPaint.top; 452*8ccd4a63SDavid du Colombier r.max.x = paint.rcPaint.right; 453*8ccd4a63SDavid du Colombier r.max.y = paint.rcPaint.bottom; 454*8ccd4a63SDavid du Colombier flushmemscreen(r); 455*8ccd4a63SDavid du Colombier EndPaint(hwnd, &paint); 456*8ccd4a63SDavid du Colombier break; 457*8ccd4a63SDavid du Colombier case WM_COMMAND: 458*8ccd4a63SDavid du Colombier case WM_SETFOCUS: 459*8ccd4a63SDavid du Colombier case WM_DEVMODECHANGE: 460*8ccd4a63SDavid du Colombier case WM_WININICHANGE: 461*8ccd4a63SDavid du Colombier case WM_INITMENU: 462*8ccd4a63SDavid du Colombier default: 463*8ccd4a63SDavid du Colombier return DefWindowProc(hwnd, msg, wparam, lparam); 464*8ccd4a63SDavid du Colombier } 465*8ccd4a63SDavid du Colombier return 0; 466*8ccd4a63SDavid du Colombier } 467*8ccd4a63SDavid du Colombier 468*8ccd4a63SDavid du Colombier void 469*8ccd4a63SDavid du Colombier mouseset(Point xy) 470*8ccd4a63SDavid du Colombier { 471*8ccd4a63SDavid du Colombier POINT pt; 472*8ccd4a63SDavid du Colombier 473*8ccd4a63SDavid du Colombier pt.x = xy.x; 474*8ccd4a63SDavid du Colombier pt.y = xy.y; 475*8ccd4a63SDavid du Colombier MapWindowPoints(window, 0, &pt, 1); 476*8ccd4a63SDavid du Colombier SetCursorPos(pt.x, pt.y); 477*8ccd4a63SDavid du Colombier } 478*8ccd4a63SDavid du Colombier 479*8ccd4a63SDavid du Colombier void 480*8ccd4a63SDavid du Colombier setcursor(void) 481*8ccd4a63SDavid du Colombier { 482*8ccd4a63SDavid du Colombier HCURSOR nh; 483*8ccd4a63SDavid du Colombier int x, y, h, w; 484*8ccd4a63SDavid du Colombier uchar *sp, *cp; 485*8ccd4a63SDavid du Colombier uchar *and, *xor; 486*8ccd4a63SDavid du Colombier 487*8ccd4a63SDavid du Colombier h = GetSystemMetrics(SM_CYCURSOR); 488*8ccd4a63SDavid du Colombier w = (GetSystemMetrics(SM_CXCURSOR)+7)/8; 489*8ccd4a63SDavid du Colombier 490*8ccd4a63SDavid du Colombier and = mallocz(h*w, 1); 491*8ccd4a63SDavid du Colombier memset(and, 0xff, h*w); 492*8ccd4a63SDavid du Colombier xor = mallocz(h*w, 1); 493*8ccd4a63SDavid du Colombier 494*8ccd4a63SDavid du Colombier lock(&cursor.lk); 495*8ccd4a63SDavid du Colombier for(y=0,sp=cursor.set,cp=cursor.clr; y<16; y++) { 496*8ccd4a63SDavid du Colombier for(x=0; x<2; x++) { 497*8ccd4a63SDavid du Colombier and[y*w+x] = ~(*sp|*cp); 498*8ccd4a63SDavid du Colombier xor[y*w+x] = ~*sp & *cp; 499*8ccd4a63SDavid du Colombier cp++; 500*8ccd4a63SDavid du Colombier sp++; 501*8ccd4a63SDavid du Colombier } 502*8ccd4a63SDavid du Colombier } 503*8ccd4a63SDavid du Colombier nh = CreateCursor(inst, -cursor.offset.x, -cursor.offset.y, 504*8ccd4a63SDavid du Colombier GetSystemMetrics(SM_CXCURSOR), h, 505*8ccd4a63SDavid du Colombier and, xor); 506*8ccd4a63SDavid du Colombier if(nh != NULL) { 507*8ccd4a63SDavid du Colombier SetCursor(nh); 508*8ccd4a63SDavid du Colombier if(hcursor != NULL) 509*8ccd4a63SDavid du Colombier DestroyCursor(hcursor); 510*8ccd4a63SDavid du Colombier hcursor = nh; 511*8ccd4a63SDavid du Colombier } 512*8ccd4a63SDavid du Colombier unlock(&cursor.lk); 513*8ccd4a63SDavid du Colombier 514*8ccd4a63SDavid du Colombier free(and); 515*8ccd4a63SDavid du Colombier free(xor); 516*8ccd4a63SDavid du Colombier 517*8ccd4a63SDavid du Colombier PostMessage(window, WM_SETCURSOR, (int)window, 0); 518*8ccd4a63SDavid du Colombier } 519*8ccd4a63SDavid du Colombier 520*8ccd4a63SDavid du Colombier void 521*8ccd4a63SDavid du Colombier cursorarrow(void) 522*8ccd4a63SDavid du Colombier { 523*8ccd4a63SDavid du Colombier if(hcursor != 0) { 524*8ccd4a63SDavid du Colombier DestroyCursor(hcursor); 525*8ccd4a63SDavid du Colombier hcursor = 0; 526*8ccd4a63SDavid du Colombier } 527*8ccd4a63SDavid du Colombier SetCursor(LoadCursor(0, IDC_ARROW)); 528*8ccd4a63SDavid du Colombier PostMessage(window, WM_SETCURSOR, (int)window, 0); 529*8ccd4a63SDavid du Colombier } 530*8ccd4a63SDavid du Colombier 531*8ccd4a63SDavid du Colombier 532*8ccd4a63SDavid du Colombier void 533*8ccd4a63SDavid du Colombier setcolor(ulong index, ulong red, ulong green, ulong blue) 534*8ccd4a63SDavid du Colombier { 535*8ccd4a63SDavid du Colombier } 536*8ccd4a63SDavid du Colombier 537*8ccd4a63SDavid du Colombier 538*8ccd4a63SDavid du Colombier uchar* 539*8ccd4a63SDavid du Colombier clipreadunicode(HANDLE h) 540*8ccd4a63SDavid du Colombier { 541*8ccd4a63SDavid du Colombier Rune *p; 542*8ccd4a63SDavid du Colombier int n; 543*8ccd4a63SDavid du Colombier uchar *q; 544*8ccd4a63SDavid du Colombier 545*8ccd4a63SDavid du Colombier p = GlobalLock(h); 546*8ccd4a63SDavid du Colombier n = wstrutflen(p)+1; 547*8ccd4a63SDavid du Colombier q = malloc(n); 548*8ccd4a63SDavid du Colombier wstrtoutf(q, p, n); 549*8ccd4a63SDavid du Colombier GlobalUnlock(h); 550*8ccd4a63SDavid du Colombier 551*8ccd4a63SDavid du Colombier return q; 552*8ccd4a63SDavid du Colombier } 553*8ccd4a63SDavid du Colombier 554*8ccd4a63SDavid du Colombier uchar * 555*8ccd4a63SDavid du Colombier clipreadutf(HANDLE h) 556*8ccd4a63SDavid du Colombier { 557*8ccd4a63SDavid du Colombier uchar *p; 558*8ccd4a63SDavid du Colombier 559*8ccd4a63SDavid du Colombier p = GlobalLock(h); 560*8ccd4a63SDavid du Colombier p = strdup(p); 561*8ccd4a63SDavid du Colombier GlobalUnlock(h); 562*8ccd4a63SDavid du Colombier 563*8ccd4a63SDavid du Colombier return p; 564*8ccd4a63SDavid du Colombier } 565*8ccd4a63SDavid du Colombier 566*8ccd4a63SDavid du Colombier char* 567*8ccd4a63SDavid du Colombier clipread(void) 568*8ccd4a63SDavid du Colombier { 569*8ccd4a63SDavid du Colombier HANDLE h; 570*8ccd4a63SDavid du Colombier uchar *p; 571*8ccd4a63SDavid du Colombier 572*8ccd4a63SDavid du Colombier if(!OpenClipboard(window)) { 573*8ccd4a63SDavid du Colombier oserror(); 574*8ccd4a63SDavid du Colombier return strdup(""); 575*8ccd4a63SDavid du Colombier } 576*8ccd4a63SDavid du Colombier 577*8ccd4a63SDavid du Colombier if((h = GetClipboardData(CF_UNICODETEXT))) 578*8ccd4a63SDavid du Colombier p = clipreadunicode(h); 579*8ccd4a63SDavid du Colombier else if((h = GetClipboardData(CF_TEXT))) 580*8ccd4a63SDavid du Colombier p = clipreadutf(h); 581*8ccd4a63SDavid du Colombier else { 582*8ccd4a63SDavid du Colombier oserror(); 583*8ccd4a63SDavid du Colombier p = strdup(""); 584*8ccd4a63SDavid du Colombier } 585*8ccd4a63SDavid du Colombier 586*8ccd4a63SDavid du Colombier CloseClipboard(); 587*8ccd4a63SDavid du Colombier return p; 588*8ccd4a63SDavid du Colombier } 589*8ccd4a63SDavid du Colombier 590*8ccd4a63SDavid du Colombier int 591*8ccd4a63SDavid du Colombier clipwrite(char *buf) 592*8ccd4a63SDavid du Colombier { 593*8ccd4a63SDavid du Colombier HANDLE h; 594*8ccd4a63SDavid du Colombier char *p, *e; 595*8ccd4a63SDavid du Colombier Rune *rp; 596*8ccd4a63SDavid du Colombier int n = strlen(buf); 597*8ccd4a63SDavid du Colombier 598*8ccd4a63SDavid du Colombier if(!OpenClipboard(window)) { 599*8ccd4a63SDavid du Colombier oserror(); 600*8ccd4a63SDavid du Colombier return -1; 601*8ccd4a63SDavid du Colombier } 602*8ccd4a63SDavid du Colombier 603*8ccd4a63SDavid du Colombier if(!EmptyClipboard()) { 604*8ccd4a63SDavid du Colombier oserror(); 605*8ccd4a63SDavid du Colombier CloseClipboard(); 606*8ccd4a63SDavid du Colombier return -1; 607*8ccd4a63SDavid du Colombier } 608*8ccd4a63SDavid du Colombier 609*8ccd4a63SDavid du Colombier h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, (n+1)*sizeof(Rune)); 610*8ccd4a63SDavid du Colombier if(h == NULL) 611*8ccd4a63SDavid du Colombier panic("out of memory"); 612*8ccd4a63SDavid du Colombier rp = GlobalLock(h); 613*8ccd4a63SDavid du Colombier p = buf; 614*8ccd4a63SDavid du Colombier e = p+n; 615*8ccd4a63SDavid du Colombier while(p<e) 616*8ccd4a63SDavid du Colombier p += chartorune(rp++, p); 617*8ccd4a63SDavid du Colombier *rp = 0; 618*8ccd4a63SDavid du Colombier GlobalUnlock(h); 619*8ccd4a63SDavid du Colombier 620*8ccd4a63SDavid du Colombier SetClipboardData(CF_UNICODETEXT, h); 621*8ccd4a63SDavid du Colombier 622*8ccd4a63SDavid du Colombier h = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, n+1); 623*8ccd4a63SDavid du Colombier if(h == NULL) 624*8ccd4a63SDavid du Colombier panic("out of memory"); 625*8ccd4a63SDavid du Colombier p = GlobalLock(h); 626*8ccd4a63SDavid du Colombier memcpy(p, buf, n); 627*8ccd4a63SDavid du Colombier p[n] = 0; 628*8ccd4a63SDavid du Colombier GlobalUnlock(h); 629*8ccd4a63SDavid du Colombier 630*8ccd4a63SDavid du Colombier SetClipboardData(CF_TEXT, h); 631*8ccd4a63SDavid du Colombier 632*8ccd4a63SDavid du Colombier CloseClipboard(); 633*8ccd4a63SDavid du Colombier return n; 634*8ccd4a63SDavid du Colombier } 635*8ccd4a63SDavid du Colombier 636*8ccd4a63SDavid du Colombier int 637*8ccd4a63SDavid du Colombier atlocalconsole(void) 638*8ccd4a63SDavid du Colombier { 639*8ccd4a63SDavid du Colombier return 1; 640*8ccd4a63SDavid du Colombier } 641