1*96cbc34fSDavid du Colombier // in this file, _Rect is os x Rect,
2*96cbc34fSDavid du Colombier // _Point is os x Point
3*96cbc34fSDavid du Colombier #undef Point
4*96cbc34fSDavid du Colombier #define Point _Point
5*96cbc34fSDavid du Colombier #undef Rect
6*96cbc34fSDavid du Colombier #define Rect _Rect
7*96cbc34fSDavid du Colombier
8*96cbc34fSDavid du Colombier #include <Carbon/Carbon.h>
9*96cbc34fSDavid du Colombier #include <QuickTime/QuickTime.h> // for full screen
10*96cbc34fSDavid du Colombier
11*96cbc34fSDavid du Colombier #undef Rect
12*96cbc34fSDavid du Colombier #undef Point
13*96cbc34fSDavid du Colombier
14*96cbc34fSDavid du Colombier #undef nil
15*96cbc34fSDavid du Colombier
16*96cbc34fSDavid du Colombier
17*96cbc34fSDavid du Colombier #include "u.h"
18*96cbc34fSDavid du Colombier #include "lib.h"
19*96cbc34fSDavid du Colombier #include "kern/dat.h"
20*96cbc34fSDavid du Colombier #include "kern/fns.h"
21*96cbc34fSDavid du Colombier #include "error.h"
22*96cbc34fSDavid du Colombier #include "user.h"
23*96cbc34fSDavid du Colombier #include <draw.h>
24*96cbc34fSDavid du Colombier #include <memdraw.h>
25*96cbc34fSDavid du Colombier #include "screen.h"
26*96cbc34fSDavid du Colombier #include "keyboard.h"
27*96cbc34fSDavid du Colombier #include "keycodes.h"
28*96cbc34fSDavid du Colombier
29*96cbc34fSDavid du Colombier #define rWindowResource 128
30*96cbc34fSDavid du Colombier
31*96cbc34fSDavid du Colombier #define topLeft(r) (((Point *) &(r))[0])
32*96cbc34fSDavid du Colombier #define botRight(r) (((Point *) &(r))[1])
33*96cbc34fSDavid du Colombier
34*96cbc34fSDavid du Colombier extern int mousequeue;
35*96cbc34fSDavid du Colombier static int depth;
36*96cbc34fSDavid du Colombier Boolean gDone;
37*96cbc34fSDavid du Colombier RgnHandle gCursorRegionHdl;
38*96cbc34fSDavid du Colombier
39*96cbc34fSDavid du Colombier Memimage *gscreen;
40*96cbc34fSDavid du Colombier Screeninfo screen;
41*96cbc34fSDavid du Colombier
42*96cbc34fSDavid du Colombier static int readybit;
43*96cbc34fSDavid du Colombier static Rendez rend;
44*96cbc34fSDavid du Colombier
45*96cbc34fSDavid du Colombier ///
46*96cbc34fSDavid du Colombier // menu
47*96cbc34fSDavid du Colombier //
48*96cbc34fSDavid du Colombier static MenuRef windMenu;
49*96cbc34fSDavid du Colombier static MenuRef viewMenu;
50*96cbc34fSDavid du Colombier
51*96cbc34fSDavid du Colombier enum {
52*96cbc34fSDavid du Colombier kQuitCmd = 1,
53*96cbc34fSDavid du Colombier kFullScreenCmd = 2,
54*96cbc34fSDavid du Colombier };
55*96cbc34fSDavid du Colombier
56*96cbc34fSDavid du Colombier static WindowGroupRef winGroup = NULL;
57*96cbc34fSDavid du Colombier static WindowRef theWindow = NULL;
58*96cbc34fSDavid du Colombier static CGContextRef context;
59*96cbc34fSDavid du Colombier static CGDataProviderRef dataProviderRef;
60*96cbc34fSDavid du Colombier static CGImageRef fullScreenImage;
61*96cbc34fSDavid du Colombier static CGRect devRect;
62*96cbc34fSDavid du Colombier static CGRect bounds;
63*96cbc34fSDavid du Colombier static PasteboardRef appleclip;
64*96cbc34fSDavid du Colombier static _Rect winRect;
65*96cbc34fSDavid du Colombier
66*96cbc34fSDavid du Colombier Boolean altPressed = false;
67*96cbc34fSDavid du Colombier Boolean button2 = false;
68*96cbc34fSDavid du Colombier Boolean button3 = false;
69*96cbc34fSDavid du Colombier
70*96cbc34fSDavid du Colombier
71*96cbc34fSDavid du Colombier static int
isready(void * a)72*96cbc34fSDavid du Colombier isready(void*a)
73*96cbc34fSDavid du Colombier {
74*96cbc34fSDavid du Colombier return readybit;
75*96cbc34fSDavid du Colombier }
76*96cbc34fSDavid du Colombier
77*96cbc34fSDavid du Colombier CGContextRef QuartzContext;
78*96cbc34fSDavid du Colombier
79*96cbc34fSDavid du Colombier void winproc(void *a);
80*96cbc34fSDavid du Colombier
screeninit(void)81*96cbc34fSDavid du Colombier void screeninit(void)
82*96cbc34fSDavid du Colombier {
83*96cbc34fSDavid du Colombier int fmt;
84*96cbc34fSDavid du Colombier int dx, dy;
85*96cbc34fSDavid du Colombier ProcessSerialNumber psn = { 0, kCurrentProcess };
86*96cbc34fSDavid du Colombier TransformProcessType(&psn, kProcessTransformToForegroundApplication);
87*96cbc34fSDavid du Colombier SetFrontProcess(&psn);
88*96cbc34fSDavid du Colombier
89*96cbc34fSDavid du Colombier memimageinit();
90*96cbc34fSDavid du Colombier depth = 32; // That's all this code deals with for now
91*96cbc34fSDavid du Colombier screen.depth = 32;
92*96cbc34fSDavid du Colombier fmt = XBGR32; //XRGB32;
93*96cbc34fSDavid du Colombier
94*96cbc34fSDavid du Colombier devRect = CGDisplayBounds(CGMainDisplayID());
95*96cbc34fSDavid du Colombier // devRect.origin.x = 0;
96*96cbc34fSDavid du Colombier // devRect.origin.y = 0;
97*96cbc34fSDavid du Colombier // devRect.size.width = 1024;
98*96cbc34fSDavid du Colombier // devRect.size.height = 768;
99*96cbc34fSDavid du Colombier dx = devRect.size.width;
100*96cbc34fSDavid du Colombier dy = devRect.size.height;
101*96cbc34fSDavid du Colombier
102*96cbc34fSDavid du Colombier gscreen = allocmemimage(Rect(0,0,dx,dy), fmt);
103*96cbc34fSDavid du Colombier dataProviderRef = CGDataProviderCreateWithData(0, gscreen->data->bdata,
104*96cbc34fSDavid du Colombier dx * dy * 4, 0);
105*96cbc34fSDavid du Colombier fullScreenImage = CGImageCreate(dx, dy, 8, 32, dx * 4,
106*96cbc34fSDavid du Colombier CGColorSpaceCreateDeviceRGB(),
107*96cbc34fSDavid du Colombier kCGImageAlphaNoneSkipLast,
108*96cbc34fSDavid du Colombier dataProviderRef, 0, 0, kCGRenderingIntentDefault);
109*96cbc34fSDavid du Colombier
110*96cbc34fSDavid du Colombier kproc("osxscreen", winproc, 0);
111*96cbc34fSDavid du Colombier ksleep(&rend, isready, 0);
112*96cbc34fSDavid du Colombier }
113*96cbc34fSDavid du Colombier
114*96cbc34fSDavid du Colombier // No wonder Apple sells so many wide displays!
115*96cbc34fSDavid du Colombier static OSStatus ApplicationQuitEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
116*96cbc34fSDavid du Colombier static OSStatus MainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
117*96cbc34fSDavid du Colombier static OSStatus MainWindowCommandHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData);
118*96cbc34fSDavid du Colombier
119*96cbc34fSDavid du Colombier void
window_resized()120*96cbc34fSDavid du Colombier window_resized()
121*96cbc34fSDavid du Colombier {
122*96cbc34fSDavid du Colombier GetWindowBounds(theWindow, kWindowContentRgn, &winRect );
123*96cbc34fSDavid du Colombier
124*96cbc34fSDavid du Colombier bounds = CGRectMake(0, 0, winRect.right-winRect.left, winRect.bottom - winRect.top);
125*96cbc34fSDavid du Colombier }
126*96cbc34fSDavid du Colombier
127*96cbc34fSDavid du Colombier
winproc(void * a)128*96cbc34fSDavid du Colombier void winproc(void *a)
129*96cbc34fSDavid du Colombier {
130*96cbc34fSDavid du Colombier winRect.left = 30;
131*96cbc34fSDavid du Colombier winRect.top = 60;
132*96cbc34fSDavid du Colombier winRect.bottom = (devRect.size.height * 0.75) + winRect.top;
133*96cbc34fSDavid du Colombier winRect.right = (devRect.size.width * 0.75) + winRect.left;
134*96cbc34fSDavid du Colombier
135*96cbc34fSDavid du Colombier ClearMenuBar();
136*96cbc34fSDavid du Colombier InitCursor();
137*96cbc34fSDavid du Colombier
138*96cbc34fSDavid du Colombier CreateStandardWindowMenu(0, &windMenu);
139*96cbc34fSDavid du Colombier InsertMenu(windMenu, 0);
140*96cbc34fSDavid du Colombier
141*96cbc34fSDavid du Colombier MenuItemIndex index;
142*96cbc34fSDavid du Colombier CreateNewMenu(1004, 0, &viewMenu);
143*96cbc34fSDavid du Colombier SetMenuTitleWithCFString(viewMenu, CFSTR("View"));
144*96cbc34fSDavid du Colombier AppendMenuItemTextWithCFString(viewMenu, CFSTR("Full Screen"), 0,
145*96cbc34fSDavid du Colombier kFullScreenCmd, &index);
146*96cbc34fSDavid du Colombier SetMenuItemCommandKey(viewMenu, index, 0, 'F');
147*96cbc34fSDavid du Colombier InsertMenu(viewMenu, GetMenuID(windMenu));
148*96cbc34fSDavid du Colombier
149*96cbc34fSDavid du Colombier DrawMenuBar();
150*96cbc34fSDavid du Colombier uint32_t windowAttrs = 0
151*96cbc34fSDavid du Colombier | kWindowCloseBoxAttribute
152*96cbc34fSDavid du Colombier | kWindowCollapseBoxAttribute
153*96cbc34fSDavid du Colombier | kWindowResizableAttribute
154*96cbc34fSDavid du Colombier | kWindowStandardHandlerAttribute
155*96cbc34fSDavid du Colombier | kWindowFullZoomAttribute
156*96cbc34fSDavid du Colombier ;
157*96cbc34fSDavid du Colombier
158*96cbc34fSDavid du Colombier CreateNewWindow(kDocumentWindowClass, windowAttrs, &winRect, &theWindow);
159*96cbc34fSDavid du Colombier CreateWindowGroup(0, &winGroup);
160*96cbc34fSDavid du Colombier SetWindowGroup(theWindow, winGroup);
161*96cbc34fSDavid du Colombier
162*96cbc34fSDavid du Colombier SetWindowTitleWithCFString(theWindow, CFSTR("Drawterm"));
163*96cbc34fSDavid du Colombier
164*96cbc34fSDavid du Colombier if(PasteboardCreate(kPasteboardClipboard, &appleclip) != noErr)
165*96cbc34fSDavid du Colombier sysfatal("pasteboard create failed");
166*96cbc34fSDavid du Colombier
167*96cbc34fSDavid du Colombier const EventTypeSpec quit_events[] = {
168*96cbc34fSDavid du Colombier { kEventClassApplication, kEventAppQuit }
169*96cbc34fSDavid du Colombier };
170*96cbc34fSDavid du Colombier const EventTypeSpec commands[] = {
171*96cbc34fSDavid du Colombier { kEventClassWindow, kEventWindowClosed },
172*96cbc34fSDavid du Colombier { kEventClassWindow, kEventWindowBoundsChanged },
173*96cbc34fSDavid du Colombier { kEventClassCommand, kEventCommandProcess }
174*96cbc34fSDavid du Colombier };
175*96cbc34fSDavid du Colombier const EventTypeSpec events[] = {
176*96cbc34fSDavid du Colombier { kEventClassKeyboard, kEventRawKeyDown },
177*96cbc34fSDavid du Colombier { kEventClassKeyboard, kEventRawKeyModifiersChanged },
178*96cbc34fSDavid du Colombier { kEventClassKeyboard, kEventRawKeyRepeat },
179*96cbc34fSDavid du Colombier { kEventClassMouse, kEventMouseDown },
180*96cbc34fSDavid du Colombier { kEventClassMouse, kEventMouseUp },
181*96cbc34fSDavid du Colombier { kEventClassMouse, kEventMouseMoved },
182*96cbc34fSDavid du Colombier { kEventClassMouse, kEventMouseDragged },
183*96cbc34fSDavid du Colombier { kEventClassMouse, kEventMouseWheelMoved },
184*96cbc34fSDavid du Colombier };
185*96cbc34fSDavid du Colombier
186*96cbc34fSDavid du Colombier InstallApplicationEventHandler (
187*96cbc34fSDavid du Colombier NewEventHandlerUPP (ApplicationQuitEventHandler),
188*96cbc34fSDavid du Colombier GetEventTypeCount(quit_events),
189*96cbc34fSDavid du Colombier quit_events,
190*96cbc34fSDavid du Colombier NULL,
191*96cbc34fSDavid du Colombier NULL);
192*96cbc34fSDavid du Colombier
193*96cbc34fSDavid du Colombier InstallApplicationEventHandler (
194*96cbc34fSDavid du Colombier NewEventHandlerUPP (MainWindowEventHandler),
195*96cbc34fSDavid du Colombier GetEventTypeCount(events),
196*96cbc34fSDavid du Colombier events,
197*96cbc34fSDavid du Colombier NULL,
198*96cbc34fSDavid du Colombier NULL);
199*96cbc34fSDavid du Colombier InstallWindowEventHandler (
200*96cbc34fSDavid du Colombier theWindow,
201*96cbc34fSDavid du Colombier NewEventHandlerUPP (MainWindowCommandHandler),
202*96cbc34fSDavid du Colombier GetEventTypeCount(commands),
203*96cbc34fSDavid du Colombier commands,
204*96cbc34fSDavid du Colombier theWindow,
205*96cbc34fSDavid du Colombier NULL);
206*96cbc34fSDavid du Colombier
207*96cbc34fSDavid du Colombier ShowWindow(theWindow);
208*96cbc34fSDavid du Colombier ShowMenuBar();
209*96cbc34fSDavid du Colombier window_resized();
210*96cbc34fSDavid du Colombier SelectWindow(theWindow);
211*96cbc34fSDavid du Colombier terminit();
212*96cbc34fSDavid du Colombier // Run the event loop
213*96cbc34fSDavid du Colombier readybit = 1;
214*96cbc34fSDavid du Colombier wakeup(&rend);
215*96cbc34fSDavid du Colombier RunApplicationEventLoop();
216*96cbc34fSDavid du Colombier
217*96cbc34fSDavid du Colombier }
218*96cbc34fSDavid du Colombier
convert_key(UInt32 key,UInt32 charcode)219*96cbc34fSDavid du Colombier static inline int convert_key(UInt32 key, UInt32 charcode)
220*96cbc34fSDavid du Colombier {
221*96cbc34fSDavid du Colombier switch(key) {
222*96cbc34fSDavid du Colombier case QZ_IBOOK_ENTER:
223*96cbc34fSDavid du Colombier case QZ_RETURN: return '\n';
224*96cbc34fSDavid du Colombier case QZ_ESCAPE: return 27;
225*96cbc34fSDavid du Colombier case QZ_BACKSPACE: return '\b';
226*96cbc34fSDavid du Colombier case QZ_LALT: return Kalt;
227*96cbc34fSDavid du Colombier case QZ_LCTRL: return Kctl;
228*96cbc34fSDavid du Colombier case QZ_LSHIFT: return Kshift;
229*96cbc34fSDavid du Colombier case QZ_F1: return KF+1;
230*96cbc34fSDavid du Colombier case QZ_F2: return KF+2;
231*96cbc34fSDavid du Colombier case QZ_F3: return KF+3;
232*96cbc34fSDavid du Colombier case QZ_F4: return KF+4;
233*96cbc34fSDavid du Colombier case QZ_F5: return KF+5;
234*96cbc34fSDavid du Colombier case QZ_F6: return KF+6;
235*96cbc34fSDavid du Colombier case QZ_F7: return KF+7;
236*96cbc34fSDavid du Colombier case QZ_F8: return KF+8;
237*96cbc34fSDavid du Colombier case QZ_F9: return KF+9;
238*96cbc34fSDavid du Colombier case QZ_F10: return KF+10;
239*96cbc34fSDavid du Colombier case QZ_F11: return KF+11;
240*96cbc34fSDavid du Colombier case QZ_F12: return KF+12;
241*96cbc34fSDavid du Colombier case QZ_INSERT: return Kins;
242*96cbc34fSDavid du Colombier case QZ_DELETE: return 0x7F;
243*96cbc34fSDavid du Colombier case QZ_HOME: return Khome;
244*96cbc34fSDavid du Colombier case QZ_END: return Kend;
245*96cbc34fSDavid du Colombier case QZ_KP_PLUS: return '+';
246*96cbc34fSDavid du Colombier case QZ_KP_MINUS: return '-';
247*96cbc34fSDavid du Colombier case QZ_TAB: return '\t';
248*96cbc34fSDavid du Colombier case QZ_PAGEUP: return Kpgup;
249*96cbc34fSDavid du Colombier case QZ_PAGEDOWN: return Kpgdown;
250*96cbc34fSDavid du Colombier case QZ_UP: return Kup;
251*96cbc34fSDavid du Colombier case QZ_DOWN: return Kdown;
252*96cbc34fSDavid du Colombier case QZ_LEFT: return Kleft;
253*96cbc34fSDavid du Colombier case QZ_RIGHT: return Kright;
254*96cbc34fSDavid du Colombier case QZ_KP_MULTIPLY: return '*';
255*96cbc34fSDavid du Colombier case QZ_KP_DIVIDE: return '/';
256*96cbc34fSDavid du Colombier case QZ_KP_ENTER: return '\n';
257*96cbc34fSDavid du Colombier case QZ_KP_PERIOD: return '.';
258*96cbc34fSDavid du Colombier case QZ_KP0: return '0';
259*96cbc34fSDavid du Colombier case QZ_KP1: return '1';
260*96cbc34fSDavid du Colombier case QZ_KP2: return '2';
261*96cbc34fSDavid du Colombier case QZ_KP3: return '3';
262*96cbc34fSDavid du Colombier case QZ_KP4: return '4';
263*96cbc34fSDavid du Colombier case QZ_KP5: return '5';
264*96cbc34fSDavid du Colombier case QZ_KP6: return '6';
265*96cbc34fSDavid du Colombier case QZ_KP7: return '7';
266*96cbc34fSDavid du Colombier case QZ_KP8: return '8';
267*96cbc34fSDavid du Colombier case QZ_KP9: return '9';
268*96cbc34fSDavid du Colombier default: return charcode;
269*96cbc34fSDavid du Colombier }
270*96cbc34fSDavid du Colombier }
271*96cbc34fSDavid du Colombier
272*96cbc34fSDavid du Colombier void
sendbuttons(int b,int x,int y)273*96cbc34fSDavid du Colombier sendbuttons(int b, int x, int y)
274*96cbc34fSDavid du Colombier {
275*96cbc34fSDavid du Colombier int i;
276*96cbc34fSDavid du Colombier lock(&mouse.lk);
277*96cbc34fSDavid du Colombier i = mouse.wi;
278*96cbc34fSDavid du Colombier if(mousequeue) {
279*96cbc34fSDavid du Colombier if(i == mouse.ri || mouse.lastb != b || mouse.trans) {
280*96cbc34fSDavid du Colombier mouse.wi = (i+1)%Mousequeue;
281*96cbc34fSDavid du Colombier if(mouse.wi == mouse.ri)
282*96cbc34fSDavid du Colombier mouse.ri = (mouse.ri+1)%Mousequeue;
283*96cbc34fSDavid du Colombier mouse.trans = mouse.lastb != b;
284*96cbc34fSDavid du Colombier } else {
285*96cbc34fSDavid du Colombier i = (i-1+Mousequeue)%Mousequeue;
286*96cbc34fSDavid du Colombier }
287*96cbc34fSDavid du Colombier } else {
288*96cbc34fSDavid du Colombier mouse.wi = (i+1)%Mousequeue;
289*96cbc34fSDavid du Colombier mouse.ri = i;
290*96cbc34fSDavid du Colombier }
291*96cbc34fSDavid du Colombier mouse.queue[i].xy.x = x;
292*96cbc34fSDavid du Colombier mouse.queue[i].xy.y = y;
293*96cbc34fSDavid du Colombier mouse.queue[i].buttons = b;
294*96cbc34fSDavid du Colombier mouse.queue[i].msec = ticks();
295*96cbc34fSDavid du Colombier mouse.lastb = b;
296*96cbc34fSDavid du Colombier unlock(&mouse.lk);
297*96cbc34fSDavid du Colombier wakeup(&mouse.r);
298*96cbc34fSDavid du Colombier }
299*96cbc34fSDavid du Colombier
300*96cbc34fSDavid du Colombier static Ptr fullScreenRestore;
301*96cbc34fSDavid du Colombier static int amFullScreen = 0;
302*96cbc34fSDavid du Colombier static WindowRef oldWindow = NULL;
303*96cbc34fSDavid du Colombier
304*96cbc34fSDavid du Colombier static void
leave_full_screen()305*96cbc34fSDavid du Colombier leave_full_screen()
306*96cbc34fSDavid du Colombier {
307*96cbc34fSDavid du Colombier if (amFullScreen) {
308*96cbc34fSDavid du Colombier EndFullScreen(fullScreenRestore, 0);
309*96cbc34fSDavid du Colombier theWindow = oldWindow;
310*96cbc34fSDavid du Colombier ShowWindow(theWindow);
311*96cbc34fSDavid du Colombier amFullScreen = 0;
312*96cbc34fSDavid du Colombier window_resized();
313*96cbc34fSDavid du Colombier Rectangle rect = { { 0, 0 },
314*96cbc34fSDavid du Colombier { bounds.size.width,
315*96cbc34fSDavid du Colombier bounds.size.height} };
316*96cbc34fSDavid du Colombier drawqlock();
317*96cbc34fSDavid du Colombier flushmemscreen(rect);
318*96cbc34fSDavid du Colombier drawqunlock();
319*96cbc34fSDavid du Colombier }
320*96cbc34fSDavid du Colombier }
321*96cbc34fSDavid du Colombier
322*96cbc34fSDavid du Colombier static void
full_screen()323*96cbc34fSDavid du Colombier full_screen()
324*96cbc34fSDavid du Colombier {
325*96cbc34fSDavid du Colombier if (!amFullScreen) {
326*96cbc34fSDavid du Colombier oldWindow = theWindow;
327*96cbc34fSDavid du Colombier HideWindow(theWindow);
328*96cbc34fSDavid du Colombier BeginFullScreen(&fullScreenRestore, 0, 0, 0, &theWindow, 0, 0);
329*96cbc34fSDavid du Colombier amFullScreen = 1;
330*96cbc34fSDavid du Colombier window_resized();
331*96cbc34fSDavid du Colombier Rectangle rect = { { 0, 0 },
332*96cbc34fSDavid du Colombier { bounds.size.width,
333*96cbc34fSDavid du Colombier bounds.size.height} };
334*96cbc34fSDavid du Colombier drawqlock();
335*96cbc34fSDavid du Colombier flushmemscreen(rect);
336*96cbc34fSDavid du Colombier drawqunlock();
337*96cbc34fSDavid du Colombier }
338*96cbc34fSDavid du Colombier }
339*96cbc34fSDavid du Colombier
340*96cbc34fSDavid du Colombier // catch quit events to handle quits from menu, Cmd+Q, applescript, and task switcher
ApplicationQuitEventHandler(EventHandlerCallRef nextHandler,EventRef event,void * userData)341*96cbc34fSDavid du Colombier static OSStatus ApplicationQuitEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
342*96cbc34fSDavid du Colombier {
343*96cbc34fSDavid du Colombier exit(0);
344*96cbc34fSDavid du Colombier // QuitApplicationEventLoop();
345*96cbc34fSDavid du Colombier return noErr;
346*96cbc34fSDavid du Colombier }
347*96cbc34fSDavid du Colombier
MainWindowEventHandler(EventHandlerCallRef nextHandler,EventRef event,void * userData)348*96cbc34fSDavid du Colombier static OSStatus MainWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData)
349*96cbc34fSDavid du Colombier {
350*96cbc34fSDavid du Colombier OSStatus result = noErr;
351*96cbc34fSDavid du Colombier result = CallNextEventHandler(nextHandler, event);
352*96cbc34fSDavid du Colombier UInt32 class = GetEventClass (event);
353*96cbc34fSDavid du Colombier UInt32 kind = GetEventKind (event);
354*96cbc34fSDavid du Colombier static uint32_t mousebuttons = 0; // bitmask of buttons currently down
355*96cbc34fSDavid du Colombier static uint32_t mouseX = 0;
356*96cbc34fSDavid du Colombier static uint32_t mouseY = 0;
357*96cbc34fSDavid du Colombier
358*96cbc34fSDavid du Colombier if(class == kEventClassKeyboard) {
359*96cbc34fSDavid du Colombier char macCharCodes;
360*96cbc34fSDavid du Colombier UInt32 macKeyCode;
361*96cbc34fSDavid du Colombier UInt32 macKeyModifiers;
362*96cbc34fSDavid du Colombier
363*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar,
364*96cbc34fSDavid du Colombier NULL, sizeof(macCharCodes), NULL, &macCharCodes);
365*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL,
366*96cbc34fSDavid du Colombier sizeof(macKeyCode), NULL, &macKeyCode);
367*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL,
368*96cbc34fSDavid du Colombier sizeof(macKeyModifiers), NULL, &macKeyModifiers);
369*96cbc34fSDavid du Colombier switch(kind) {
370*96cbc34fSDavid du Colombier case kEventRawKeyModifiersChanged:
371*96cbc34fSDavid du Colombier if (macKeyModifiers == (controlKey | optionKey)) leave_full_screen();
372*96cbc34fSDavid du Colombier
373*96cbc34fSDavid du Colombier switch(macKeyModifiers & (optionKey | cmdKey)) {
374*96cbc34fSDavid du Colombier case (optionKey | cmdKey):
375*96cbc34fSDavid du Colombier /* due to chording we need to handle the case when both
376*96cbc34fSDavid du Colombier * modifier keys are pressed at the same time.
377*96cbc34fSDavid du Colombier * currently it's only 2-3 snarf and the 3-2 noop
378*96cbc34fSDavid du Colombier */
379*96cbc34fSDavid du Colombier altPressed = true;
380*96cbc34fSDavid du Colombier if(mousebuttons & 1 || mousebuttons & 2 || mousebuttons & 4) {
381*96cbc34fSDavid du Colombier mousebuttons |= 2; /* set button 2 */
382*96cbc34fSDavid du Colombier mousebuttons |= 4; /* set button 3 */
383*96cbc34fSDavid du Colombier button2 = true;
384*96cbc34fSDavid du Colombier button3 = true;
385*96cbc34fSDavid du Colombier sendbuttons(mousebuttons, mouseX, mouseY);
386*96cbc34fSDavid du Colombier }
387*96cbc34fSDavid du Colombier break;
388*96cbc34fSDavid du Colombier case optionKey:
389*96cbc34fSDavid du Colombier altPressed = true;
390*96cbc34fSDavid du Colombier if(mousebuttons & 1 || mousebuttons & 4) {
391*96cbc34fSDavid du Colombier mousebuttons |= 2; /* set button 2 */
392*96cbc34fSDavid du Colombier button2 = true;
393*96cbc34fSDavid du Colombier sendbuttons(mousebuttons, mouseX, mouseY);
394*96cbc34fSDavid du Colombier }
395*96cbc34fSDavid du Colombier break;
396*96cbc34fSDavid du Colombier case cmdKey:
397*96cbc34fSDavid du Colombier if(mousebuttons & 1 || mousebuttons & 2) {
398*96cbc34fSDavid du Colombier mousebuttons |= 4; /* set button 3 */
399*96cbc34fSDavid du Colombier button3 = true;
400*96cbc34fSDavid du Colombier sendbuttons(mousebuttons, mouseX, mouseY);
401*96cbc34fSDavid du Colombier }
402*96cbc34fSDavid du Colombier break;
403*96cbc34fSDavid du Colombier case 0:
404*96cbc34fSDavid du Colombier default:
405*96cbc34fSDavid du Colombier if(button2 || button3) {
406*96cbc34fSDavid du Colombier if(button2) {
407*96cbc34fSDavid du Colombier mousebuttons &= ~2; /* clear button 2 */
408*96cbc34fSDavid du Colombier button2 = false;
409*96cbc34fSDavid du Colombier altPressed = false;
410*96cbc34fSDavid du Colombier }
411*96cbc34fSDavid du Colombier if(button3) {
412*96cbc34fSDavid du Colombier mousebuttons &= ~4; /* clear button 3 */
413*96cbc34fSDavid du Colombier button3 = false;
414*96cbc34fSDavid du Colombier }
415*96cbc34fSDavid du Colombier sendbuttons(mousebuttons, mouseX, mouseY);
416*96cbc34fSDavid du Colombier }
417*96cbc34fSDavid du Colombier if(altPressed) {
418*96cbc34fSDavid du Colombier kbdputc(kbdq, Kalt);
419*96cbc34fSDavid du Colombier altPressed = false;
420*96cbc34fSDavid du Colombier }
421*96cbc34fSDavid du Colombier break;
422*96cbc34fSDavid du Colombier }
423*96cbc34fSDavid du Colombier break;
424*96cbc34fSDavid du Colombier case kEventRawKeyDown:
425*96cbc34fSDavid du Colombier case kEventRawKeyRepeat:
426*96cbc34fSDavid du Colombier if(macKeyModifiers != cmdKey) {
427*96cbc34fSDavid du Colombier int key = convert_key(macKeyCode, macCharCodes);
428*96cbc34fSDavid du Colombier if (key != -1) kbdputc(kbdq, key);
429*96cbc34fSDavid du Colombier } else
430*96cbc34fSDavid du Colombier result = eventNotHandledErr;
431*96cbc34fSDavid du Colombier break;
432*96cbc34fSDavid du Colombier default:
433*96cbc34fSDavid du Colombier break;
434*96cbc34fSDavid du Colombier }
435*96cbc34fSDavid du Colombier }
436*96cbc34fSDavid du Colombier else if(class == kEventClassMouse) {
437*96cbc34fSDavid du Colombier _Point mousePos;
438*96cbc34fSDavid du Colombier
439*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
440*96cbc34fSDavid du Colombier 0, sizeof mousePos, 0, &mousePos);
441*96cbc34fSDavid du Colombier
442*96cbc34fSDavid du Colombier switch (kind) {
443*96cbc34fSDavid du Colombier case kEventMouseWheelMoved:
444*96cbc34fSDavid du Colombier {
445*96cbc34fSDavid du Colombier int32_t wheeldelta;
446*96cbc34fSDavid du Colombier GetEventParameter(event,kEventParamMouseWheelDelta,typeSInt32,
447*96cbc34fSDavid du Colombier 0,sizeof(wheeldelta), 0, &wheeldelta);
448*96cbc34fSDavid du Colombier mouseX = mousePos.h - winRect.left;
449*96cbc34fSDavid du Colombier mouseY = mousePos.v - winRect.top;
450*96cbc34fSDavid du Colombier sendbuttons(wheeldelta>0 ? 8 : 16, mouseX, mouseY);
451*96cbc34fSDavid du Colombier break;
452*96cbc34fSDavid du Colombier }
453*96cbc34fSDavid du Colombier case kEventMouseUp:
454*96cbc34fSDavid du Colombier case kEventMouseDown:
455*96cbc34fSDavid du Colombier {
456*96cbc34fSDavid du Colombier uint32_t buttons;
457*96cbc34fSDavid du Colombier uint32_t modifiers;
458*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamKeyModifiers, typeUInt32,
459*96cbc34fSDavid du Colombier 0, sizeof(modifiers), 0, &modifiers);
460*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamMouseChord, typeUInt32,
461*96cbc34fSDavid du Colombier 0, sizeof buttons, 0, &buttons);
462*96cbc34fSDavid du Colombier /* simulate other buttons via alt/apple key. like x11 */
463*96cbc34fSDavid du Colombier if(modifiers & optionKey) {
464*96cbc34fSDavid du Colombier mousebuttons = ((buttons & 1) ? 2 : 0);
465*96cbc34fSDavid du Colombier altPressed = false;
466*96cbc34fSDavid du Colombier } else if(modifiers & cmdKey)
467*96cbc34fSDavid du Colombier mousebuttons = ((buttons & 1) ? 4 : 0);
468*96cbc34fSDavid du Colombier else
469*96cbc34fSDavid du Colombier mousebuttons = (buttons & 1);
470*96cbc34fSDavid du Colombier
471*96cbc34fSDavid du Colombier mousebuttons |= ((buttons & 2)<<1);
472*96cbc34fSDavid du Colombier mousebuttons |= ((buttons & 4)>>1);
473*96cbc34fSDavid du Colombier
474*96cbc34fSDavid du Colombier } /* Fallthrough */
475*96cbc34fSDavid du Colombier case kEventMouseMoved:
476*96cbc34fSDavid du Colombier case kEventMouseDragged:
477*96cbc34fSDavid du Colombier mouseX = mousePos.h - winRect.left;
478*96cbc34fSDavid du Colombier mouseY = mousePos.v - winRect.top;
479*96cbc34fSDavid du Colombier sendbuttons(mousebuttons, mouseX, mouseY);
480*96cbc34fSDavid du Colombier break;
481*96cbc34fSDavid du Colombier default:
482*96cbc34fSDavid du Colombier result = eventNotHandledErr;
483*96cbc34fSDavid du Colombier break;
484*96cbc34fSDavid du Colombier }
485*96cbc34fSDavid du Colombier }
486*96cbc34fSDavid du Colombier return result;
487*96cbc34fSDavid du Colombier }
488*96cbc34fSDavid du Colombier
489*96cbc34fSDavid du Colombier
490*96cbc34fSDavid du Colombier //default window command handler (from menus)
MainWindowCommandHandler(EventHandlerCallRef nextHandler,EventRef event,void * userData)491*96cbc34fSDavid du Colombier static OSStatus MainWindowCommandHandler(EventHandlerCallRef nextHandler,
492*96cbc34fSDavid du Colombier EventRef event, void *userData)
493*96cbc34fSDavid du Colombier {
494*96cbc34fSDavid du Colombier OSStatus result = noErr;
495*96cbc34fSDavid du Colombier UInt32 class = GetEventClass (event);
496*96cbc34fSDavid du Colombier UInt32 kind = GetEventKind (event);
497*96cbc34fSDavid du Colombier
498*96cbc34fSDavid du Colombier result = CallNextEventHandler(nextHandler, event);
499*96cbc34fSDavid du Colombier
500*96cbc34fSDavid du Colombier if(class == kEventClassCommand)
501*96cbc34fSDavid du Colombier {
502*96cbc34fSDavid du Colombier HICommand theHICommand;
503*96cbc34fSDavid du Colombier GetEventParameter( event, kEventParamDirectObject, typeHICommand,
504*96cbc34fSDavid du Colombier NULL, sizeof( HICommand ), NULL, &theHICommand );
505*96cbc34fSDavid du Colombier
506*96cbc34fSDavid du Colombier switch ( theHICommand.commandID )
507*96cbc34fSDavid du Colombier {
508*96cbc34fSDavid du Colombier case kHICommandQuit:
509*96cbc34fSDavid du Colombier exit(0);
510*96cbc34fSDavid du Colombier break;
511*96cbc34fSDavid du Colombier
512*96cbc34fSDavid du Colombier case kFullScreenCmd:
513*96cbc34fSDavid du Colombier full_screen();
514*96cbc34fSDavid du Colombier break;
515*96cbc34fSDavid du Colombier
516*96cbc34fSDavid du Colombier default:
517*96cbc34fSDavid du Colombier result = eventNotHandledErr;
518*96cbc34fSDavid du Colombier break;
519*96cbc34fSDavid du Colombier }
520*96cbc34fSDavid du Colombier }
521*96cbc34fSDavid du Colombier else if(class == kEventClassWindow)
522*96cbc34fSDavid du Colombier {
523*96cbc34fSDavid du Colombier WindowRef window;
524*96cbc34fSDavid du Colombier _Rect rectPort = {0,0,0,0};
525*96cbc34fSDavid du Colombier
526*96cbc34fSDavid du Colombier GetEventParameter(event, kEventParamDirectObject, typeWindowRef,
527*96cbc34fSDavid du Colombier NULL, sizeof(WindowRef), NULL, &window);
528*96cbc34fSDavid du Colombier
529*96cbc34fSDavid du Colombier if(window)
530*96cbc34fSDavid du Colombier {
531*96cbc34fSDavid du Colombier GetPortBounds(GetWindowPort(window), &rectPort);
532*96cbc34fSDavid du Colombier }
533*96cbc34fSDavid du Colombier
534*96cbc34fSDavid du Colombier switch (kind)
535*96cbc34fSDavid du Colombier {
536*96cbc34fSDavid du Colombier case kEventWindowClosed:
537*96cbc34fSDavid du Colombier // send a quit carbon event instead of directly calling cleanexit
538*96cbc34fSDavid du Colombier // so that all quits are done in ApplicationQuitEventHandler
539*96cbc34fSDavid du Colombier {
540*96cbc34fSDavid du Colombier EventRef quitEvent;
541*96cbc34fSDavid du Colombier CreateEvent(NULL,
542*96cbc34fSDavid du Colombier kEventClassApplication,
543*96cbc34fSDavid du Colombier kEventAppQuit,
544*96cbc34fSDavid du Colombier 0,
545*96cbc34fSDavid du Colombier kEventAttributeNone,
546*96cbc34fSDavid du Colombier &quitEvent);
547*96cbc34fSDavid du Colombier EventTargetRef target;
548*96cbc34fSDavid du Colombier target = GetApplicationEventTarget();
549*96cbc34fSDavid du Colombier SendEventToEventTarget(quitEvent, target);
550*96cbc34fSDavid du Colombier }
551*96cbc34fSDavid du Colombier break;
552*96cbc34fSDavid du Colombier
553*96cbc34fSDavid du Colombier //resize window
554*96cbc34fSDavid du Colombier case kEventWindowBoundsChanged:
555*96cbc34fSDavid du Colombier window_resized();
556*96cbc34fSDavid du Colombier Rectangle rect = { { 0, 0 },
557*96cbc34fSDavid du Colombier { bounds.size.width,
558*96cbc34fSDavid du Colombier bounds.size.height} };
559*96cbc34fSDavid du Colombier drawqlock();
560*96cbc34fSDavid du Colombier flushmemscreen(rect);
561*96cbc34fSDavid du Colombier drawqunlock();
562*96cbc34fSDavid du Colombier break;
563*96cbc34fSDavid du Colombier
564*96cbc34fSDavid du Colombier default:
565*96cbc34fSDavid du Colombier result = eventNotHandledErr;
566*96cbc34fSDavid du Colombier break;
567*96cbc34fSDavid du Colombier }
568*96cbc34fSDavid du Colombier }
569*96cbc34fSDavid du Colombier
570*96cbc34fSDavid du Colombier return result;
571*96cbc34fSDavid du Colombier }
572*96cbc34fSDavid du Colombier
573*96cbc34fSDavid du Colombier void
flushmemscreen(Rectangle r)574*96cbc34fSDavid du Colombier flushmemscreen(Rectangle r)
575*96cbc34fSDavid du Colombier {
576*96cbc34fSDavid du Colombier // sanity check. Trips from the initial "terminal"
577*96cbc34fSDavid du Colombier if (r.max.x < r.min.x || r.max.y < r.min.y) return;
578*96cbc34fSDavid du Colombier
579*96cbc34fSDavid du Colombier screenload(r, gscreen->depth, byteaddr(gscreen, ZP), ZP,
580*96cbc34fSDavid du Colombier gscreen->width*sizeof(ulong));
581*96cbc34fSDavid du Colombier }
582*96cbc34fSDavid du Colombier
583*96cbc34fSDavid du Colombier uchar*
attachscreen(Rectangle * r,ulong * chan,int * depth,int * width,int * softscreen,void ** X)584*96cbc34fSDavid du Colombier attachscreen(Rectangle *r, ulong *chan, int *depth, int *width, int *softscreen, void **X)
585*96cbc34fSDavid du Colombier {
586*96cbc34fSDavid du Colombier *r = gscreen->r;
587*96cbc34fSDavid du Colombier *chan = gscreen->chan;
588*96cbc34fSDavid du Colombier *depth = gscreen->depth;
589*96cbc34fSDavid du Colombier *width = gscreen->width;
590*96cbc34fSDavid du Colombier *softscreen = 1;
591*96cbc34fSDavid du Colombier
592*96cbc34fSDavid du Colombier return gscreen->data->bdata;
593*96cbc34fSDavid du Colombier }
594*96cbc34fSDavid du Colombier
595*96cbc34fSDavid du Colombier // PAL - no palette handling. Don't intend to either.
596*96cbc34fSDavid du Colombier void
getcolor(ulong i,ulong * r,ulong * g,ulong * b)597*96cbc34fSDavid du Colombier getcolor(ulong i, ulong *r, ulong *g, ulong *b)
598*96cbc34fSDavid du Colombier {
599*96cbc34fSDavid du Colombier
600*96cbc34fSDavid du Colombier // PAL: Certainly wrong to return a grayscale.
601*96cbc34fSDavid du Colombier *r = i;
602*96cbc34fSDavid du Colombier *g = i;
603*96cbc34fSDavid du Colombier *b = i;
604*96cbc34fSDavid du Colombier }
605*96cbc34fSDavid du Colombier
606*96cbc34fSDavid du Colombier void
setcolor(ulong index,ulong red,ulong green,ulong blue)607*96cbc34fSDavid du Colombier setcolor(ulong index, ulong red, ulong green, ulong blue)
608*96cbc34fSDavid du Colombier {
609*96cbc34fSDavid du Colombier assert(0);
610*96cbc34fSDavid du Colombier }
611*96cbc34fSDavid du Colombier
612*96cbc34fSDavid du Colombier
613*96cbc34fSDavid du Colombier static char snarf[3*SnarfSize+1];
614*96cbc34fSDavid du Colombier static Rune rsnarf[SnarfSize+1];
615*96cbc34fSDavid du Colombier
616*96cbc34fSDavid du Colombier char*
clipread(void)617*96cbc34fSDavid du Colombier clipread(void)
618*96cbc34fSDavid du Colombier {
619*96cbc34fSDavid du Colombier CFDataRef cfdata;
620*96cbc34fSDavid du Colombier OSStatus err = noErr;
621*96cbc34fSDavid du Colombier ItemCount nItems;
622*96cbc34fSDavid du Colombier
623*96cbc34fSDavid du Colombier // Wow. This is ridiculously complicated.
624*96cbc34fSDavid du Colombier PasteboardSynchronize(appleclip);
625*96cbc34fSDavid du Colombier if((err = PasteboardGetItemCount(appleclip, &nItems)) != noErr) {
626*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard GetItemCount failed - Error %d\n", err);
627*96cbc34fSDavid du Colombier return 0;
628*96cbc34fSDavid du Colombier }
629*96cbc34fSDavid du Colombier
630*96cbc34fSDavid du Colombier uint32_t i;
631*96cbc34fSDavid du Colombier // Yes, based at 1. Silly API.
632*96cbc34fSDavid du Colombier for(i = 1; i <= nItems; ++i) {
633*96cbc34fSDavid du Colombier PasteboardItemID itemID;
634*96cbc34fSDavid du Colombier CFArrayRef flavorTypeArray;
635*96cbc34fSDavid du Colombier CFIndex flavorCount;
636*96cbc34fSDavid du Colombier
637*96cbc34fSDavid du Colombier if((err = PasteboardGetItemIdentifier(appleclip, i, &itemID)) != noErr){
638*96cbc34fSDavid du Colombier fprint(2, "Can't get pasteboard item identifier: %d\n", err);
639*96cbc34fSDavid du Colombier return 0;
640*96cbc34fSDavid du Colombier }
641*96cbc34fSDavid du Colombier
642*96cbc34fSDavid du Colombier if((err = PasteboardCopyItemFlavors(appleclip, itemID, &flavorTypeArray))!=noErr){
643*96cbc34fSDavid du Colombier fprint(2, "Can't copy pasteboard item flavors: %d\n", err);
644*96cbc34fSDavid du Colombier return 0;
645*96cbc34fSDavid du Colombier }
646*96cbc34fSDavid du Colombier
647*96cbc34fSDavid du Colombier flavorCount = CFArrayGetCount(flavorTypeArray);
648*96cbc34fSDavid du Colombier CFIndex flavorIndex;
649*96cbc34fSDavid du Colombier for(flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex){
650*96cbc34fSDavid du Colombier CFStringRef flavorType;
651*96cbc34fSDavid du Colombier flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
652*96cbc34fSDavid du Colombier if (UTTypeConformsTo(flavorType, CFSTR("public.utf16-plain-text"))){
653*96cbc34fSDavid du Colombier if((err = PasteboardCopyItemFlavorData(appleclip, itemID,
654*96cbc34fSDavid du Colombier CFSTR("public.utf16-plain-text"), &cfdata)) != noErr){
655*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard CopyItem failed - Error %d\n", err);
656*96cbc34fSDavid du Colombier return 0;
657*96cbc34fSDavid du Colombier }
658*96cbc34fSDavid du Colombier CFIndex length = CFDataGetLength(cfdata);
659*96cbc34fSDavid du Colombier if (length > sizeof rsnarf) length = sizeof rsnarf;
660*96cbc34fSDavid du Colombier CFDataGetBytes(cfdata, CFRangeMake(0, length), (uint8_t *)rsnarf);
661*96cbc34fSDavid du Colombier snprint(snarf, sizeof snarf, "%.*S", length/sizeof(Rune), rsnarf);
662*96cbc34fSDavid du Colombier char *s = snarf;
663*96cbc34fSDavid du Colombier while (*s) {
664*96cbc34fSDavid du Colombier if (*s == '\r') *s = '\n';
665*96cbc34fSDavid du Colombier s++;
666*96cbc34fSDavid du Colombier }
667*96cbc34fSDavid du Colombier CFRelease(cfdata);
668*96cbc34fSDavid du Colombier return strdup(snarf);
669*96cbc34fSDavid du Colombier }
670*96cbc34fSDavid du Colombier }
671*96cbc34fSDavid du Colombier }
672*96cbc34fSDavid du Colombier return 0;
673*96cbc34fSDavid du Colombier }
674*96cbc34fSDavid du Colombier
675*96cbc34fSDavid du Colombier int
clipwrite(char * snarf)676*96cbc34fSDavid du Colombier clipwrite(char *snarf)
677*96cbc34fSDavid du Colombier {
678*96cbc34fSDavid du Colombier CFDataRef cfdata;
679*96cbc34fSDavid du Colombier PasteboardSyncFlags flags;
680*96cbc34fSDavid du Colombier
681*96cbc34fSDavid du Colombier runesnprint(rsnarf, nelem(rsnarf), "%s", snarf);
682*96cbc34fSDavid du Colombier if(PasteboardClear(appleclip) != noErr){
683*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard clear failed\n");
684*96cbc34fSDavid du Colombier return 0;
685*96cbc34fSDavid du Colombier }
686*96cbc34fSDavid du Colombier flags = PasteboardSynchronize(appleclip);
687*96cbc34fSDavid du Colombier if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){
688*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard cannot assert ownership\n");
689*96cbc34fSDavid du Colombier return 0;
690*96cbc34fSDavid du Colombier }
691*96cbc34fSDavid du Colombier cfdata = CFDataCreate(kCFAllocatorDefault,
692*96cbc34fSDavid du Colombier (uchar*)rsnarf, runestrlen(rsnarf)*2);
693*96cbc34fSDavid du Colombier if(cfdata == nil){
694*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard cfdatacreate failed\n");
695*96cbc34fSDavid du Colombier return 0;
696*96cbc34fSDavid du Colombier }
697*96cbc34fSDavid du Colombier if(PasteboardPutItemFlavor(appleclip, (PasteboardItemID)1,
698*96cbc34fSDavid du Colombier CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){
699*96cbc34fSDavid du Colombier fprint(2, "apple pasteboard putitem failed\n");
700*96cbc34fSDavid du Colombier CFRelease(cfdata);
701*96cbc34fSDavid du Colombier return 0;
702*96cbc34fSDavid du Colombier }
703*96cbc34fSDavid du Colombier CFRelease(cfdata);
704*96cbc34fSDavid du Colombier return 1;
705*96cbc34fSDavid du Colombier }
706*96cbc34fSDavid du Colombier
707*96cbc34fSDavid du Colombier
708*96cbc34fSDavid du Colombier void
mouseset(Point xy)709*96cbc34fSDavid du Colombier mouseset(Point xy)
710*96cbc34fSDavid du Colombier {
711*96cbc34fSDavid du Colombier CGPoint pnt;
712*96cbc34fSDavid du Colombier pnt.x = xy.x + winRect.left;
713*96cbc34fSDavid du Colombier pnt.y = xy.y + winRect.top;
714*96cbc34fSDavid du Colombier CGWarpMouseCursorPosition(pnt);
715*96cbc34fSDavid du Colombier }
716*96cbc34fSDavid du Colombier
717*96cbc34fSDavid du Colombier void
screenload(Rectangle r,int depth,uchar * p,Point pt,int step)718*96cbc34fSDavid du Colombier screenload(Rectangle r, int depth, uchar *p, Point pt, int step)
719*96cbc34fSDavid du Colombier {
720*96cbc34fSDavid du Colombier CGRect rbounds;
721*96cbc34fSDavid du Colombier rbounds.size.width = r.max.x - r.min.x;
722*96cbc34fSDavid du Colombier rbounds.size.height = r.max.y - r.min.y;
723*96cbc34fSDavid du Colombier rbounds.origin.x = r.min.x;
724*96cbc34fSDavid du Colombier rbounds.origin.y = r.min.y;
725*96cbc34fSDavid du Colombier
726*96cbc34fSDavid du Colombier if(depth != gscreen->depth)
727*96cbc34fSDavid du Colombier panic("screenload: bad ldepth");
728*96cbc34fSDavid du Colombier
729*96cbc34fSDavid du Colombier QDBeginCGContext( GetWindowPort(theWindow), &context);
730*96cbc34fSDavid du Colombier
731*96cbc34fSDavid du Colombier // The sub-image is relative to our whole screen image.
732*96cbc34fSDavid du Colombier CGImageRef subimg = CGImageCreateWithImageInRect(fullScreenImage, rbounds);
733*96cbc34fSDavid du Colombier
734*96cbc34fSDavid du Colombier // Drawing the sub-image is relative to the window.
735*96cbc34fSDavid du Colombier rbounds.origin.y = winRect.bottom - winRect.top - r.min.y - rbounds.size.height;
736*96cbc34fSDavid du Colombier CGContextDrawImage(context, rbounds, subimg);
737*96cbc34fSDavid du Colombier CGContextFlush(context);
738*96cbc34fSDavid du Colombier CGImageRelease(subimg);
739*96cbc34fSDavid du Colombier QDEndCGContext( GetWindowPort(theWindow), &context);
740*96cbc34fSDavid du Colombier
741*96cbc34fSDavid du Colombier }
742*96cbc34fSDavid du Colombier
743*96cbc34fSDavid du Colombier // PAL: these don't work.
744*96cbc34fSDavid du Colombier // SetCursor and InitCursor are marked as deprecated in 10.4, and I can't for the
745*96cbc34fSDavid du Colombier // life of me find out what has replaced them.
746*96cbc34fSDavid du Colombier void
setcursor(void)747*96cbc34fSDavid du Colombier setcursor(void)
748*96cbc34fSDavid du Colombier {
749*96cbc34fSDavid du Colombier Cursor crsr;
750*96cbc34fSDavid du Colombier int i;
751*96cbc34fSDavid du Colombier
752*96cbc34fSDavid du Colombier for(i=0; i<16; i++){
753*96cbc34fSDavid du Colombier crsr.data[i] = ((ushort*)cursor.set)[i];
754*96cbc34fSDavid du Colombier crsr.mask[i] = crsr.data[i] | ((ushort*)cursor.clr)[i];
755*96cbc34fSDavid du Colombier }
756*96cbc34fSDavid du Colombier crsr.hotSpot.h = -cursor.offset.x;
757*96cbc34fSDavid du Colombier crsr.hotSpot.v = -cursor.offset.y;
758*96cbc34fSDavid du Colombier SetCursor(&crsr);
759*96cbc34fSDavid du Colombier }
760*96cbc34fSDavid du Colombier
761*96cbc34fSDavid du Colombier void
cursorarrow(void)762*96cbc34fSDavid du Colombier cursorarrow(void)
763*96cbc34fSDavid du Colombier {
764*96cbc34fSDavid du Colombier InitCursor();
765*96cbc34fSDavid du Colombier }
766