689 lines · 12.3 KB · C
RawDownload
#define _WIN32_WINNT 0x0500#include	<windows.h> #undef Rectangle#define Rectangle _Rectangle #include "u.h"#include "lib.h"#include "kern/dat.h"#include "kern/fns.h"#include "error.h"#include "user.h"#include <draw.h>#include <memdraw.h>#include "screen.h"#include "keyboard.h" Memimage	*gscreen; static int depth;static int dibtype; 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 int readybit;static Rendez	rend; static intisready(void*a){	return readybit;} voidscreeninit(void){	int dx, dy;	ulong chan; 	FreeConsole();	memimageinit(); 	if(depth == 0)		depth = GetDeviceCaps(GetDC(NULL), BITSPIXEL);	switch(depth){	case 32:		dibtype = DIB_RGB_COLORS;		depth = 32;		chan = XRGB32;		break;	case 24:		dibtype = DIB_RGB_COLORS;		depth = 24;		chan = RGB24;		break;	case 16:		dibtype = DIB_RGB_COLORS;		depth = 16;		chan = RGB15;	/* [sic] */		break;	case 8:	default:		dibtype = DIB_PAL_COLORS;		depth = 8;		depth = 8;		chan = CMAP8;		break;	}	dx = GetDeviceCaps(GetDC(NULL), HORZRES);	dy = GetDeviceCaps(GetDC(NULL), VERTRES);	screensize(Rect(0,0,dx,dy), chan);	kproc("winscreen", winproc, 0);	ksleep(&rend, isready, 0);} voidscreensize(Rectangle r, ulong chan){	Memimage *i; 	if((i = allocmemimage(r, chan)) == nil)		return;	if(gscreen != nil)		freememimage(gscreen);	gscreen = i;	gscreen->clipr = ZR;} Memdata*attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen){	*r = gscreen->clipr;	*chan = gscreen->chan;	*depth = gscreen->depth;	*width = gscreen->width;	*softscreen = 1; 	gscreen->data->ref++;	return gscreen->data;} voidflushmemscreen(Rectangle r){	int dx, dy;	HDC hdc; 	/*	 * 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->clipr) == 0)		return;		lock(&gdilock); 	hdc = GetDC(window);	SelectPalette(hdc, palette, 0);	RealizePalette(hdc); 	dx = r.max.x - r.min.x;	dy = r.max.y - r.min.y; 	bmi->bmiHeader.biWidth = (gscreen->width*sizeof(ulong)*8)/gscreen->depth;	bmi->bmiHeader.biHeight = -dy;	/* - => origin upper left */ 	SetDIBitsToDevice(hdc,		r.min.x, r.min.y,		dx, dy,		r.min.x, 0,		0, dy,		byteaddr(gscreen, Pt(0, r.min.y)), bmi,		dibtype); 	ReleaseDC(window, hdc); 	GdiFlush(); 	unlock(&gdilock);} static voidwinproc(void *a){	WNDCLASS wc;	MSG msg; 	inst = GetModuleHandle(NULL); 	paletteinit();	bmiinit(); 	wc.style = 0;	wc.lpfnWndProc = WindowProc;	wc.cbClsExtra = 0;	wc.cbWndExtra = 0;	wc.hInstance = inst;	wc.hIcon = LoadIcon(inst, MAKEINTRESOURCE(101));	wc.hCursor = LoadCursor(NULL, IDC_ARROW);	wc.hbrBackground = GetStockObject(WHITE_BRUSH);	wc.lpszMenuName = 0;	wc.lpszClassName = L"9pmgraphics";	RegisterClass(&wc); 	window = CreateWindowEx(		0,			/* extended style */		L"9pmgraphics",		/* class */		L"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); 	terminit(); 	readybit = 1;	wakeup(&rend); 	while(GetMessage(&msg, NULL, 0, 0)) {		TranslateMessage(&msg);		DispatchMessage(&msg);	}//	MessageBox(0, "winproc", "exits", MB_OK);	ExitProcess(0);} 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)		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);}  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)		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;} voidtogglefull(HWND hwnd){	static int full;	static LONG style, exstyle;	static WINDOWPLACEMENT pl;	MONITORINFO mi;		full = !full;	if(full){		SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);		style = GetWindowLong(hwnd, GWL_STYLE);		exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);		pl.length = sizeof(WINDOWPLACEMENT);		GetWindowPlacement(hwnd, &pl);		SetWindowLong(hwnd, GWL_STYLE, style & ~(WS_CAPTION | WS_THICKFRAME));		SetWindowLong(hwnd, GWL_EXSTYLE, exstyle & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));		mi.cbSize = sizeof(MONITORINFO);		GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &mi);		SetWindowPos(hwnd, NULL, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);	}else{		SetWindowLong(hwnd, GWL_STYLE, style);		SetWindowLong(hwnd, GWL_EXSTYLE, exstyle);		SetWindowPlacement(hwnd, &pl);	}} Rune vk2rune[256] = {[VK_CANCEL] Kbreak,[VK_CAPITAL] Kcaps,[VK_CONTROL] Kctl,[VK_DELETE] Kdel,[VK_DOWN] Kdown,[VK_END] Kend,[VK_F1] KF|1,KF|2,KF|3,KF|4,KF|5,KF|6,KF|7,KF|8,KF|9,KF|10,KF|11,KF|12,[VK_HOME] Khome,[VK_INSERT] Kins,[VK_LEFT] Kleft,[VK_MENU] Kalt,[VK_NEXT] Kpgdown,[VK_NUMLOCK] Knum,[VK_PRINT] Kprint,[VK_PRIOR] Kpgup,[VK_RIGHT] Kright,[VK_RMENU] Kaltgr,[VK_SCROLL] Kscroll,[VK_SHIFT] Kshift,[VK_UP] Kup,};		 LRESULT CALLBACKWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){	static Rune scdown[256];	PAINTSTRUCT paint;	HDC hdc;	LONG x, y, b;	int i;	RECT winr;	Rectangle r;	Rune k; 	b = 0; 	switch(msg) {	case WM_CREATE:		if(GetClientRect(hwnd, &winr) == 0)			break;		gscreen->clipr = Rect(0, 0, winr.right - winr.left, winr.bottom - winr.top);		rectclip(&gscreen->clipr, gscreen->r);		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;		mousetrack(0, 0, b, ticks());		break;	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)			b |= 4;		absmousetrack(x, y, b, ticks());		break; 	case WM_CHAR:		k = wparam;		if(k == '\n')			k = '\r';		else if(k == '\r')			k = '\n';		if(0){	case WM_SYSKEYDOWN:	case WM_KEYDOWN:			k = vk2rune[wparam&0xFF];		}		if(k == 0)			break;		i = (lparam>>16)&0xFF;		scdown[i] = k;		kbdkey(k, 1);		break;	case WM_SYSKEYUP:	case WM_KEYUP:		if(wparam == VK_PAUSE)			togglefull(hwnd);		i = (lparam>>16)&0xFF;		k = scdown[i];		if(k != 0){			scdown[i] = 0;			kbdkey(k, 0);		}		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_SIZE:		if(GetClientRect(hwnd, &winr) == 0)			break;		screenresize(Rect(0, 0, winr.right - winr.left, winr.bottom - winr.top));		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;} voidmouseset(Point xy){	POINT pt; 	pt.x = xy.x;	pt.y = xy.y;	MapWindowPoints(window, 0, &pt, 1);	SetCursorPos(pt.x, pt.y);} voidsetcursor(void){	HCURSOR nh;

Lines 1–500 of 689.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t