aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/devdraw
diff options
context:
space:
mode:
authorJacob Vosmaer <contact@jacobvosmaer.nl>2018-10-06 00:13:04 +0200
committerRuss Cox <rsc@swtch.com>2018-11-15 22:03:27 -0500
commit3d6fc088f028e0267ecbc64e21eadbe9ca1bcb83 (patch)
treebe0ba502ce6499f0874cc1ef86832d84b39bb218 /src/cmd/devdraw
parent4e2ac7657b2ac3173bd4b23ecb7a7e8c4b74c00f (diff)
downloadplan9port-3d6fc088f028e0267ecbc64e21eadbe9ca1bcb83.tar.gz
plan9port-3d6fc088f028e0267ecbc64e21eadbe9ca1bcb83.tar.bz2
plan9port-3d6fc088f028e0267ecbc64e21eadbe9ca1bcb83.zip
devdraw: remove os x 10.5 compatibility code
Diffstat (limited to 'src/cmd/devdraw')
-rw-r--r--src/cmd/devdraw/mkwsysrules.sh10
-rw-r--r--src/cmd/devdraw/osx-screen-carbon.m1302
-rw-r--r--src/cmd/devdraw/osx-screen.h18
-rw-r--r--src/cmd/devdraw/osx-srv.c462
4 files changed, 2 insertions, 1790 deletions
diff --git a/src/cmd/devdraw/mkwsysrules.sh b/src/cmd/devdraw/mkwsysrules.sh
index 98d6799d..e94afbd3 100644
--- a/src/cmd/devdraw/mkwsysrules.sh
+++ b/src/cmd/devdraw/mkwsysrules.sh
@@ -23,7 +23,8 @@ fi
if [ "x$WSYSTYPE" = "x" ]; then
if [ "x`uname`" = "xDarwin" ]; then
if sw_vers | grep 'ProductVersion: 10\.[0-5]\.' >/dev/null; then
- WSYSTYPE=osx
+ echo 1>&2 'OS X 10.5 and older are not supported'
+ exit 1
else
#echo 1>&2 'WARNING: OS X Lion is not working. Copy binaries from a Snow Leopard system.'
WSYSTYPE=osx-cocoa
@@ -52,13 +53,6 @@ if [ $WSYSTYPE = x11 ]; then
echo 'HFILES=$HFILES $XHFILES'
XO=`ls x11-*.c 2>/dev/null | sed 's/\.c$/.o/'`
echo 'WSYSOFILES=$WSYSOFILES '$XO
-elif [ $WSYSTYPE = osx ]; then
- if [ -d /System/Library/PrivateFrameworks/MultitouchSupport.framework ]; then
- echo 'CFLAGS=$CFLAGS -DMULTITOUCH'
- echo 'LDFLAGS=$LDFLAGS -F/System/Library/PrivateFrameworks'
- fi
- echo 'WSYSOFILES=$WSYSOFILES osx-screen-carbon-objc.o osx-draw.o osx-srv.o'
- echo 'MACARGV=macargv.o'
elif [ $WSYSTYPE = osx-cocoa ]; then
if sw_vers|awk '/ProductVersion/{split($2,a,".");exit(a[2]<14)}' >/dev/null; then # 0 is true in sh.
echo 'OBJCFLAGS=$OBJCFLAGS -fobjc-arc'
diff --git a/src/cmd/devdraw/osx-screen-carbon.m b/src/cmd/devdraw/osx-screen-carbon.m
deleted file mode 100644
index d41e9d10..00000000
--- a/src/cmd/devdraw/osx-screen-carbon.m
+++ /dev/null
@@ -1,1302 +0,0 @@
-#define Point OSXPoint
-#define Rect OSXRect
-#define Cursor OSXCursor
-#include <Carbon/Carbon.h>
-#import <Foundation/Foundation.h>
-#ifdef MULTITOUCH
-#include <IOKit/IOKitLib.h>
-#include <IOKit/hidsystem/IOHIDShared.h>
-#endif
-#undef Rect
-#undef Point
-#undef Cursor
-#undef offsetof
-#undef nil
-
-#include "u.h"
-#include "libc.h"
-#include <thread.h>
-#include <draw.h>
-#include <memdraw.h>
-#include <keyboard.h>
-#include "mouse.h"
-#include <cursor.h>
-#include "osx-screen.h"
-#include "osx-keycodes.h"
-#include "devdraw.h"
-#include "glendapng.h"
-
-AUTOFRAMEWORK(Carbon)
-AUTOFRAMEWORK(Cocoa)
-
-#ifdef MULTITOUCH
-AUTOFRAMEWORK(MultitouchSupport)
-AUTOFRAMEWORK(IOKit)
-#endif
-
-#define panic sysfatal
-
-extern Rectangle mouserect;
-
-struct {
- char *label;
- char *winsize;
- QLock labellock;
-
- Rectangle fullscreenr;
- Rectangle screenr;
- Memimage *screenimage;
- int isfullscreen;
- ulong fullscreentime;
-
- Point xy;
- int buttons;
- int kbuttons;
-
- CGDataProviderRef provider;
- MenuRef wmenu;
- MenuRef vmenu;
- WindowRef window;
- CGImageRef image;
- CGContextRef windowctx;
- PasteboardRef snarf;
- int needflush;
- QLock flushlock;
- int active;
- int infullscreen;
- int kalting; // last keystroke was Kalt
- int touched; // last mouse event was touchCallback
- int collapsed; // parked in dock
- int flushing; // flushproc has started
- NSMutableArray* devicelist;
-} osx;
-
-/*
- These structs are required, in order to handle some parameters returned from the
- Support.framework
- */
-typedef struct {
- float x;
- float y;
-}mtPoint;
-
-typedef struct {
- mtPoint position;
- mtPoint velocity;
-}mtReadout;
-
-/*
- Some reversed engineered informations from MultiTouchSupport.framework
- */
-typedef struct
-{
- int frame; //the current frame
- double timestamp; //event timestamp
- int identifier; //identifier guaranteed unique for life of touch per device
- int state; //the current state (not sure what the values mean)
- int unknown1; //no idea what this does
- int unknown2; //no idea what this does either
- mtReadout normalized; //the normalized position and vector of the touch (0,0 to 1,1)
- float size; //the size of the touch (the area of your finger being tracked)
- int unknown3; //no idea what this does
- float angle; //the angle of the touch -|
- float majorAxis; //the major axis of the touch -|-- an ellipsoid. you can track the angle of each finger!
- float minorAxis; //the minor axis of the touch -|
- mtReadout unknown4; //not sure what this is for
- int unknown5[2]; //no clue
- float unknown6; //no clue
-}Touch;
-
-//a reference pointer for the multitouch device
-typedef void *MTDeviceRef;
-
-//the prototype for the callback function
-typedef int (*MTContactCallbackFunction)(int,Touch*,int,double,int);
-
-//returns a pointer to the default device (the trackpad?)
-MTDeviceRef MTDeviceCreateDefault(void);
-
-//returns a CFMutableArrayRef array of all multitouch devices
-CFMutableArrayRef MTDeviceCreateList(void);
-
-//registers a device's frame callback to your callback function
-void MTRegisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
-void MTUnregisterContactFrameCallback(MTDeviceRef, MTContactCallbackFunction);
-
-//start sending events
-void MTDeviceStart(MTDeviceRef, int);
-void MTDeviceStop(MTDeviceRef);
-
-MTDeviceRef MTDeviceCreateFromService(io_service_t);
-io_service_t MTDeviceGetService(MTDeviceRef);
-
-#define kNTracks 10
-struct TouchTrack {
- int id;
- float firstThreshTime;
- mtPoint pos;
-} tracks[kNTracks];
-
-#define kSizeSensitivity 1.25f
-#define kTimeSensitivity 0.03f /* seconds */
-#define kButtonLimit 0.6f /* percentage from base of pad */
-
-int
-findTrack(int id)
-{
- int i;
- for(i = 0; i < kNTracks; ++i)
- if(tracks[i].id == id)
- return i;
- return -1;
-}
-
-#define kMoveSensitivity 0.05f
-
-int
-moved(mtPoint a, mtPoint b)
-{
- if(fabs(a.x - b.x) > kMoveSensitivity)
- return 1;
- if(fabs(a.y - b.y) > kMoveSensitivity)
- return 1;
- return 0;
-}
-
-int
-classifyTouch(Touch *t)
-{
- mtPoint p;
- int i;
-
- p = t->normalized.position;
-
- i = findTrack(t->identifier);
- if(i == -1) {
- i = findTrack(-1);
- if(i == -1)
- return 0; // No empty tracks.
- tracks[i].id = t->identifier;
- tracks[i].firstThreshTime = t->timestamp;
- tracks[i].pos = p;
- // we don't have a touch yet - we wait kTimeSensitivity before reporting it.
- return 0;
- }
-
- if(t->size == 0) { // lost touch
- tracks[i].id = -1;
- return 0;
- }
- if(t->size < kSizeSensitivity) {
- tracks[i].firstThreshTime = t->timestamp;
- }
- if((t->timestamp - tracks[i].firstThreshTime) < kTimeSensitivity) {
- return 0;
- }
- if(p.y > kButtonLimit && t->size > kSizeSensitivity) {
- if(p.x < 0.35)
- return 1;
- if(p.x > 0.65)
- return 4;
- if(p.x > 0.35 && p.x < 0.65)
- return 2;
- }
- return 0;
-}
-
-static ulong msec(void);
-
-int
-touchCallback(int device, Touch *data, int nFingers, double timestamp, int frame)
-{
-#ifdef MULTITOUCH
- int buttons, delta, i;
- static int obuttons;
- CGPoint p;
- CGEventRef e;
-
- p.x = osx.xy.x+osx.screenr.min.x;
- p.y = osx.xy.y+osx.screenr.min.y;
- if(!ptinrect(Pt(p.x, p.y), osx.screenr))
- return 0;
- osx.touched = 1;
- buttons = 0;
- for(i = 0; i < nFingers; ++i)
- buttons |= classifyTouch(data+i);
- delta = buttons ^ obuttons;
- obuttons = buttons;
- if(delta & 1) {
- e = CGEventCreateMouseEvent(NULL,
- (buttons & 1) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp,
- p,
- 29);
- CGEventPost(kCGSessionEventTap, e);
- CFRelease(e);
- }
- if(delta & 2) {
- e = CGEventCreateMouseEvent(NULL,
- (buttons & 2) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp,
- p,
- 30);
- CGEventPost(kCGSessionEventTap, e);
- CFRelease(e);
- }
- if(delta & 4){
- e = CGEventCreateMouseEvent(NULL,
- (buttons & 4) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp,
- p,
- 31);
- CGEventPost(kCGSessionEventTap, e);
- CFRelease(e);
- }
- return delta != 0;
-#else
- return 0;
-#endif
-}
-
-extern int multitouch;
-
-enum
-{
- WindowAttrs =
- kWindowCloseBoxAttribute |
- kWindowCollapseBoxAttribute |
- kWindowResizableAttribute |
- kWindowStandardHandlerAttribute |
- kWindowFullZoomAttribute
-};
-
-enum
-{
- P9PEventLabelUpdate = 1
-};
-
-static void screenproc(void*);
-static void eresized(int);
-static void fullscreen(int);
-static void seticon(void);
-static void activated(int);
-
-static OSStatus quithandler(EventHandlerCallRef, EventRef, void*);
-static OSStatus eventhandler(EventHandlerCallRef, EventRef, void*);
-static OSStatus cmdhandler(EventHandlerCallRef, EventRef, void*);
-
-enum
-{
- CmdFullScreen = 1,
-};
-
-void screeninit(void);
-void _flushmemscreen(Rectangle r);
-
-#ifdef MULTITOUCH
-static void
-RegisterMultitouch(void *ctx, io_iterator_t iter)
-{
- io_object_t io;
- MTDeviceRef dev;
-
- while((io = IOIteratorNext(iter)) != 0){
- dev = MTDeviceCreateFromService(io);
- if (dev != nil){
- MTRegisterContactFrameCallback(dev, touchCallback);
- [osx.devicelist addObject:dev];
- if(osx.active)
- MTDeviceStart(dev, 0);
- }
-
- IOObjectRelease(io);
- }
-}
-
-static void
-UnregisterMultitouch(void *ctx, io_iterator_t iter)
-{
- io_object_t io;
- MTDeviceRef dev;
- int i;
-
- while((io = IOIteratorNext(iter)) != 0){
- for(i = 0; i < [osx.devicelist count]; i++){
- dev = [osx.devicelist objectAtIndex:i];
- if(IOObjectIsEqualTo(MTDeviceGetService(dev), io)){
- if(osx.active)
- MTDeviceStop(dev);
- MTUnregisterContactFrameCallback(dev, touchCallback);
- [osx.devicelist removeObjectAtIndex:i];
- break;
- }
- }
-
- IOObjectRelease(io);
- }
-}
-
-#endif /*MULTITOUCH*/
-
-static void
-InitMultiTouch()
-{
-#ifdef MULTITOUCH
- IONotificationPortRef port;
- CFRunLoopSourceRef source;
- io_iterator_t iter;
- kern_return_t kr;
- io_object_t obj;
- int i;
-
- if(!multitouch)
- return;
-
- osx.devicelist = [[NSMutableArray alloc] init];
-
- for(i = 0; i < kNTracks; ++i)
- tracks[i].id = -1;
-
- port = IONotificationPortCreate(kIOMasterPortDefault);
- if(port == nil){
- fprint(2, "failed to get an IO notification port\n");
- return;
- }
-
- source = IONotificationPortGetRunLoopSource(port);
- if(source == nil){
- fprint(2, "failed to get loop source for port");
- return;
- }
-
- CFRunLoopAddSource(
- (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()),
- source,
- kCFRunLoopDefaultMode);
-
- kr = IOServiceAddMatchingNotification(
- port, kIOTerminatedNotification,
- IOServiceMatching("AppleMultitouchDevice"),
- &UnregisterMultitouch,
- nil, &iter);
-
- if(kr != KERN_SUCCESS){
- fprint(2, "failed to add termination notification\n");
- return;
- }
-
- /* Arm the notification */
- while((obj = IOIteratorNext(iter)) != 0)
- IOObjectRelease(obj);
-
- kr = IOServiceAddMatchingNotification(
- port, kIOMatchedNotification,
- IOServiceMatching("AppleMultitouchDevice"),
- &RegisterMultitouch,
- nil, &iter);
-
- if(kr != KERN_SUCCESS){
- fprint(2, "failed to add matching notification\n");
- return;
- }
-
- RegisterMultitouch(nil, iter);
-#endif
-}
-
-Memimage*
-attachscreen(char *label, char *winsize)
-{
- if(label == nil)
- label = "gnot a label";
- osx.label = strdup(label);
- osx.winsize = winsize;
- if(osx.screenimage == nil){
- screeninit();
- if(osx.screenimage == nil)
- panic("cannot create OS X screen");
- }
- return osx.screenimage;
-}
-
-extern int multitouch;
-
-void
-_screeninit(void)
-{
- CGRect cgr;
- OSXRect or;
- Rectangle r;
- int havemin;
-
- memimageinit();
-
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
- SetFrontProcess(&psn);
-
- cgr = CGDisplayBounds(CGMainDisplayID());
- osx.fullscreenr = Rect(0, 0, cgr.size.width, cgr.size.height);
-
- InitCursor();
-
- // Create minimal menu with full-screen option.
- ClearMenuBar();
- CreateStandardWindowMenu(0, &osx.wmenu);
- InsertMenu(osx.wmenu, 0);
- MenuItemIndex ix;
- CreateNewMenu(1004, 0, &osx.vmenu); // XXX 1004?
- SetMenuTitleWithCFString(osx.vmenu, CFSTR("View"));
- AppendMenuItemTextWithCFString(osx.vmenu,
- CFSTR("Full Screen"), 0, CmdFullScreen, &ix);
- SetMenuItemCommandKey(osx.vmenu, ix, 0, 'F');
- AppendMenuItemTextWithCFString(osx.vmenu,
- CFSTR("Cmd-F exits full screen"),
- kMenuItemAttrDisabled, CmdFullScreen, &ix);
- InsertMenu(osx.vmenu, GetMenuID(osx.wmenu));
- DrawMenuBar();
-
- // Create the window.
- r = Rect(0, 0, Dx(osx.fullscreenr)*2/3, Dy(osx.fullscreenr)*2/3);
- havemin = 0;
- if(osx.winsize && osx.winsize[0]){
- if(parsewinsize(osx.winsize, &r, &havemin) < 0)
- sysfatal("%r");
- }
- if(!havemin)
- r = rectaddpt(r, Pt((Dx(osx.fullscreenr)-Dx(r))/2, (Dy(osx.fullscreenr)-Dy(r))/2));
- or.left = r.min.x;
- or.top = r.min.y;
- or.right = r.max.x;
- or.bottom = r.max.y;
- CreateNewWindow(kDocumentWindowClass, WindowAttrs, &or, &osx.window);
- setlabel(osx.label);
- seticon();
-
- // Set up the clip board.
- if(PasteboardCreate(kPasteboardClipboard, &osx.snarf) != noErr)
- panic("pasteboard create");
-
- // Explain in great detail which events we want to handle.
- // Why can't we just have one handler?
- const EventTypeSpec quits[] = {
- { kEventClassApplication, kEventAppQuit }
- };
- const EventTypeSpec cmds[] = {
- { kEventClassWindow, kEventWindowClosed },
- { kEventClassWindow, kEventWindowBoundsChanged },
- { kEventClassWindow, kEventWindowDrawContent },
- { kEventClassCommand, kEventCommandProcess },
- { kEventClassWindow, kEventWindowActivated },
- { kEventClassWindow, kEventWindowDeactivated },
- { kEventClassWindow, kEventWindowCollapsed },
- { kEventClassWindow, kEventWindowExpanded },
- };
- const EventTypeSpec events[] = {
- { kEventClassApplication, kEventAppShown },
- { kEventClassKeyboard, kEventRawKeyDown },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassMouse, kEventMouseWheelMoved },
- { 'P9PE', P9PEventLabelUpdate}
- };
-
- InstallApplicationEventHandler(
- NewEventHandlerUPP(quithandler),
- nelem(quits), quits, nil, nil);
-
- InstallApplicationEventHandler(
- NewEventHandlerUPP(eventhandler),
- nelem(events), events, nil, nil);
-
- InstallWindowEventHandler(osx.window,
- NewEventHandlerUPP(cmdhandler),
- nelem(cmds), cmds, osx.window, nil);
-
- // Finally, put the window on the screen.
- ShowWindow(osx.window);
- ShowMenuBar();
- eresized(0);
- SelectWindow(osx.window);
-
- if(multitouch)
- InitMultiTouch();
-
- // CoreGraphics pins mouse events to the destination point of a
- // CGWarpMouseCursorPosition (see setmouse) for an interval of time
- // following the move. Disable this by setting the interval to zero
- // seconds.
- CGSetLocalEventsSuppressionInterval(0.0);
-
- InitCursor();
-}
-
-static Rendez scr;
-static QLock slock;
-
-void
-screeninit(void)
-{
- scr.l = &slock;
- qlock(scr.l);
- proccreate(screenproc, nil, 256*1024);
- while(osx.window == nil)
- rsleep(&scr);
- qunlock(scr.l);
-}
-
-static void
-screenproc(void *v)
-{
- qlock(scr.l);
- _screeninit();
- rwakeup(&scr);
- qunlock(scr.l);
- RunApplicationEventLoop();
-}
-
-static OSStatus kbdevent(EventRef);
-static OSStatus mouseevent(EventRef);
-
-static OSStatus
-cmdhandler(EventHandlerCallRef next, EventRef event, void *arg)
-{
- return eventhandler(next, event, arg);
-}
-
-static OSStatus
-quithandler(EventHandlerCallRef next, EventRef event, void *arg)
-{
- exit(0);
- return 0;
-}
-
-static OSStatus
-eventhandler(EventHandlerCallRef next, EventRef event, void *arg)
-{
- OSStatus result;
-
- result = CallNextEventHandler(next, event);
-
- switch(GetEventClass(event)){
-
- case 'P9PE':
- if(GetEventKind(event) == P9PEventLabelUpdate) {
- qlock(&osx.labellock);
- setlabel(osx.label);
- qunlock(&osx.labellock);
- return noErr;
- } else
- return eventNotHandledErr;
-
- case kEventClassApplication:;
- Rectangle r = Rect(0, 0, Dx(osx.screenr), Dy(osx.screenr));
- _flushmemscreen(r);
- return eventNotHandledErr;
-
- case kEventClassKeyboard:
- return kbdevent(event);
-
- case kEventClassMouse:
- return mouseevent(event);
-
- case kEventClassCommand:;
- HICommand cmd;
- GetEventParameter(event, kEventParamDirectObject,
- typeHICommand, nil, sizeof cmd, nil, &cmd);
- switch(cmd.commandID){
- case kHICommandQuit:
- exit(0);
-
- case CmdFullScreen:
- fullscreen(1);
- break;
-
- default:
- return eventNotHandledErr;
- }
- break;
-
- case kEventClassWindow:
- switch(GetEventKind(event)){
- case kEventWindowClosed:
- exit(0);
-
- case kEventWindowBoundsChanged:;
- // We see kEventWindowDrawContent
- // if we grow a window but not if we shrink it.
- UInt32 flags;
- GetEventParameter(event, kEventParamAttributes,
- typeUInt32, 0, sizeof flags, 0, &flags);
- int new = (flags & kWindowBoundsChangeSizeChanged) != 0;
- eresized(new);
- break;
-
- case kEventWindowDrawContent:
- // Tried using just flushmemimage here, but
- // it causes an odd artifact in which making a window
- // bigger in both width and height can then only draw
- // on the new border: it's like the old window is stuck
- // floating on top. Doing a full "get a new window"
- // seems to solve the problem.
- eresized(1);
- break;
-
- case kEventWindowActivated:
- if(!osx.collapsed)
- activated(1);
- return eventNotHandledErr;
-
- case kEventWindowDeactivated:
- activated(0);
- return eventNotHandledErr;
-
- case kEventWindowCollapsed:
- osx.collapsed = 1;
- activated(0);
- return eventNotHandledErr;
-
- case kEventWindowExpanded:
- osx.collapsed = 0;
- activated(1);
- return eventNotHandledErr;
-
- default:
- return eventNotHandledErr;
- }
- break;
- }
-
- return result;
-}
-
-static ulong
-msec(void)
-{
- return nsec()/1000000;
-}
-
-static OSStatus
-mouseevent(EventRef event)
-{
- int wheel;
- OSXPoint op;
-
- GetEventParameter(event, kEventParamMouseLocation,
- typeQDPoint, 0, sizeof op, 0, &op);
-
- osx.xy = subpt(Pt(op.h, op.v), osx.screenr.min);
- wheel = 0;
-
- switch(GetEventKind(event)){
- case kEventMouseWheelMoved:;
- SInt32 delta;
- GetEventParameter(event, kEventParamMouseWheelDelta,
- typeSInt32, 0, sizeof delta, 0, &delta);
-
- // if I have any active touches in my region, I need to ignore the wheel motion.
- //int i;
- //for(i = 0; i < kNTracks; ++i) {
- // if(tracks[i].id != -1 && tracks[i].pos.y > kButtonLimit) break;
- //}
- //if(i == kNTracks) { // No active touches, go ahead and scroll.
- if(delta > 0)
- wheel = 8;
- else
- wheel = 16;
- //}
- break;
-
- case kEventMouseDown:
- case kEventMouseUp:;
- UInt32 but, mod;
- GetEventParameter(event, kEventParamMouseChord,
- typeUInt32, 0, sizeof but, 0, &but);
- GetEventParameter(event, kEventParamKeyModifiers,
- typeUInt32, 0, sizeof mod, 0, &mod);
-
- // OS X swaps button 2 and 3
- but = (but & ~6) | ((but & 4)>>1) | ((but&2)<<1);
- but = (but & ~((1<<10)-1)) | mouseswap(but & ((1<<10)-1));
- if(osx.touched) {
- // in multitouch we use the clicks down to enable our
- // virtual buttons.
- if(but & 0x7) {
- if(but>>29)
- but = but >> 29;
- } else
- but = 0;
- osx.touched = 0;
- }
-
- // Apply keyboard modifiers and pretend it was a real mouse button.
- // (Modifiers typed while holding the button go into kbuttons,
- // but this one does not.)
- if(but == 1){
- if(mod & optionKey) {
- // Take the ALT away from the keyboard handler.
- if(osx.kalting) {
- osx.kalting = 0;
- keystroke(Kalt);
- }
- but = 2;
- }
- else if(mod & cmdKey)
- but = 4;
- }
- osx.buttons = but;
- break;
-
- case kEventMouseMoved:
- case kEventMouseDragged:
- break;
-
- default:
- return eventNotHandledErr;
- }
-
- mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons|wheel, msec());
- return noErr;
-}
-
-static int keycvt[] =
-{
- [QZ_IBOOK_ENTER] '\n',
- [QZ_RETURN] '\n',
- [QZ_ESCAPE] 27,
- [QZ_BACKSPACE] '\b',
- [QZ_LALT] Kalt,
- [QZ_LCTRL] Kctl,
- [QZ_LSHIFT] Kshift,
- [QZ_F1] KF+1,
- [QZ_F2] KF+2,
- [QZ_F3] KF+3,
- [QZ_F4] KF+4,
- [QZ_F5] KF+5,
- [QZ_F6] KF+6,
- [QZ_F7] KF+7,
- [QZ_F8] KF+8,
- [QZ_F9] KF+9,
- [QZ_F10] KF+10,
- [QZ_F11] KF+11,
- [QZ_F12] KF+12,
- [QZ_INSERT] Kins,
- [QZ_DELETE] 0x7F,
- [QZ_HOME] Khome,
- [QZ_END] Kend,
- [QZ_KP_PLUS] '+',
- [QZ_KP_MINUS] '-',
- [QZ_TAB] '\t',
- [QZ_PAGEUP] Kpgup,
- [QZ_PAGEDOWN] Kpgdown,
- [QZ_UP] Kup,
- [QZ_DOWN] Kdown,
- [QZ_LEFT] Kleft,
- [QZ_RIGHT] Kright,
- [QZ_KP_MULTIPLY] '*',
- [QZ_KP_DIVIDE] '/',
- [QZ_KP_ENTER] '\n',
- [QZ_KP_PERIOD] '.',
- [QZ_KP0] '0',
- [QZ_KP1] '1',
- [QZ_KP2] '2',
- [QZ_KP3] '3',
- [QZ_KP4] '4',
- [QZ_KP5] '5',
- [QZ_KP6] '6',
- [QZ_KP7] '7',
- [QZ_KP8] '8',
- [QZ_KP9] '9',
-};
-
-static OSStatus
-kbdevent(EventRef event)
-{
- char ch;
- UInt32 code;
- UInt32 mod;
- int k;
-
- GetEventParameter(event, kEventParamKeyMacCharCodes,
- typeChar, nil, sizeof ch, nil, &ch);
- GetEventParameter(event, kEventParamKeyCode,
- typeUInt32, nil, sizeof code, nil, &code);
- GetEventParameter(event, kEventParamKeyModifiers,
- typeUInt32, nil, sizeof mod, nil, &mod);
-
- switch(GetEventKind(event)){
- case kEventRawKeyDown:
- case kEventRawKeyRepeat:
- osx.kalting = 0;
- if(mod == cmdKey){
- if(ch == 'F' || ch == 'f'){
- if(osx.isfullscreen && msec() - osx.fullscreentime > 500)
- fullscreen(0);
- return noErr;
- }
-
- // Pass most Cmd keys through as Kcmd + ch.
- // OS X interprets a few no matter what we do,
- // so it is useless to pass them through as keystrokes too.
- switch(ch) {
- case 'm': // minimize window
- case 'h': // hide window
- case 'H': // hide others
- case 'q': // quit
- return eventNotHandledErr;
- }
- if(' ' <= ch && ch <= '~') {
- keystroke(Kcmd + ch);
- return noErr;
- }
- return eventNotHandledErr;
- }
- k = ch;
- if(code < nelem(keycvt) && keycvt[code])
- k = keycvt[code];
- if(k == 0)
- return noErr;
- if(k > 0)
- keystroke(k);
- else{
- UniChar uc;
- OSStatus s;
-
- s = GetEventParameter(event, kEventParamKeyUnicodes,
- typeUnicodeText, nil, sizeof uc, nil, &uc);
- if(s == noErr)
- keystroke(uc);
- }
- break;
-
- case kEventRawKeyModifiersChanged:
- if(!osx.buttons && !osx.kbuttons){
- if(mod == optionKey) {
- osx.kalting = 1;
- keystroke(Kalt);
- }
- break;
- }
-
- // If the mouse button is being held down, treat
- // changes in the keyboard modifiers as changes
- // in the mouse buttons.
- osx.kbuttons = 0;
- if(mod & optionKey)
- osx.kbuttons |= 2;
- if(mod & cmdKey)
- osx.kbuttons |= 4;
- mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons, msec());
- break;
- }
- return noErr;
-}
-
-static void
-eresized(int new)
-{
- Memimage *m;
- OSXRect or;
- ulong chan;
- Rectangle r;
- int bpl;
- CGDataProviderRef provider;
- CGImageRef image;
- CGColorSpaceRef cspace;
-
- GetWindowBounds(osx.window, kWindowContentRgn, &or);
- r = Rect(or.left, or.top, or.right, or.bottom);
- if(Dx(r) == Dx(osx.screenr) && Dy(r) == Dy(osx.screenr) && !new){
- // No need to make new image.
- osx.screenr = r;
- return;
- }
-
- chan = XBGR32;
- m = allocmemimage(Rect(0, 0, Dx(r), Dy(r)), chan);
- if(m == nil)
- panic("allocmemimage: %r");
- if(m->data == nil)
- panic("m->data == nil");
- bpl = bytesperline(r, 32);
- provider = CGDataProviderCreateWithData(0,
- m->data->bdata, Dy(r)*bpl, 0);
- //cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- cspace = CGColorSpaceCreateDeviceRGB();
- image = CGImageCreate(Dx(r), Dy(r), 8, 32, bpl,
- cspace,
- kCGImageAlphaNoneSkipLast,
- provider, 0, 0, kCGRenderingIntentDefault);
- CGColorSpaceRelease(cspace);
- CGDataProviderRelease(provider); // CGImageCreate did incref
-
- mouserect = m->r;
- if(new){
- mouseresized = 1;
- mousetrack(osx.xy.x, osx.xy.y, osx.buttons|osx.kbuttons, msec());
- }
-// termreplacescreenimage(m);
- _drawreplacescreenimage(m); // frees old osx.screenimage if any
- if(osx.image)
- CGImageRelease(osx.image);
- osx.image = image;
- osx.screenimage = m;
- osx.screenr = r;
-
- if(new){
- qlock(&osx.flushlock);
- QDEndCGContext(GetWindowPort(osx.window), &osx.windowctx);
- osx.windowctx = nil;
- qunlock(&osx.flushlock);
- }
-}
-
-void
-flushproc(void *v)
-{
- for(;;){
- if(osx.needflush && osx.windowctx && canqlock(&osx.flushlock)){
- if(osx.windowctx){
- CGContextFlush(osx.windowctx);
- osx.needflush = 0;
- }
- qunlock(&osx.flushlock);
- }
- usleep(33333);
- }
-}
-
-void
-_flushmemscreen(Rectangle r)
-{
- CGRect cgr;
- CGImageRef subimg;
-
- qlock(&osx.flushlock);
- if(osx.windowctx == nil){
- QDBeginCGContext(GetWindowPort(osx.window), &osx.windowctx);
- if(!osx.flushing) {
- proccreate(flushproc, nil, 256*1024);
- osx.flushing = 1;
- }
- }
-
- cgr.origin.x = r.min.x;
- cgr.origin.y = r.min.y;
- cgr.size.width = Dx(r);
- cgr.size.height = Dy(r);
- subimg = CGImageCreateWithImageInRect(osx.image, cgr);
- cgr.origin.y = Dy(osx.screenr) - r.max.y; // XXX how does this make any sense?
- CGContextDrawImage(osx.windowctx, cgr, subimg);
- osx.needflush = 1;
- qunlock(&osx.flushlock);
- CGImageRelease(subimg);
-}
-
-void
-activated(int active)
-{
-#ifdef MULTITOUCH
- int i;
- if(active) {
- for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices
- MTDeviceStart([osx.devicelist objectAtIndex:i], 0); //start sending events
- }
- } else {
- osx.xy.x = -10000;
- for(i = 0; i<[osx.devicelist count]; i++) { //iterate available devices
- MTDeviceStop([osx.devicelist objectAtIndex:i]); //stop sending events
- }
- for(i = 0; i<kNTracks; ++i) {
- tracks[i].id = -1;
- }
- }
-#endif
- osx.active = active;
-}
-
-void
-fullscreen(int wascmd)
-{
- static OSXRect oldrect;
- GDHandle device;
- OSXRect dr;
-
- if(!wascmd)
- return;
-
- if(!osx.isfullscreen){
- GetWindowGreatestAreaDevice(osx.window,
- kWindowTitleBarRgn, &device, nil);
- dr = (*device)->gdRect;
- if(dr.top == 0 && dr.left == 0)
- HideMenuBar();
- GetWindowBounds(osx.window, kWindowContentRgn, &oldrect);
- ChangeWindowAttributes(osx.window,
- kWindowNoTitleBarAttribute,
- kWindowResizableAttribute);
- MoveWindow(osx.window, 0, 0, 1);
- MoveWindow(osx.window, dr.left, dr.top, 0);
- SizeWindow(osx.window,
- dr.right - dr.left,
- dr.bottom - dr.top, 0);
- osx.isfullscreen = 1;
- }else{
- ShowMenuBar();
- ChangeWindowAttributes(osx.window,
- kWindowResizableAttribute,
- kWindowNoTitleBarAttribute);
- SizeWindow(osx.window,
- oldrect.right - oldrect.left,
- oldrect.bottom - oldrect.top, 0);
- MoveWindow(osx.window, oldrect.left, oldrect.top, 0);
- osx.isfullscreen = 0;
- }
- eresized(1);
-}
-
-void
-setmouse(Point p)
-{
- CGPoint cgp;
-
- cgp.x = p.x + osx.screenr.min.x;
- cgp.y = p.y + osx.screenr.min.y;
- CGWarpMouseCursorPosition(cgp);
- osx.xy = p;
-}
-
-void
-setcursor(Cursor *c)
-{
- OSXCursor oc;
- int i;
-
- if(c == nil){
- InitCursor();
- return;
- }
-
- // SetCursor is deprecated, but what replaces it?
- for(i=0; i<16; i++){
- oc.data[i] = ((ushort*)c->set)[i];
- oc.mask[i] = oc.data[i] | ((ushort*)c->clr)[i];
- }
- oc.hotSpot.h = - c->offset.x;
- oc.hotSpot.v = - c->offset.y;
- SetCursor(&oc);
-}
-
-void
-getcolor(ulong i, ulong *r, ulong *g, ulong *b)
-{
- ulong v;
-
- v = 0;
- *r = (v>>16)&0xFF;
- *g = (v>>8)&0xFF;
- *b = v&0xFF;
-}
-
-int
-setcolor(ulong i, ulong r, ulong g, ulong b)
-{
- /* no-op */
- return 0;
-}
-
-
-int
-hwdraw(Memdrawparam *p)
-{
- return 0;
-}
-
-struct {
- QLock lk;
- char buf[SnarfSize];
- Rune rbuf[SnarfSize];
- PasteboardRef apple;
-} clip;
-
-char*
-getsnarf(void)
-{
- char *s;
- CFArrayRef flavors;
- CFDataRef data;
- CFIndex nflavor, ndata, j;
- CFStringRef type;
- ItemCount nitem;
- PasteboardItemID id;
- PasteboardSyncFlags flags;
- UInt32 i;
- u16int *u;
- Fmt fmt;
- Rune r;
-
-/* fprint(2, "applegetsnarf\n"); */
- qlock(&clip.lk);
- clip.apple = osx.snarf;
- if(clip.apple == nil){
- if(PasteboardCreate(kPasteboardClipboard, &clip.apple) != noErr){
- fprint(2, "apple pasteboard create failed\n");
- qunlock(&clip.lk);
- return nil;
- }
- }
- flags = PasteboardSynchronize(clip.apple);
- if(flags&kPasteboardClientIsOwner){
- s = strdup(clip.buf);
- qunlock(&clip.lk);
- return s;
- }
- if(PasteboardGetItemCount(clip.apple, &nitem) != noErr){
- fprint(2, "apple pasteboard get item count failed\n");
- qunlock(&clip.lk);
- return nil;
- }
- for(i=1; i<=nitem; i++){
- if(PasteboardGetItemIdentifier(clip.apple, i, &id) != noErr)
- continue;
- if(PasteboardCopyItemFlavors(clip.apple, id, &flavors) != noErr)
- continue;
- nflavor = CFArrayGetCount(flavors);
- for(j=0; j<nflavor; j++){
- type = (CFStringRef)CFArrayGetValueAtIndex(flavors, j);
- if(!UTTypeConformsTo(type, CFSTR("public.utf16-plain-text")))
- continue;
- if(PasteboardCopyItemFlavorData(clip.apple, id, type, &data) != noErr)
- continue;
- qunlock(&clip.lk);
- ndata = CFDataGetLength(data)/2;
- u = (u16int*)CFDataGetBytePtr(data);
- fmtstrinit(&fmt);
- // decode utf-16. what was apple thinking?
- for(i=0; i<ndata; i++) {
- r = u[i];
- if(0xd800 <= r && r < 0xdc00 && i+1 < ndata && 0xdc00 <= u[i+1] && u[i+1] < 0xe000) {
- r = (((r - 0xd800)<<10) | (u[i+1] - 0xdc00)) + 0x10000;
- i++;
- }
- else if(0xd800 <= r && r < 0xe000)
- r = Runeerror;
- if(r == '\r')
- r = '\n';
- fmtrune(&fmt, r);
- }
- CFRelease(flavors);
- CFRelease(data);
- return fmtstrflush(&fmt);
- }
- CFRelease(flavors);
- }
- qunlock(&clip.lk);
- return nil;
-}
-
-void
-putsnarf(char *s)
-{
- CFDataRef cfdata;
- PasteboardSyncFlags flags;
- u16int *u, *p;
- Rune r;
- int i;
-
-/* fprint(2, "appleputsnarf\n"); */
-
- if(strlen(s) >= SnarfSize)
- return;
- qlock(&clip.lk);
- strcpy(clip.buf, s);
- runesnprint(clip.rbuf, nelem(clip.rbuf), "%s", s);
- clip.apple = osx.snarf;
- if(PasteboardClear(clip.apple) != noErr){
- fprint(2, "apple pasteboard clear failed\n");
- qunlock(&clip.lk);
- return;
- }
- flags = PasteboardSynchronize(clip.apple);
- if((flags&kPasteboardModified) || !(flags&kPasteboardClientIsOwner)){
- fprint(2, "apple pasteboard cannot assert ownership\n");
- qunlock(&clip.lk);
- return;
- }
- u = malloc(runestrlen(clip.rbuf)*4);
- p = u;
- for(i=0; clip.rbuf[i]; i++) {
- r = clip.rbuf[i];
- // convert to utf-16
- if(0xd800 <= r && r < 0xe000)
- r = Runeerror;
- if(r >= 0x10000) {
- r -= 0x10000;
- *p++ = 0xd800 + (r>>10);
- *p++ = 0xdc00 + (r & ((1<<10)-1));
- } else
- *p++ = r;
- }
- cfdata = CFDataCreate(kCFAllocatorDefault,
- (uchar*)u, (p-u)*2);
- free(u);
- if(cfdata == nil){
- fprint(2, "apple pasteboard cfdatacreate failed\n");
- qunlock(&clip.lk);
- return;
- }
- if(PasteboardPutItemFlavor(clip.apple, (PasteboardItemID)1,
- CFSTR("public.utf16-plain-text"), cfdata, 0) != noErr){
- fprint(2, "apple pasteboard putitem failed\n");
- CFRelease(cfdata);
- qunlock(&clip.lk);
- return;
- }
- CFRelease(cfdata);
- qunlock(&clip.lk);
-}
-
-void
-setlabel(char *label)
-{
- CFStringRef cs;
-
- cs = CFStringCreateWithBytes(nil, (uchar*)label, strlen(label), kCFStringEncodingUTF8, false);
- SetWindowTitleWithCFString(osx.window, cs);
- CFRelease(cs);
-}
-
-void
-kicklabel(char *label)
-{
- char *p;
- EventRef e;
-
- p = strdup(label);
- if(p == nil)
- return;
- qlock(&osx.labellock);
- free(osx.label);
- osx.label = p;
- qunlock(&osx.labellock);
-
- CreateEvent(nil, 'P9PE', P9PEventLabelUpdate, 0, kEventAttributeUserEvent, &e);
- PostEventToQueue(GetMainEventQueue(), e, kEventPriorityStandard);
-
-}
-
-static void
-seticon(void)
-{
- CGImageRef im;
- CGDataProviderRef d;
-
- d = CGDataProviderCreateWithData(nil, glenda_png, sizeof glenda_png, nil);
- im = CGImageCreateWithPNGDataProvider(d, nil, true, kCGRenderingIntentDefault);
- if(im)
- SetApplicationDockTileImage(im);
- CGImageRelease(im);
- CGDataProviderRelease(d);
-}
-
diff --git a/src/cmd/devdraw/osx-screen.h b/src/cmd/devdraw/osx-screen.h
deleted file mode 100644
index d5ba3dd2..00000000
--- a/src/cmd/devdraw/osx-screen.h
+++ /dev/null
@@ -1,18 +0,0 @@
-void zlock(void);
-void zunlock(void);
-
-#define setcursor dsetcursor
-
-Memimage *attachscreen(char*, char*);
-void setmouse(Point);
-void setcursor(Cursor*, Cursor2*);
-void setlabel(char*);
-char* getsnarf(void);
-void putsnarf(char*);
-
-void mousetrack(int, int, int, int);
-void keystroke(int);
-void kicklabel(char*);
-
-extern Rectangle mouserect;
-extern int mouseresized;
diff --git a/src/cmd/devdraw/osx-srv.c b/src/cmd/devdraw/osx-srv.c
deleted file mode 100644
index d0a1c2d3..00000000
--- a/src/cmd/devdraw/osx-srv.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Window system protocol server.
- */
-
-#include <u.h>
-#include <errno.h>
-#include <sys/select.h>
-#include <libc.h>
-#include <thread.h>
-#include <draw.h>
-#include <memdraw.h>
-#include <memlayer.h>
-#include <keyboard.h>
-#include <mouse.h>
-#include <cursor.h>
-#include <drawfcall.h>
-#include "osx-screen.h"
-#include "devdraw.h"
-
-#undef time
-
-#define MouseMask (\
- ButtonPressMask|\
- ButtonReleaseMask|\
- PointerMotionMask|\
- Button1MotionMask|\
- Button2MotionMask|\
- Button3MotionMask)
-
-#define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|EnterWindowMask|LeaveWindowMask
-
-typedef struct Kbdbuf Kbdbuf;
-typedef struct Mousebuf Mousebuf;
-typedef struct Fdbuf Fdbuf;
-typedef struct Tagbuf Tagbuf;
-
-struct Kbdbuf
-{
- Rune r[32];
- int ri;
- int wi;
- int stall;
-};
-
-struct Mousebuf
-{
- Mouse m[32];
- Mouse last;
- int ri;
- int wi;
- int stall;
-};
-
-struct Tagbuf
-{
- int t[32];
- int ri;
- int wi;
-};
-
-Kbdbuf kbd;
-Mousebuf mouse;
-Tagbuf kbdtags;
-Tagbuf mousetags;
-
-void fdslide(Fdbuf*);
-void runmsg(Wsysmsg*);
-void replymsg(Wsysmsg*);
-void matchkbd(void);
-void matchmouse(void);
-int fdnoblock(int);
-Rectangle mouserect;
-int mouseresized;
-
-
-QLock lk;
-void
-zlock(void)
-{
- qlock(&lk);
-}
-
-void
-zunlock(void)
-{
- qunlock(&lk);
-}
-
-int chatty;
-int drawsleep;
-int trace;
-int multitouch = 1;
-
-void
-usage(void)
-{
- fprint(2, "usage: devdraw (don't run directly)\n");
- threadexitsall("usage");
-}
-
-void
-bell(void *v, char *msg)
-{
- if(strcmp(msg, "alarm") == 0)
- drawsleep = drawsleep ? 0 : 1000;
- noted(NCONT);
-}
-
-void
-threadmain(int argc, char **argv)
-{
- uchar buf[4], *mbuf;
- int nmbuf, n, nn;
- Wsysmsg m;
-
- /*
- * Move the protocol off stdin/stdout so that
- * any inadvertent prints don't screw things up.
- */
- dup(0, 3);
- dup(1, 4);
- close(0);
- close(1);
- open("/dev/null", OREAD);
- open("/dev/null", OWRITE);
-
-//trace = 1;
- fmtinstall('W', drawfcallfmt);
-
- ARGBEGIN{
- case 'D':
- chatty++;
- break;
- case 'M':
- multitouch = 0;
- break;
- default:
- usage();
- }ARGEND
-
- /*
- * Ignore arguments. They're only for good ps -a listings.
- */
-
- notify(bell);
-
- mbuf = nil;
- nmbuf = 0;
- while((n = read(3, buf, 4)) == 4){
- GET(buf, n);
- if(n > nmbuf){
- free(mbuf);
- mbuf = malloc(4+n);
- if(mbuf == nil)
- sysfatal("malloc: %r");
- nmbuf = n;
- }
- memmove(mbuf, buf, 4);
- nn = readn(3, mbuf+4, n-4);
- if(nn != n-4)
- sysfatal("eof during message");
-
- /* pick off messages one by one */
- if(convM2W(mbuf, nn+4, &m) <= 0)
- sysfatal("cannot convert message");
- if(trace) fprint(2, "<- %W\n", &m);
- runmsg(&m);
- }
- threadexitsall(0);
-}
-
-void
-replyerror(Wsysmsg *m)
-{
- char err[256];
-
- rerrstr(err, sizeof err);
- m->type = Rerror;
- m->error = err;
- replymsg(m);
-}
-
-/*
- * Handle a single wsysmsg.
- * Might queue for later (kbd, mouse read)
- */
-void
-runmsg(Wsysmsg *m)
-{
- static uchar buf[65536];
- int n;
- Memimage *i;
-
- switch(m->type){
- case Tinit:
- memimageinit();
- i = attachscreen(m->label, m->winsize);
- _initdisplaymemimage(i);
- replymsg(m);
- break;
-
- case Trdmouse:
- zlock();
- mousetags.t[mousetags.wi++] = m->tag;
- if(mousetags.wi == nelem(mousetags.t))
- mousetags.wi = 0;
- if(mousetags.wi == mousetags.ri)
- sysfatal("too many queued mouse reads");
- mouse.stall = 0;
- matchmouse();
- zunlock();
- break;
-
- case Trdkbd:
- zlock();
- kbdtags.t[kbdtags.wi++] = m->tag;
- if(kbdtags.wi == nelem(kbdtags.t))
- kbdtags.wi = 0;
- if(kbdtags.wi == kbdtags.ri)
- sysfatal("too many queued keyboard reads");
- kbd.stall = 0;
- matchkbd();
- zunlock();
- break;
-
- case Tmoveto:
- setmouse(m->mouse.xy);
- replymsg(m);
- break;
-
- case Tcursor:
- if(m->arrowcursor)
- setcursor(nil, nil);
- else
- setcursor(&m->cursor, &m->cursor2);
- replymsg(m);
- break;
-
- case Tbouncemouse:
- // _xbouncemouse(&m->mouse);
- replymsg(m);
- break;
-
- case Tlabel:
- kicklabel(m->label);
- replymsg(m);
- break;
-
- case Trdsnarf:
- m->snarf = getsnarf();
- replymsg(m);
- free(m->snarf);
- break;
-
- case Twrsnarf:
- putsnarf(m->snarf);
- replymsg(m);
- break;
-
- case Trddraw:
- n = m->count;
- if(n > sizeof buf)
- n = sizeof buf;
- n = _drawmsgread(buf, n);
- if(n < 0)
- replyerror(m);
- else{
- m->count = n;
- m->data = buf;
- replymsg(m);
- }
- break;
-
- case Twrdraw:
- if(_drawmsgwrite(m->data, m->count) < 0)
- replyerror(m);
- else
- replymsg(m);
- break;
-
- case Ttop:
- // _xtopwindow();
- replymsg(m);
- break;
-
- case Tresize:
- // _xresizewindow(m->rect);
- replymsg(m);
- break;
- }
-}
-
-/*
- * Reply to m.
- */
-QLock replylock;
-void
-replymsg(Wsysmsg *m)
-{
- int n;
- static uchar *mbuf;
- static int nmbuf;
-
- /* T -> R msg */
- if(m->type%2 == 0)
- m->type++;
-
- if(trace) fprint(2, "-> %W\n", m);
- /* copy to output buffer */
- n = sizeW2M(m);
-
- qlock(&replylock);
- if(n > nmbuf){
- free(mbuf);
- mbuf = malloc(n);
- if(mbuf == nil)
- sysfatal("out of memory");
- nmbuf = n;
- }
- convW2M(m, mbuf, n);
- if(write(4, mbuf, n) != n)
- sysfatal("write: %r");
- qunlock(&replylock);
-}
-
-/*
- * Match queued kbd reads with queued kbd characters.
- */
-void
-matchkbd(void)
-{
- Wsysmsg m;
-
- if(kbd.stall)
- return;
- while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){
- m.type = Rrdkbd;
- m.tag = kbdtags.t[kbdtags.ri++];
- if(kbdtags.ri == nelem(kbdtags.t))
- kbdtags.ri = 0;
- m.rune = kbd.r[kbd.ri++];
- if(kbd.ri == nelem(kbd.r))
- kbd.ri = 0;
- replymsg(&m);
- }
-}
-
-/*
- * Match queued mouse reads with queued mouse events.
- */
-void
-matchmouse(void)
-{
- Wsysmsg m;
-
- while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){
- m.type = Rrdmouse;
- m.tag = mousetags.t[mousetags.ri++];
- if(mousetags.ri == nelem(mousetags.t))
- mousetags.ri = 0;
- m.mouse = mouse.m[mouse.ri];
- m.resized = mouseresized;
- /*
- if(m.resized)
- fprint(2, "sending resize\n");
- */
- mouseresized = 0;
- mouse.ri++;
- if(mouse.ri == nelem(mouse.m))
- mouse.ri = 0;
- replymsg(&m);
- }
-}
-
-void
-mousetrack(int x, int y, int b, int ms)
-{
- Mouse *m;
-
- if(x < mouserect.min.x)
- x = mouserect.min.x;
- if(x > mouserect.max.x)
- x = mouserect.max.x;
- if(y < mouserect.min.y)
- y = mouserect.min.y;
- if(y > mouserect.max.y)
- y = mouserect.max.y;
-
- zlock();
- // If reader has stopped reading, don't bother.
- // If reader is completely caught up, definitely queue.
- // Otherwise, queue only button change events.
- if(!mouse.stall)
- if(mouse.wi == mouse.ri || mouse.last.buttons != b){
- m = &mouse.last;
- m->xy.x = x;
- m->xy.y = y;
- m->buttons = b;
- m->msec = ms;
-
- mouse.m[mouse.wi] = *m;
- if(++mouse.wi == nelem(mouse.m))
- mouse.wi = 0;
- if(mouse.wi == mouse.ri){
- mouse.stall = 1;
- mouse.ri = 0;
- mouse.wi = 1;
- mouse.m[0] = *m;
- }
- matchmouse();
- }
- zunlock();
-}
-
-void
-kputc(int c)
-{
- zlock();
- kbd.r[kbd.wi++] = c;
- if(kbd.wi == nelem(kbd.r))
- kbd.wi = 0;
- if(kbd.ri == kbd.wi)
- kbd.stall = 1;
- matchkbd();
- zunlock();
-}
-
-void
-keystroke(int c)
-{
- static Rune k[10];
- static int alting, nk;
- int i;
-
- if(c == Kalt){
- alting = !alting;
- return;
- }
- if(!alting){
- kputc(c);
- return;
- }
- if(nk >= nelem(k)) // should not happen
- nk = 0;
- k[nk++] = c;
- c = _latin1(k, nk);
- if(c > 0){
- alting = 0;
- kputc(c);
- nk = 0;
- return;
- }
- if(c == -1){
- alting = 0;
- for(i=0; i<nk; i++)
- kputc(k[i]);
- nk = 0;
- return;
- }
- // need more input
- return;
-}