Charles.Forsyth20071011-11329612a0519 years agoHistory
755 lines · 18.0 KB · C
RawDownload
// in this file, _Rect is os x Rect,// _Point is os x Point#define Point _Point#define Rect _Rect #include <Carbon/Carbon.h>#include <QuickTime/QuickTime.h> // for full screen #undef Rect#undef Point #undef nil #include "dat.h"#include "fns.h"#undef log2#include <draw.h>#include <memdraw.h>#include "cursor.h"#include "keyboard.h"#include "keycodes.h" #define	Kup	Up#define	Kleft	Left#define	Kdown	Down#define	Kright	Right#define	Kalt	LAlt#define	Kctl	LCtrl#define	Kshift	LShift#define	Kpgup	Pgup#define	Kpgdown	Pgdown#define	Khome	Home#define	Kins	Ins#define	Kend	End #define rWindowResource  128 extern	void		flushmemscreen(Rectangle); Memimage	*gscreen; static int readybit;static Rendez	rend;static int triedscreen; ///// menu//static MenuRef windMenu;static MenuRef viewMenu; enum {	kQuitCmd = 1,	kFullScreenCmd = 2,}; static WindowGroupRef winGroup = NULL;static WindowRef theWindow = NULL;static CGContextRef context;static CGDataProviderRef dataProviderRef;static CGImageRef fullScreenImage;static CGRect devRect;static CGRect bounds;static PasteboardRef appleclip;static _Rect winRect; static Boolean altPressed = false;static Boolean button2 = false;static Boolean button3 = false; static Boolean needflush = false;  static intisready(void*a){	return readybit;} CGContextRef QuartzContext; static OSStatus MainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);static OSStatus MainWindowCommandHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData); static void winproc(void *a);static void flushproc(void *a); voidscreeninit(void){	int fmt;	int dx, dy;	ProcessSerialNumber psn = { 0, kCurrentProcess };	TransformProcessType(&psn, kProcessTransformToForegroundApplication);	SetFrontProcess(&psn); 	fmt = XBGR32; //XRGB32; 	devRect = CGDisplayBounds(CGMainDisplayID());//	devRect.origin.x = 0;//	devRect.origin.y = 0;//	devRect.size.width = 1024;//	devRect.size.height = 768;	dx = devRect.size.width;	dy = devRect.size.height; 	if(1){	/* TO DO: new dev draw for changing screen size */		dx = Xsize;		dy = Ysize;	} 	gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);	dataProviderRef = CGDataProviderCreateWithData(0, gscreen->data->bdata,						dx * dy * 4, 0);	fullScreenImage = CGImageCreate(dx, dy, 8, 32, dx * 4,				CGColorSpaceCreateDeviceRGB(),				kCGImageAlphaNoneSkipLast,				dataProviderRef, 0, 0, kCGRenderingIntentDefault); 	kproc("osxscreen", winproc, nil, 0);	kproc("osxflush", flushproc, nil, 0);	Sleep(&rend, isready, nil);} voidwindow_resized(void){	GetWindowBounds(theWindow, kWindowContentRgn, &winRect); 	bounds = CGRectMake(0, 0, winRect.right-winRect.left, winRect.bottom - winRect.top);} static voidflushproc(void *a){	for(;;) {		if(needflush) {			drawqlock();			QDBeginCGContext(GetWindowPort(theWindow), &context);			CGContextFlush(context);			QDEndCGContext(GetWindowPort(theWindow), &context);			needflush = false; 			drawqunlock();		}		usleep(33333);	}} static voidwinproc(void *a){	MenuItemIndex index;	int dx, dy; 	winRect.left = 30;	winRect.top = 60;	dx = devRect.size.width*0.75;	/* devRect is full screen; take only most of it */	dy = devRect.size.height*0.75;	if(1){	/* TO DO */		dx = Xsize;		dy = Ysize;	}	winRect.bottom = winRect.top + dy;	winRect.right = winRect.left + dx; 	ClearMenuBar();	InitCursor(); 	CreateStandardWindowMenu(0, &windMenu);	InsertMenu(windMenu, 0); 	CreateNewMenu(1004, 0, &viewMenu);	SetMenuTitleWithCFString(viewMenu, CFSTR("View"));	AppendMenuItemTextWithCFString(viewMenu, CFSTR("Full Screen"), 0,			kFullScreenCmd, &index);	SetMenuItemCommandKey(viewMenu, index, 0, 'F');	AppendMenuItemTextWithCFString(viewMenu, CFSTR("ctrl-opt to return"),			kMenuItemAttrDisabled,			kFullScreenCmd, &index);	InsertMenu(viewMenu, GetMenuID(windMenu)); 	DrawMenuBar();	uint32_t windowAttrs = 0				| kWindowCloseBoxAttribute				| kWindowCollapseBoxAttribute//				| kWindowResizableAttribute		// TO DO				| kWindowStandardHandlerAttribute//				| kWindowFullZoomAttribute		// TO DO		; 	CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow);	CreateWindowGroup(0, &winGroup);	SetWindowGroup(theWindow, winGroup); 	SetWindowTitleWithCFString(theWindow, CFSTR("Inferno")); 	if(PasteboardCreate(kPasteboardClipboard, &appleclip) != noErr)		sysfatal("pasteboard create failed"); 	const EventTypeSpec commands[] = {		{ kEventClassWindow, kEventWindowClosed },		{ kEventClassWindow, kEventWindowBoundsChanged },		{ kEventClassCommand, kEventCommandProcess }	};	const EventTypeSpec events[] = {		{ kEventClassKeyboard, kEventRawKeyDown },		{ kEventClassKeyboard, kEventRawKeyModifiersChanged },		{ kEventClassKeyboard, kEventRawKeyRepeat },		{ kEventClassMouse, kEventMouseDown },		{ kEventClassMouse, kEventMouseUp },		{ kEventClassMouse, kEventMouseMoved },		{ kEventClassMouse, kEventMouseDragged },		{ kEventClassMouse, kEventMouseWheelMoved },	};  	InstallApplicationEventHandler ( 								NewEventHandlerUPP (MainWindowEventHandler),								GetEventTypeCount(events),								events,								NULL,								NULL);	InstallWindowEventHandler (								theWindow,								NewEventHandlerUPP (MainWindowCommandHandler),								GetEventTypeCount(commands),								commands,								theWindow,								NULL); 	ShowWindow(theWindow);	ShowMenuBar();	window_resized();	SelectWindow(theWindow);	// Run the event loop	readybit = 1;	Wakeup(&rend);	RunApplicationEventLoop(); } static intconvert_key(UInt32 key, UInt32 charcode){	switch(key) {	case QZ_IBOOK_ENTER:	case QZ_RETURN: return '\n';	case QZ_ESCAPE: return 27;	case QZ_BACKSPACE: return '\b';	case QZ_LALT: return Kalt;	case QZ_LCTRL: return Kctl;	case QZ_LSHIFT: return Kshift;	case QZ_F1: return KF+1;	case QZ_F2: return KF+2;	case QZ_F3: return KF+3;	case QZ_F4: return KF+4;	case QZ_F5: return KF+5;	case QZ_F6: return KF+6;	case QZ_F7: return KF+7;	case QZ_F8: return KF+8;	case QZ_F9: return KF+9;	case QZ_F10: return KF+10;	case QZ_F11: return KF+11;	case QZ_F12: return KF+12;	case QZ_INSERT: return Kins;	case QZ_DELETE: return 0x7F;	case QZ_HOME: return Khome;	case QZ_END: return Kend;	case QZ_KP_PLUS: return '+';	case QZ_KP_MINUS: return '-';	case QZ_TAB: return '\t';	case QZ_PAGEUP: return Kpgup;	case QZ_PAGEDOWN: return Kpgdown;	case QZ_UP: return Kup;	case QZ_DOWN: return Kdown;	case QZ_LEFT: return Kleft;	case QZ_RIGHT: return Kright;	case QZ_KP_MULTIPLY: return '*';	case QZ_KP_DIVIDE: return '/';	case QZ_KP_ENTER: return '\n';	case QZ_KP_PERIOD: return '.';	case QZ_KP0: return '0';	case QZ_KP1: return '1';	case QZ_KP2: return '2';	case QZ_KP3: return '3';	case QZ_KP4: return '4';	case QZ_KP5: return '5';	case QZ_KP6: return '6';	case QZ_KP7: return '7';	case QZ_KP8: return '8';	case QZ_KP9: return '9';	default: return charcode;	}} voidsendbuttons(int b, int x, int y){	mousetrack(b, x, y, 0);} static Ptr fullScreenRestore;static int amFullScreen = 0;static WindowRef oldWindow = NULL; static voidleave_full_screen(void){	if (0 && amFullScreen) {		EndFullScreen(fullScreenRestore, 0);		theWindow = oldWindow;		ShowWindow(theWindow);		amFullScreen = 0;		window_resized();		Rectangle rect =  { { 0, 0 }, { bounds.size.width, bounds.size.height} };		drawqlock(); 		flushmemscreen(rect); 		drawqunlock();	}} static voidfull_screen(void){	if (0 && !amFullScreen) {		oldWindow = theWindow;		HideWindow(theWindow);		BeginFullScreen(&fullScreenRestore, 0, 0, 0, &theWindow, 0, 0);		amFullScreen = 1;		window_resized();		Rectangle rect =  { { 0, 0 }, 							{ bounds.size.width, 							  bounds.size.height} };		drawqlock(); 		flushmemscreen(rect); 		drawqunlock();	}} static OSStatusMainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData){	OSStatus result = noErr;	result = CallNextEventHandler(nextHandler, event);	UInt32 class = GetEventClass (event);	UInt32 kind = GetEventKind (event);	static uint32_t mousebuttons = 0; // bitmask of buttons currently down	static uint32_t mouseX = 0;	static uint32_t mouseY = 0; 	if(class == kEventClassKeyboard) {		char macCharCodes;		UInt32 macKeyCode;		UInt32 macKeyModifiers; 		GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar,							NULL, sizeof(macCharCodes), NULL, &macCharCodes);		GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL,							sizeof(macKeyCode), NULL, &macKeyCode);		GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,							sizeof(macKeyModifiers), NULL, &macKeyModifiers);        switch(kind) {		case kEventRawKeyModifiersChanged:			if (macKeyModifiers == (controlKey | optionKey)) leave_full_screen(); 			switch(macKeyModifiers & (optionKey | cmdKey)) {			case (optionKey | cmdKey):				/* due to chording we need to handle the case when both				 * modifier keys are pressed at the same time.				 * currently it's only 2-3 snarf and the 3-2 noop				 */				altPressed = true;				if(mousebuttons & 1 || mousebuttons & 2 || mousebuttons & 4) {					mousebuttons |= 2;	/* set button 2 */					mousebuttons |= 4;	/* set button 3 */					button2 = true;					button3 = true;					sendbuttons(mousebuttons, mouseX, mouseY);				}				break;			case optionKey:				altPressed = true;				if(mousebuttons & 1 || mousebuttons & 4) {					mousebuttons |= 2;	/* set button 2 */					button2 = true;					sendbuttons(mousebuttons, mouseX, mouseY);				}				break;			case cmdKey:				if(mousebuttons & 1 || mousebuttons & 2) {					mousebuttons |= 4;	/* set button 3 */					button3 = true;					sendbuttons(mousebuttons, mouseX, mouseY);				}else					gkbdputc(gkbdq, Latin);				break;			case 0:			default:				if(button2 || button3) {					if(button2) {						mousebuttons &= ~2;	/* clear button 2 */						button2 = false;						altPressed = false;					}					if(button3) {						mousebuttons &= ~4;	/* clear button 3 */						button3 = false;					}					sendbuttons(mousebuttons, mouseX, mouseY);				}				if(altPressed) {					gkbdputc(gkbdq, Kalt);					altPressed = false;				}				break;			}			break;		case kEventRawKeyDown:		case kEventRawKeyRepeat:			if(macKeyModifiers != cmdKey) {				int key;				key = convert_key(macKeyCode, macCharCodes);				if(key != -1)					gkbdputc(gkbdq, key);			}else				result = eventNotHandledErr;			break;		default:			break;		}	}	else if(class == kEventClassMouse) {		_Point mousePos; 		GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,							0, sizeof mousePos, 0, &mousePos);				switch(kind) {		case kEventMouseWheelMoved:		{		    int32_t wheeldelta;			GetEventParameter(event,kEventParamMouseWheelDelta,typeSInt32,								0,sizeof(wheeldelta), 0, &wheeldelta);			mouseX = mousePos.h - winRect.left;			mouseY = mousePos.v - winRect.top;			sendbuttons(wheeldelta>0 ? 8 : 16, mouseX, mouseY);			break;		}		case kEventMouseUp:		case kEventMouseDown:		{			uint32_t buttons;			uint32_t modifiers;			GetEventParameter(event, kEventParamKeyModifiers, typeUInt32,								0, sizeof(modifiers), 0, &modifiers);			GetEventParameter(event, kEventParamMouseChord, typeUInt32,								0, sizeof buttons, 0, &buttons);			/* simulate other buttons via alt/apple key. like x11 */			if(modifiers & optionKey) {				mousebuttons = ((buttons & 1) ? 2 : 0);				altPressed = false;			} else if(modifiers & cmdKey)				mousebuttons = ((buttons & 1) ? 4 : 0);			else				mousebuttons = (buttons & 1); 			mousebuttons |= ((buttons & 2)<<1);			mousebuttons |= ((buttons & 4)>>1); 		} /* Fallthrough */		case kEventMouseMoved:		case kEventMouseDragged:			mouseX = mousePos.h - winRect.left;			mouseY = mousePos.v - winRect.top;			sendbuttons(mousebuttons, mouseX, mouseY);			break;		default:			result = eventNotHandledErr;			break;		}	}	return result;}  //default window command handler (from menus)static OSStatusMainWindowCommandHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData){	OSStatus result = noErr;	UInt32 class = GetEventClass (event);	UInt32 kind = GetEventKind (event); 	result = CallNextEventHandler(nextHandler, event); 	if(class == kEventClassCommand) {		HICommand theHICommand;		GetEventParameter(event, kEventParamDirectObject, typeHICommand,							NULL, sizeof(HICommand), NULL, &theHICommand); 		switch(theHICommand.commandID) {

Lines 1–500 of 755.