gfx/skia/trunk/src/views/mac/SkOSWindow_Mac.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2011 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkTypes.h"
    10 #if defined(SK_BUILD_FOR_MAC)
    12 #include <AGL/agl.h>
    14 #include <Carbon/Carbon.h>
    15 #include "SkCGUtils.h"
    17 #include "SkWindow.h"
    18 #include "SkCanvas.h"
    19 #include "SkOSMenu.h"
    20 #include "SkTime.h"
    22 #include "SkGraphics.h"
    23 #include <new.h>
    25 static void (*gPrevNewHandler)();
    27 extern "C" {
    28     static void sk_new_handler()
    29     {
    30         if (SkGraphics::SetFontCacheUsed(0))
    31             return;
    32         if (gPrevNewHandler)
    33             gPrevNewHandler();
    34         else
    35             sk_throw();
    36     }
    37 }
    39 static SkOSWindow* gCurrOSWin;
    40 static EventTargetRef gEventTarget;
    41 static EventQueueRef gCurrEventQ;
    43 static OSStatus MyDrawEventHandler(EventHandlerCallRef myHandler,
    44                                    EventRef event, void *userData) {
    45     // NOTE: GState is save/restored by the HIView system doing the callback,
    46     // so the draw handler doesn't need to do it
    48     OSStatus status = noErr;
    49     CGContextRef context;
    50     HIRect        bounds;
    52     // Get the CGContextRef
    53     status = GetEventParameter (event, kEventParamCGContextRef,
    54                                 typeCGContextRef, NULL,
    55                                 sizeof (CGContextRef),
    56                                 NULL,
    57                                 &context);
    59     if (status != noErr) {
    60         SkDebugf("Got error %d getting the context!\n", status);
    61         return status;
    62     }
    64     // Get the bounding rectangle
    65     HIViewGetBounds ((HIViewRef) userData, &bounds);
    67     gCurrOSWin->doPaint(context);
    68     return status;
    69 }
    71 #define SK_MacEventClass            FOUR_CHAR_CODE('SKec')
    72 #define SK_MacEventKind                FOUR_CHAR_CODE('SKek')
    73 #define SK_MacEventParamName        FOUR_CHAR_CODE('SKev')
    74 #define SK_MacEventSinkIDParamName    FOUR_CHAR_CODE('SKes')
    76 static void set_bindingside(HISideBinding* side, HIViewRef parent, HIBindingKind kind) {
    77     side->toView = parent;
    78     side->kind = kind;
    79     side->offset = 0;
    80 }
    82 static void set_axisscale(HIAxisScale* axis, HIViewRef parent) {
    83     axis->toView = parent;
    84     axis->kind = kHILayoutScaleAbsolute;
    85     axis->ratio = 1;
    86 }
    88 static void set_axisposition(HIAxisPosition* pos, HIViewRef parent, HIPositionKind kind) {
    89     pos->toView = parent;
    90     pos->kind = kind;
    91     pos->offset = 0;
    92 }
    94 SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), fAGLCtx(NULL)
    95 {
    96     OSStatus    result;
    97     WindowRef   wr = (WindowRef)hWnd;
    99     HIViewRef imageView, parent;
   100     HIViewRef rootView = HIViewGetRoot(wr);
   101     HIViewFindByID(rootView, kHIViewWindowContentID, &parent);
   102     result = HIImageViewCreate(NULL, &imageView);
   103     SkASSERT(result == noErr);
   105     result = HIViewAddSubview(parent, imageView);
   106     SkASSERT(result == noErr);
   108     fHVIEW = imageView;
   110     HIViewSetVisible(imageView, true);
   111     HIViewPlaceInSuperviewAt(imageView, 0, 0);
   113     if (true) {
   114         HILayoutInfo layout;
   115         layout.version = kHILayoutInfoVersionZero;
   116         set_bindingside(&layout.binding.left, parent, kHILayoutBindLeft);
   117         set_bindingside(&layout.binding.top, parent, kHILayoutBindTop);
   118         set_bindingside(&layout.binding.right, parent, kHILayoutBindRight);
   119         set_bindingside(&layout.binding.bottom, parent, kHILayoutBindBottom);
   120         set_axisscale(&layout.scale.x, parent);
   121         set_axisscale(&layout.scale.y, parent);
   122         set_axisposition(&layout.position.x, parent, kHILayoutPositionLeft);
   123         set_axisposition(&layout.position.y, rootView, kHILayoutPositionTop);
   124         HIViewSetLayoutInfo(imageView, &layout);
   125     }
   127     HIImageViewSetOpaque(imageView, true);
   128     HIImageViewSetScaleToFit(imageView, false);
   130     static const EventTypeSpec  gTypes[] = {
   131         { kEventClassKeyboard,  kEventRawKeyDown            },
   132         { kEventClassKeyboard,  kEventRawKeyUp              },
   133         { kEventClassMouse,        kEventMouseDown                },
   134         { kEventClassMouse,        kEventMouseDragged            },
   135         { kEventClassMouse,        kEventMouseMoved            },
   136         { kEventClassMouse,        kEventMouseUp                },
   137         { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent   },
   138         { kEventClassWindow,    kEventWindowBoundsChanged    },
   139 //        { kEventClassWindow,    kEventWindowDrawContent        },
   140         { SK_MacEventClass,        SK_MacEventKind                }
   141     };
   143     EventHandlerUPP handlerUPP = NewEventHandlerUPP(SkOSWindow::EventHandler);
   144     int                count = SK_ARRAY_COUNT(gTypes);
   146     result = InstallEventHandler(GetWindowEventTarget(wr), handlerUPP,
   147                         count, gTypes, this, nil);
   148     SkASSERT(result == noErr);
   150     gCurrOSWin = this;
   151     gCurrEventQ = GetCurrentEventQueue();
   152     gEventTarget = GetWindowEventTarget(wr);
   154     static bool gOnce = true;
   155     if (gOnce) {
   156         gOnce = false;
   157         gPrevNewHandler = set_new_handler(sk_new_handler);
   158     }
   159 }
   161 void SkOSWindow::doPaint(void* ctx)
   162 {
   163 #if 0
   164     this->update(NULL);
   166     const SkBitmap& bm = this->getBitmap();
   167     CGImageRef img = SkCreateCGImageRef(bm);
   169     if (img) {
   170         CGRect r = CGRectMake(0, 0, bm.width(), bm.height());
   172         CGContextRef cg = reinterpret_cast<CGContextRef>(ctx);
   174         CGContextSaveGState(cg);
   175         CGContextTranslateCTM(cg, 0, r.size.height);
   176         CGContextScaleCTM(cg, 1, -1);
   178         CGContextDrawImage(cg, r, img);
   180         CGContextRestoreGState(cg);
   182         CGImageRelease(img);
   183     }
   184 #endif
   185 }
   187 void SkOSWindow::updateSize()
   188 {
   189     Rect    r;
   191     GetWindowBounds((WindowRef)fHWND, kWindowContentRgn, &r);
   192     this->resize(r.right - r.left, r.bottom - r.top);
   194 #if 0
   195     HIRect    frame;
   196     HIViewRef imageView = (HIViewRef)getHVIEW();
   197     HIViewRef parent = HIViewGetSuperview(imageView);
   199     HIViewGetBounds(imageView, &frame);
   200     SkDebugf("------ %d bounds %g %g %g %g\n", r.right - r.left,
   201              frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
   202 #endif
   203 }
   205 void SkOSWindow::onHandleInval(const SkIRect& r)
   206 {
   207     (new SkEvent("inval-imageview", this->getSinkID()))->post();
   208 }
   210 bool SkOSWindow::onEvent(const SkEvent& evt) {
   211     if (evt.isType("inval-imageview")) {
   212         this->update(NULL);
   214         SkEvent query("ignore-window-bitmap");
   215         if (!this->doQuery(&query) || !query.getFast32()) {
   216             const SkBitmap& bm = this->getBitmap();
   218             CGImageRef img = SkCreateCGImageRef(bm);
   219             HIImageViewSetImage((HIViewRef)getHVIEW(), img);
   220             CGImageRelease(img);
   221         }
   222         return true;
   223     }
   224     return INHERITED::onEvent(evt);
   225 }
   227 void SkOSWindow::onSetTitle(const char title[])
   228 {
   229     CFStringRef str = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
   230     SetWindowTitleWithCFString((WindowRef)fHWND, str);
   231     CFRelease(str);
   232 }
   234 void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu)
   235 {
   236 }
   238 static void getparam(EventRef inEvent, OSType name, OSType type, UInt32 size, void* data)
   239 {
   240     EventParamType  actualType;
   241     UInt32            actualSize;
   242     OSStatus        status;
   244     status = GetEventParameter(inEvent, name, type, &actualType, size, &actualSize, data);
   245     SkASSERT(status == noErr);
   246     SkASSERT(actualType == type);
   247     SkASSERT(actualSize == size);
   248 }
   250 enum {
   251     SK_MacReturnKey        = 36,
   252     SK_MacDeleteKey        = 51,
   253     SK_MacEndKey        = 119,
   254     SK_MacLeftKey        = 123,
   255     SK_MacRightKey        = 124,
   256     SK_MacDownKey        = 125,
   257     SK_MacUpKey            = 126,
   259     SK_Mac0Key          = 0x52,
   260     SK_Mac1Key          = 0x53,
   261     SK_Mac2Key          = 0x54,
   262     SK_Mac3Key          = 0x55,
   263     SK_Mac4Key          = 0x56,
   264     SK_Mac5Key          = 0x57,
   265     SK_Mac6Key          = 0x58,
   266     SK_Mac7Key          = 0x59,
   267     SK_Mac8Key          = 0x5b,
   268     SK_Mac9Key          = 0x5c
   269 };
   271 static SkKey raw2key(UInt32 raw)
   272 {
   273     static const struct {
   274         UInt32  fRaw;
   275         SkKey   fKey;
   276     } gKeys[] = {
   277         { SK_MacUpKey,        kUp_SkKey        },
   278         { SK_MacDownKey,    kDown_SkKey        },
   279         { SK_MacLeftKey,    kLeft_SkKey        },
   280         { SK_MacRightKey,   kRight_SkKey    },
   281         { SK_MacReturnKey,  kOK_SkKey        },
   282         { SK_MacDeleteKey,  kBack_SkKey        },
   283         { SK_MacEndKey,        kEnd_SkKey        },
   284         { SK_Mac0Key,       k0_SkKey        },
   285         { SK_Mac1Key,       k1_SkKey        },
   286         { SK_Mac2Key,       k2_SkKey        },
   287         { SK_Mac3Key,       k3_SkKey        },
   288         { SK_Mac4Key,       k4_SkKey        },
   289         { SK_Mac5Key,       k5_SkKey        },
   290         { SK_Mac6Key,       k6_SkKey        },
   291         { SK_Mac7Key,       k7_SkKey        },
   292         { SK_Mac8Key,       k8_SkKey        },
   293         { SK_Mac9Key,       k9_SkKey        }
   294     };
   296     for (unsigned i = 0; i < SK_ARRAY_COUNT(gKeys); i++)
   297         if (gKeys[i].fRaw == raw)
   298             return gKeys[i].fKey;
   299     return kNONE_SkKey;
   300 }
   302 static void post_skmacevent()
   303 {
   304     EventRef    ref;
   305     OSStatus    status = CreateEvent(nil, SK_MacEventClass, SK_MacEventKind, 0, 0, &ref);
   306     SkASSERT(status == noErr);
   308 #if 0
   309     status = SetEventParameter(ref, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
   310     SkASSERT(status == noErr);
   311     status = SetEventParameter(ref, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
   312     SkASSERT(status == noErr);
   313 #endif
   315     EventTargetRef target = gEventTarget;
   316     SetEventParameter(ref, kEventParamPostTarget, typeEventTargetRef, sizeof(target), &target);
   317     SkASSERT(status == noErr);
   319     status = PostEventToQueue(gCurrEventQ, ref, kEventPriorityStandard);
   320     SkASSERT(status == noErr);
   322     ReleaseEvent(ref);
   323 }
   325 pascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRef inEvent, void* userData )
   326 {
   327     SkOSWindow* win = (SkOSWindow*)userData;
   328     OSStatus    result = eventNotHandledErr;
   329     UInt32        wClass = GetEventClass(inEvent);
   330     UInt32        wKind = GetEventKind(inEvent);
   332     gCurrOSWin = win;    // will need to be in TLS. Set this so PostEvent will work
   334     switch (wClass) {
   335         case kEventClassMouse: {
   336             Point   pt;
   337             getparam(inEvent, kEventParamMouseLocation, typeQDPoint, sizeof(pt), &pt);
   338             SetPortWindowPort((WindowRef)win->getHWND());
   339             GlobalToLocal(&pt);
   341             switch (wKind) {
   342                 case kEventMouseDown:
   343                     if (win->handleClick(pt.h, pt.v, Click::kDown_State)) {
   344                         result = noErr;
   345                     }
   346                     break;
   347                 case kEventMouseMoved:
   348                     // fall through
   349                 case kEventMouseDragged:
   350                     (void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
   351                   //  result = noErr;
   352                     break;
   353                 case kEventMouseUp:
   354                     (void)win->handleClick(pt.h, pt.v, Click::kUp_State);
   355                   //  result = noErr;
   356                     break;
   357                 default:
   358                     break;
   359             }
   360             break;
   361         }
   362         case kEventClassKeyboard:
   363             if (wKind == kEventRawKeyDown) {
   364                 UInt32  raw;
   365                 getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
   366                 SkKey key = raw2key(raw);
   367                 if (key != kNONE_SkKey)
   368                     (void)win->handleKey(key);
   369             } else if (wKind == kEventRawKeyUp) {
   370                 UInt32 raw;
   371                 getparam(inEvent, kEventParamKeyCode, typeUInt32, sizeof(raw), &raw);
   372                 SkKey key = raw2key(raw);
   373                 if (key != kNONE_SkKey)
   374                     (void)win->handleKeyUp(key);
   375             }
   376             break;
   377         case kEventClassTextInput:
   378             if (wKind == kEventTextInputUnicodeForKeyEvent) {
   379                 UInt16  uni;
   380                 getparam(inEvent, kEventParamTextInputSendText, typeUnicodeText, sizeof(uni), &uni);
   381                 win->handleChar(uni);
   382             }
   383             break;
   384         case kEventClassWindow:
   385             switch (wKind) {
   386                 case kEventWindowBoundsChanged:
   387                     win->updateSize();
   388                     break;
   389                 case kEventWindowDrawContent: {
   390                     CGContextRef cg;
   391                     result = GetEventParameter(inEvent,
   392                                                kEventParamCGContextRef,
   393                                                typeCGContextRef,
   394                                                NULL,
   395                                                sizeof (CGContextRef),
   396                                                NULL,
   397                                                &cg);
   398                     if (result != 0) {
   399                         cg = NULL;
   400                     }
   401                     win->doPaint(cg);
   402                     break;
   403                 }
   404                 default:
   405                     break;
   406             }
   407             break;
   408         case SK_MacEventClass: {
   409             SkASSERT(wKind == SK_MacEventKind);
   410             if (SkEvent::ProcessEvent()) {
   411                     post_skmacevent();
   412             }
   413     #if 0
   414             SkEvent*        evt;
   415             SkEventSinkID    sinkID;
   416             getparam(inEvent, SK_MacEventParamName, SK_MacEventParamName, sizeof(evt), &evt);
   417             getparam(inEvent, SK_MacEventSinkIDParamName, SK_MacEventSinkIDParamName, sizeof(sinkID), &sinkID);
   418     #endif
   419             result = noErr;
   420             break;
   421         }
   422         default:
   423             break;
   424     }
   425     if (result == eventNotHandledErr) {
   426         result = CallNextEventHandler(inHandler, inEvent);
   427     }
   428     return result;
   429 }
   431 ///////////////////////////////////////////////////////////////////////////////////////
   433 void SkEvent::SignalNonEmptyQueue()
   434 {
   435     post_skmacevent();
   436 //    SkDebugf("signal nonempty\n");
   437 }
   439 static TMTask    gTMTaskRec;
   440 static TMTask*    gTMTaskPtr;
   442 static void sk_timer_proc(TMTask* rec)
   443 {
   444     SkEvent::ServiceQueueTimer();
   445 //    SkDebugf("timer task fired\n");
   446 }
   448 void SkEvent::SignalQueueTimer(SkMSec delay)
   449 {
   450     if (gTMTaskPtr)
   451     {
   452         RemoveTimeTask((QElem*)gTMTaskPtr);
   453         DisposeTimerUPP(gTMTaskPtr->tmAddr);
   454         gTMTaskPtr = nil;
   455     }
   456     if (delay)
   457     {
   458         gTMTaskPtr = &gTMTaskRec;
   459         memset(gTMTaskPtr, 0, sizeof(gTMTaskRec));
   460         gTMTaskPtr->tmAddr = NewTimerUPP(sk_timer_proc);
   461         OSErr err = InstallTimeTask((QElem*)gTMTaskPtr);
   462 //        SkDebugf("installtimetask of %d returned %d\n", delay, err);
   463         PrimeTimeTask((QElem*)gTMTaskPtr, delay);
   464     }
   465 }
   467 #define USE_MSAA 0
   469 AGLContext create_gl(WindowRef wref)
   470 {
   471     GLint major, minor;
   472     AGLContext ctx;
   474     aglGetVersion(&major, &minor);
   475     SkDebugf("---- agl version %d %d\n", major, minor);
   477     const GLint pixelAttrs[] = {
   478         AGL_RGBA,
   479         AGL_STENCIL_SIZE, 8,
   480 #if USE_MSAA
   481         AGL_SAMPLE_BUFFERS_ARB, 1,
   482         AGL_MULTISAMPLE,
   483         AGL_SAMPLES_ARB, 8,
   484 #endif
   485         AGL_ACCELERATED,
   486         AGL_DOUBLEBUFFER,
   487         AGL_NONE
   488     };
   489     AGLPixelFormat format = aglChoosePixelFormat(NULL, 0, pixelAttrs);
   490     //AGLPixelFormat format = aglCreatePixelFormat(pixelAttrs);
   491     SkDebugf("----- agl format %p\n", format);
   492     ctx = aglCreateContext(format, NULL);
   493     SkDebugf("----- agl context %p\n", ctx);
   494     aglDestroyPixelFormat(format);
   496     static const GLint interval = 1;
   497     aglSetInteger(ctx, AGL_SWAP_INTERVAL, &interval);
   498     aglSetCurrentContext(ctx);
   499     return ctx;
   500 }
   502 bool SkOSWindow::attach(SkBackEndTypes /* attachType */)
   503 {
   504     if (NULL == fAGLCtx) {
   505         fAGLCtx = create_gl((WindowRef)fHWND);
   506         if (NULL == fAGLCtx) {
   507             return false;
   508         }
   509     }
   511     GLboolean success = true;
   513     int width, height;
   515     success = aglSetWindowRef((AGLContext)fAGLCtx, (WindowRef)fHWND);
   516     width = this->width();
   517     height = this->height();
   519     GLenum err = aglGetError();
   520     if (err) {
   521         SkDebugf("---- aglSetWindowRef %d %d %s [%d %d]\n", success, err,
   522                  aglErrorString(err), width, height);
   523     }
   525     if (success) {
   526         glViewport(0, 0, width, height);
   527         glClearColor(0, 0, 0, 0);
   528         glClearStencil(0);
   529         glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
   530     }
   531     return success;
   532 }
   534 void SkOSWindow::detach() {
   535     aglSetWindowRef((AGLContext)fAGLCtx, NULL);
   536 }
   538 void SkOSWindow::present() {
   539     aglSwapBuffers((AGLContext)fAGLCtx);
   540 }
   542 #endif

mercurial