1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7f75b84e94b1ca1540295584421de0158d87a9b52bsalomon@google.com
86efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkTypes.h"
96efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
10e229e92ea51e9bc7c11033e2099d3ef275621115tfarina@chromium.org#if defined(SK_BUILD_FOR_MAC)
116efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
12f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#include <AGL/agl.h>
13f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
146efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include <Carbon/Carbon.h>
156efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkCGUtils.h"
166efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
176efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkWindow.h"
186efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkCanvas.h"
196efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkOSMenu.h"
206efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkTime.h"
216efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
226efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include "SkGraphics.h"
236efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#include <new.h>
246efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
256efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void (*gPrevNewHandler)();
266efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
276efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comextern "C" {
28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static void sk_new_handler()
29d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (SkGraphics::SetFontCacheUsed(0))
31d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            return;
32d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (gPrevNewHandler)
33d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            gPrevNewHandler();
34d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        else
35d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            sk_throw();
36d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
376efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
386efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
396efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic SkOSWindow* gCurrOSWin;
406efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic EventTargetRef gEventTarget;
416efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic EventQueueRef gCurrEventQ;
426efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
436efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic OSStatus MyDrawEventHandler(EventHandlerCallRef myHandler,
446efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                   EventRef event, void *userData) {
45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // NOTE: GState is save/restored by the HIView system doing the callback,
466efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    // so the draw handler doesn't need to do it
475782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
48d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    OSStatus status = noErr;
49d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    CGContextRef context;
50d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    HIRect        bounds;
515782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
52d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // Get the CGContextRef
53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    status = GetEventParameter (event, kEventParamCGContextRef,
545782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com                                typeCGContextRef, NULL,
556efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                sizeof (CGContextRef),
566efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                NULL,
576efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                &context);
585782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (status != noErr) {
60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkDebugf("Got error %d getting the context!\n", status);
61d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return status;
62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
635782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
64d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // Get the bounding rectangle
65d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    HIViewGetBounds ((HIViewRef) userData, &bounds);
665782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
676efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    gCurrOSWin->doPaint(context);
68d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return status;
696efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
706efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
71d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#define SK_MacEventClass            FOUR_CHAR_CODE('SKec')
72d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#define SK_MacEventKind                FOUR_CHAR_CODE('SKek')
73d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#define SK_MacEventParamName        FOUR_CHAR_CODE('SKev')
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com#define SK_MacEventSinkIDParamName    FOUR_CHAR_CODE('SKes')
756efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
766efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void set_bindingside(HISideBinding* side, HIViewRef parent, HIBindingKind kind) {
776efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    side->toView = parent;
786efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    side->kind = kind;
796efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    side->offset = 0;
806efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
816efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
826efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void set_axisscale(HIAxisScale* axis, HIViewRef parent) {
836efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    axis->toView = parent;
846efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    axis->kind = kHILayoutScaleAbsolute;
856efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    axis->ratio = 1;
866efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
876efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
886efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void set_axisposition(HIAxisPosition* pos, HIViewRef parent, HIPositionKind kind) {
896efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    pos->toView = parent;
906efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    pos->kind = kind;
916efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    pos->offset = 0;
926efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
936efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
94f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comSkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), fAGLCtx(NULL)
956efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
96d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    OSStatus    result;
976efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    WindowRef   wr = (WindowRef)hWnd;
985782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
996efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewRef imageView, parent;
1006efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewRef rootView = HIViewGetRoot(wr);
1016efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewFindByID(rootView, kHIViewWindowContentID, &parent);
1026efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    result = HIImageViewCreate(NULL, &imageView);
103d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(result == noErr);
1045782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1056efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    result = HIViewAddSubview(parent, imageView);
106d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(result == noErr);
1076efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1086efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    fHVIEW = imageView;
1096efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1106efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewSetVisible(imageView, true);
1116efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewPlaceInSuperviewAt(imageView, 0, 0);
1126efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1136efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    if (true) {
1146efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        HILayoutInfo layout;
1156efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        layout.version = kHILayoutInfoVersionZero;
1166efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_bindingside(&layout.binding.left, parent, kHILayoutBindLeft);
1176efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_bindingside(&layout.binding.top, parent, kHILayoutBindTop);
1186efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_bindingside(&layout.binding.right, parent, kHILayoutBindRight);
1196efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_bindingside(&layout.binding.bottom, parent, kHILayoutBindBottom);
1206efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_axisscale(&layout.scale.x, parent);
1216efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_axisscale(&layout.scale.y, parent);
1226efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_axisposition(&layout.position.x, parent, kHILayoutPositionLeft);
1236efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        set_axisposition(&layout.position.y, rootView, kHILayoutPositionTop);
1246efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        HIViewSetLayoutInfo(imageView, &layout);
1256efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    }
1266efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1276efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIImageViewSetOpaque(imageView, true);
1286efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIImageViewSetScaleToFit(imageView, false);
1296efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
130d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static const EventTypeSpec  gTypes[] = {
131d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassKeyboard,  kEventRawKeyDown            },
1326efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { kEventClassKeyboard,  kEventRawKeyUp              },
133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassMouse,        kEventMouseDown                },
134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassMouse,        kEventMouseDragged            },
135d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassMouse,        kEventMouseMoved            },
136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassMouse,        kEventMouseUp                },
137d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent   },
138d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { kEventClassWindow,    kEventWindowBoundsChanged    },
139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com//        { kEventClassWindow,    kEventWindowDrawContent        },
140d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacEventClass,        SK_MacEventKind                }
141d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    };
142d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
143d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    EventHandlerUPP handlerUPP = NewEventHandlerUPP(SkOSWindow::EventHandler);
144d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    int                count = SK_ARRAY_COUNT(gTypes);
145d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
146d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    result = InstallEventHandler(GetWindowEventTarget(wr), handlerUPP,
147d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                        count, gTypes, this, nil);
148d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(result == noErr);
149d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
150d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    gCurrOSWin = this;
151d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    gCurrEventQ = GetCurrentEventQueue();
152d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    gEventTarget = GetWindowEventTarget(wr);
153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
154d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static bool gOnce = true;
155d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (gOnce) {
156d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        gOnce = false;
157d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        gPrevNewHandler = set_new_handler(sk_new_handler);
158d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
1596efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
1606efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1616efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkOSWindow::doPaint(void* ctx)
1626efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
1636efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#if 0
164d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->update(NULL);
1656efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1666efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    const SkBitmap& bm = this->getBitmap();
1676efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    CGImageRef img = SkCreateCGImageRef(bm);
1686efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1696efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    if (img) {
1706efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGRect r = CGRectMake(0, 0, bm.width(), bm.height());
1716efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1726efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextRef cg = reinterpret_cast<CGContextRef>(ctx);
1736efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1746efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextSaveGState(cg);
1756efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextTranslateCTM(cg, 0, r.size.height);
1766efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextScaleCTM(cg, 1, -1);
1776efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1786efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextDrawImage(cg, r, img);
1795782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1806efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGContextRestoreGState(cg);
1816efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1826efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        CGImageRelease(img);
1836efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    }
1846efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#endif
1856efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
1866efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
1876efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkOSWindow::updateSize()
1886efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
189d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    Rect    r;
1905782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
191d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GetWindowBounds((WindowRef)fHWND, kWindowContentRgn, &r);
192d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    this->resize(r.right - r.left, r.bottom - r.top);
1935782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1946efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#if 0
1956efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIRect    frame;
1966efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewRef imageView = (HIViewRef)getHVIEW();
1976efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewRef parent = HIViewGetSuperview(imageView);
1985782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
1996efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    HIViewGetBounds(imageView, &frame);
2006efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SkDebugf("------ %d bounds %g %g %g %g\n", r.right - r.left,
2016efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com             frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
2026efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#endif
2036efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2046efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2056efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkOSWindow::onHandleInval(const SkIRect& r)
2066efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
20787fac4abd7ea446c05d5cfd4a8ad27420223b591reed@google.com    (new SkEvent("inval-imageview", this->getSinkID()))->post();
2086efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2096efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2106efdc47afc8bb24603fc0d15146ada609b728f2freed@android.combool SkOSWindow::onEvent(const SkEvent& evt) {
2116efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    if (evt.isType("inval-imageview")) {
2126efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        this->update(NULL);
2136efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
21429038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        SkEvent query("ignore-window-bitmap");
21529038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        if (!this->doQuery(&query) || !query.getFast32()) {
21629038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com            const SkBitmap& bm = this->getBitmap();
21729038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com
21829038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com            CGImageRef img = SkCreateCGImageRef(bm);
21929038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com            HIImageViewSetImage((HIViewRef)getHVIEW(), img);
22029038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com            CGImageRelease(img);
22129038ed2ab5cb87fda5a2a4d3267f0a5aa227a3dreed@google.com        }
2226efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        return true;
2236efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    }
2246efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    return INHERITED::onEvent(evt);
2256efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2266efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2276efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkOSWindow::onSetTitle(const char title[])
2286efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
2296efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    CFStringRef str = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
2306efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SetWindowTitleWithCFString((WindowRef)fHWND, str);
2316efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    CFRelease(str);
2326efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2336efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2346efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
2356efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
2366efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2376efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2386efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void getparam(EventRef inEvent, OSType name, OSType type, UInt32 size, void* data)
2396efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
240d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    EventParamType  actualType;
241d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    UInt32            actualSize;
242d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    OSStatus        status;
243d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
244d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    status = GetEventParameter(inEvent, name, type, &actualType, size, &actualSize, data);
245d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
246d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(actualType == type);
247d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(actualSize == size);
2486efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
2496efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
2506efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comenum {
251d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacReturnKey        = 36,
252d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacDeleteKey        = 51,
253d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacEndKey        = 119,
254d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacLeftKey        = 123,
255d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacRightKey        = 124,
256d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacDownKey        = 125,
257d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SK_MacUpKey            = 126,
2585782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2596efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac0Key          = 0x52,
2606efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac1Key          = 0x53,
2616efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac2Key          = 0x54,
2626efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac3Key          = 0x55,
2636efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac4Key          = 0x56,
2646efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac5Key          = 0x57,
2656efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac6Key          = 0x58,
2666efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac7Key          = 0x59,
2676efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac8Key          = 0x5b,
2686efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    SK_Mac9Key          = 0x5c
2696efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com};
2705782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
2716efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic SkKey raw2key(UInt32 raw)
2726efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
273d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    static const struct {
274d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        UInt32  fRaw;
275d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkKey   fKey;
276d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    } gKeys[] = {
277d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacUpKey,        kUp_SkKey        },
278d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacDownKey,    kDown_SkKey        },
279d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacLeftKey,    kLeft_SkKey        },
280d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacRightKey,   kRight_SkKey    },
281d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacReturnKey,  kOK_SkKey        },
282d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacDeleteKey,  kBack_SkKey        },
283d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        { SK_MacEndKey,        kEnd_SkKey        },
2846efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac0Key,       k0_SkKey        },
2856efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac1Key,       k1_SkKey        },
2866efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac2Key,       k2_SkKey        },
2876efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac3Key,       k3_SkKey        },
2886efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac4Key,       k4_SkKey        },
2896efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac5Key,       k5_SkKey        },
2906efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac6Key,       k6_SkKey        },
2916efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac7Key,       k7_SkKey        },
2926efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac8Key,       k8_SkKey        },
2936efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        { SK_Mac9Key,       k9_SkKey        }
294d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    };
2955782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
296d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
297d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        if (gKeys[i].fRaw == raw)
298d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            return gKeys[i].fKey;
299d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return kNONE_SkKey;
3006efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
3016efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
3026efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void post_skmacevent()
3036efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
304d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    EventRef    ref;
305d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    OSStatus    status = CreateEvent(nil, SK_MacEventClass, SK_MacEventKind, 0, 0, &ref);
306d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
3075782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
3086efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#if 0
309d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    status = SetEventParameter(ref, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
310d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
311d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    status = SetEventParameter(ref, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
312d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
3136efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#endif
3145782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
315d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    EventTargetRef target = gEventTarget;
316d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SetEventParameter(ref, kEventParamPostTarget, typeEventTargetRef, sizeof(target), &target);
317d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
3185782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
319d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    status = PostEventToQueue(gCurrEventQ, ref, kEventPriorityStandard);
320d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkASSERT(status == noErr);
3216efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
322d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    ReleaseEvent(ref);
3236efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
3246efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
3256efdc47afc8bb24603fc0d15146ada609b728f2freed@android.compascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* userData )
3266efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
327d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkOSWindow* win = (SkOSWindow*)userData;
328d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    OSStatus    result = eventNotHandledErr;
329d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    UInt32        wClass = GetEventClass(inEvent);
330d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    UInt32        wKind = GetEventKind(inEvent);
3316efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
332d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    gCurrOSWin = win;    // will need to be in TLS. Set this so PostEvent will work
3336efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
334d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    switch (wClass) {
3356efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        case kEventClassMouse: {
336d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            Point   pt;
337d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            getparam(inEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pt), &pt);
338d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SetPortWindowPort((WindowRef)win->getHWND());
339d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            GlobalToLocal(&pt);
3406efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
341d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            switch (wKind) {
342a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                case kEventMouseDown:
343800046eba45c9e982ecfe8964b2107f7713ed639reed@android.com                    if (win->handleClick(pt.h, pt.v, Click::kDown_State)) {
344879a252d090a0929c11d8963dbd4328b11d0916freed@android.com                        result = noErr;
345800046eba45c9e982ecfe8964b2107f7713ed639reed@android.com                    }
346a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    break;
3470f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo                case kEventMouseMoved:
3480f185c2709f638c0f4d452cb38b434cadfd15ab9Scroggo                    // fall through
349a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                case kEventMouseDragged:
350a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    (void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
351800046eba45c9e982ecfe8964b2107f7713ed639reed@android.com                  //  result = noErr;
352a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    break;
353a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                case kEventMouseUp:
354a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    (void)win->handleClick(pt.h, pt.v, Click::kUp_State);
355800046eba45c9e982ecfe8964b2107f7713ed639reed@android.com                  //  result = noErr;
356a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    break;
357a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                default:
358a03a70124ddf450ac986eef3d4aeb50e103e0e19reed@android.com                    break;
359d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            }
3606efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
361d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        }
3626efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        case kEventClassKeyboard:
3636efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            if (wKind == kEventRawKeyDown) {
3646efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                UInt32  raw;
3656efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
3666efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                SkKey key = raw2key(raw);
3676efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                if (key != kNONE_SkKey)
3686efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    (void)win->handleKey(key);
3696efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            } else if (wKind == kEventRawKeyUp) {
3706efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                UInt32 raw;
3716efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
3726efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                SkKey key = raw2key(raw);
3736efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                if (key != kNONE_SkKey)
3746efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    (void)win->handleKeyUp(key);
3756efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            }
3766efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
3776efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        case kEventClassTextInput:
3786efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            if (wKind == kEventTextInputUnicodeForKeyEvent) {
3796efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                UInt16  uni;
3806efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                getparam(inEvent, kEventParamTextInputSendText, typeUnicodeText, sizeof(uni), &uni);
3816efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                win->handleChar(uni);
3826efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            }
3836efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
3846efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        case kEventClassWindow:
3856efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            switch (wKind) {
3866efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                case kEventWindowBoundsChanged:
3876efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    win->updateSize();
3886efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    break;
3896efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                case kEventWindowDrawContent: {
3906efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    CGContextRef cg;
3916efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    result = GetEventParameter(inEvent,
3926efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               kEventParamCGContextRef,
3936efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               typeCGContextRef,
3946efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               NULL,
3956efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               sizeof (CGContextRef),
3966efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               NULL,
3976efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                                               &cg);
3986efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    if (result != 0) {
3996efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                        cg = NULL;
4006efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    }
4016efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    win->doPaint(cg);
4026efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    break;
4036efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                }
4046efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                default:
4056efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    break;
4066efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            }
4076efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
4086efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        case SK_MacEventClass: {
4096efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            SkASSERT(wKind == SK_MacEventKind);
4106efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            if (SkEvent::ProcessEvent()) {
4116efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com                    post_skmacevent();
4126efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            }
4136efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    #if 0
414d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkEvent*        evt;
415d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkEventSinkID    sinkID;
4166efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            getparam(inEvent, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
4176efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            getparam(inEvent, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
4186efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    #endif
4196efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            result = noErr;
4206efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
4216efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        }
4226efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com        default:
4236efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com            break;
4246efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com    }
425d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (result == eventNotHandledErr) {
426d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        result = CallNextEventHandler(inHandler, inEvent);
427d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
428d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    return result;
4296efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
4306efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
4316efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com///////////////////////////////////////////////////////////////////////////////////////
4326efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
4336efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkEvent::SignalNonEmptyQueue()
4346efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
435d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    post_skmacevent();
436d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com//    SkDebugf("signal nonempty\n");
4376efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
4386efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
439d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic TMTask    gTMTaskRec;
440d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic TMTask*    gTMTaskPtr;
4416efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
4426efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comstatic void sk_timer_proc(TMTask* rec)
4436efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
444d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    SkEvent::ServiceQueueTimer();
445d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com//    SkDebugf("timer task fired\n");
4466efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
4476efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
4486efdc47afc8bb24603fc0d15146ada609b728f2freed@android.comvoid SkEvent::SignalQueueTimer(SkMSec delay)
4496efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com{
450d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (gTMTaskPtr)
451d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
452d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        RemoveTimeTask((QElem*)gTMTaskPtr);
453d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        DisposeTimerUPP(gTMTaskPtr->tmAddr);
454d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        gTMTaskPtr = nil;
455d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
456d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    if (delay)
457d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    {
458d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        gTMTaskPtr = &gTMTaskRec;
459d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        memset(gTMTaskPtr, 0, sizeof(gTMTaskRec));
460d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        gTMTaskPtr->tmAddr = NewTimerUPP(sk_timer_proc);
461d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        OSErr err = InstallTimeTask((QElem*)gTMTaskPtr);
462d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com//        SkDebugf("installtimetask of %d returned %d\n", delay, err);
463d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        PrimeTimeTask((QElem*)gTMTaskPtr, delay);
464d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    }
4656efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com}
4666efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com
467205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com#define USE_MSAA 0
468205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com
469498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.comAGLContext create_gl(WindowRef wref)
470f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com{
471f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    GLint major, minor;
472f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    AGLContext ctx;
4735782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
474f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglGetVersion(&major, &minor);
475f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf("---- agl version %d %d\n", major, minor);
4765782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
477f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    const GLint pixelAttrs[] = {
478f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        AGL_RGBA,
479f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        AGL_STENCIL_SIZE, 8,
480205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com#if USE_MSAA
481f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        AGL_SAMPLE_BUFFERS_ARB, 1,
482205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com        AGL_MULTISAMPLE,
483205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com        AGL_SAMPLES_ARB, 8,
484205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com#endif
485205ddd7452c56bc465fc3800eeec4ec8fbb6485fbsalomon@google.com        AGL_ACCELERATED,
486498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        AGL_DOUBLEBUFFER,
487f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        AGL_NONE
488f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    };
489f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
490f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    //AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
491f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf("----- agl format %p\n", format);
492f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    ctx = aglCreateContext(format, NULL);
493f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    SkDebugf("----- agl context %p\n", ctx);
494f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglDestroyPixelFormat(format);
495f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
496f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    static const GLint interval = 1;
497f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglSetInteger(ctx, AGL_SWAP_INTERVAL, &interval);
498f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglSetCurrentContext(ctx);
499f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return ctx;
500f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
501f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
502b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.combool SkOSWindow::attach(SkBackEndTypes /* attachType */)
503f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com{
504f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (NULL == fAGLCtx) {
505498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        fAGLCtx = create_gl((WindowRef)fHWND);
506f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        if (NULL == fAGLCtx) {
507f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com            return false;
508f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        }
509f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
510f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
511f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    GLboolean success = true;
512f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5135782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com    int width, height;
5145782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
515498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com    success = aglSetWindowRef((AGLContext)fAGLCtx, (WindowRef)fHWND);
516498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com    width = this->width();
517498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com    height = this->height();
518f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
519f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    GLenum err = aglGetError();
520f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (err) {
521498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com        SkDebugf("---- aglSetWindowRef %d %d %s [%d %d]\n", success, err,
522498a623e2eacb709c23e5c5be6d4991ad83ab167bsalomon@google.com                 aglErrorString(err), width, height);
523f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
5245782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com
525f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    if (success) {
5265782d712ffc31557d0cb12d5a220cebb783f6895bsalomon@google.com        glViewport(0, 0, width, height);
527f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        glClearColor(0, 0, 0, 0);
5282e7b43d33cc495663cb814a7a9d1ecdc09c31828bsalomon@google.com        glClearStencil(0);
529f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com        glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
530f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    }
531f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    return success;
532f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
533f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
534b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.comvoid SkOSWindow::detach() {
535f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglSetWindowRef((AGLContext)fAGLCtx, NULL);
536f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
537f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
538b442a6d5726569364e15c3056bbfb59b9b6e38cerobertphillips@google.comvoid SkOSWindow::present() {
539f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com    aglSwapBuffers((AGLContext)fAGLCtx);
540f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com}
541f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com
5426efdc47afc8bb24603fc0d15146ada609b728f2freed@android.com#endif
543