yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 1 | #import <UIKit/UIKit.h> |
| 2 | #import <OpenGLES/EAGL.h> |
| 3 | #import <OpenGLES/ES1/gl.h> |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 4 | #include "SkCanvas.h" |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 5 | #include "SkGraphics.h" |
| 6 | #import "SkIOSNotifier.h" |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 7 | #include "SkOSMenu.h" |
| 8 | #include "SkTime.h" |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 9 | #include "SkTypes.h" |
yangsu@google.com | c5aeccd | 2011-07-17 14:42:08 +0000 | [diff] [blame^] | 10 | #import "SkUIView.h" |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 11 | #include "SkWindow.h" |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 12 | |
| 13 | #define kINVAL_UIVIEW_EventType "inval-uiview" |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 14 | |
| 15 | SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd) { |
| 16 | fInvalEventIsPending = false; |
| 17 | fNotifier = [[SkIOSNotifier alloc] init]; |
| 18 | } |
| 19 | SkOSWindow::~SkOSWindow() { |
| 20 | [(SkIOSNotifier*)fNotifier release]; |
| 21 | } |
| 22 | |
| 23 | void SkOSWindow::onHandleInval(const SkIRect& r) { |
| 24 | if (!fInvalEventIsPending) { |
| 25 | fInvalEventIsPending = true; |
| 26 | (new SkEvent(kINVAL_UIVIEW_EventType))->post(this->getSinkID()); |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | bool SkOSWindow::onEvent(const SkEvent& evt) { |
| 31 | if (evt.isType(kINVAL_UIVIEW_EventType)) { |
| 32 | fInvalEventIsPending = false; |
| 33 | const SkIRect& r = this->getDirtyBounds(); |
yangsu@google.com | c5aeccd | 2011-07-17 14:42:08 +0000 | [diff] [blame^] | 34 | [(SkUIView*)fHWND postInvalWithRect:&r]; |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 35 | return true; |
| 36 | } |
yangsu@google.com | c5aeccd | 2011-07-17 14:42:08 +0000 | [diff] [blame^] | 37 | if ([(SkUIView*)fHWND onHandleEvent:evt]) { |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 38 | return true; |
| 39 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 40 | return this->INHERITED::onEvent(evt); |
| 41 | } |
| 42 | |
| 43 | bool SkOSWindow::onDispatchClick(int x, int y, Click::State state, void* owner) { |
| 44 | return this->INHERITED::onDispatchClick(x, y, state, owner); |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | void SkOSWindow::onSetTitle(const char title[]) { |
yangsu@google.com | c5aeccd | 2011-07-17 14:42:08 +0000 | [diff] [blame^] | 48 | [(SkUIView*)fHWND setSkTitle:title]; |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 49 | } |
| 50 | |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 51 | void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) { |
| 52 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | /////////////////////////////////////////////////////////////////////////////////////// |
| 56 | /* |
| 57 | #if 1 |
| 58 | static void NonEmptyCallback(CFRunLoopTimerRef timer, void*) { |
| 59 | // printf("------- event queue depth = %d\n", SkEvent::CountEventsOnQueue()); |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 60 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 61 | if (!SkEvent::ProcessEvent()) { |
| 62 | CFRunLoopTimerInvalidate(timer); |
| 63 | } |
| 64 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 65 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 66 | void SkEvent::SignalNonEmptyQueue() { |
| 67 | double tinyDelay = 1.0 / 60; |
| 68 | CFRunLoopTimerRef timer; |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 69 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 70 | timer = CFRunLoopTimerCreate(NULL, |
| 71 | CACurrentMediaTime() + tinyDelay, |
| 72 | tinyDelay, |
| 73 | 0, |
| 74 | 0, |
| 75 | NonEmptyCallback, |
| 76 | NULL); |
| 77 | CFRunLoopAddTimer(CFRunLoopGetCurrent(), |
| 78 | timer, |
| 79 | kCFRunLoopCommonModes); |
| 80 | CFRelease(timer); |
| 81 | } |
| 82 | #elif 1 |
| 83 | #if 0 |
| 84 | #define NONE_EMPTY_CODE(code) code |
| 85 | #else |
| 86 | #define NONE_EMPTY_CODE(code) |
| 87 | #endif |
| 88 | static CFRunLoopSourceRef gNonEmptySource; |
| 89 | static CFRunLoopRef gNoneEmptyRunLoop; |
| 90 | static bool gAlreadySignaled; |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 91 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 92 | static void signal_nonempty() { |
| 93 | if (!gAlreadySignaled) { |
| 94 | NONE_EMPTY_CODE(printf("--- before resignal\n");) |
| 95 | gAlreadySignaled = true; |
| 96 | CFRunLoopSourceSignal(gNonEmptySource); |
| 97 | CFRunLoopWakeUp(gNoneEmptyRunLoop); |
| 98 | NONE_EMPTY_CODE(printf("--- after resignal\n");) |
| 99 | } |
| 100 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 101 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 102 | static void NonEmptySourceCallback(void*) { |
| 103 | gAlreadySignaled = false; |
| 104 | NONE_EMPTY_CODE(printf("---- service NonEmptySourceCallback %d\n", SkEvent::CountEventsOnQueue());) |
| 105 | if (SkEvent::ProcessEvent()) { |
| 106 | signal_nonempty(); |
| 107 | } |
| 108 | NONE_EMPTY_CODE(printf("----- after service\n");) |
| 109 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 110 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 111 | void SkEvent::SignalNonEmptyQueue() { |
| 112 | if (NULL == gNonEmptySource) { |
| 113 | gNoneEmptyRunLoop = CFRunLoopGetMain(); |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 114 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 115 | CFIndex order = 0; // should this be lower, to not start UIEvents? |
| 116 | CFRunLoopSourceContext context; |
| 117 | sk_bzero(&context, sizeof(context)); |
| 118 | // give it a "unique" info, for the default Hash function |
| 119 | context.info = (void*)NonEmptySourceCallback; |
| 120 | // our perform callback |
| 121 | context.perform = NonEmptySourceCallback; |
| 122 | gNonEmptySource = CFRunLoopSourceCreate(NULL, order, &context); |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 123 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 124 | CFRunLoopAddSource(gNoneEmptyRunLoop, |
| 125 | gNonEmptySource, |
| 126 | kCFRunLoopCommonModes); |
| 127 | } |
| 128 | signal_nonempty(); |
| 129 | } |
| 130 | #elif 1 |
| 131 | @interface NonEmptyHandler : NSObject {} |
| 132 | - (void)signalNonEmptyQ; |
| 133 | @end |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 134 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 135 | @implementation NonEmptyHandler |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 136 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 137 | - (void)callProccessEvent { |
| 138 | // printf("----- callProcessEvent\n"); |
| 139 | if (SkEvent::ProcessEvent()) { |
| 140 | [self signalNonEmptyQ]; |
| 141 | } |
| 142 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 143 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 144 | - (void)signalNonEmptyQ { |
| 145 | [self performSelectorOnMainThread:@selector(callProccessEvent) withObject:nil waitUntilDone:NO]; |
| 146 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 147 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 148 | void SkEvent::SignalNonEmptyQueue() { |
| 149 | static id gNonEmptyQueueObject; |
| 150 | if (nil == gNonEmptyQueueObject) { |
| 151 | gNonEmptyQueueObject = [[NonEmptyHandler alloc] init]; |
| 152 | } |
| 153 | [gNonEmptyQueueObject signalNonEmptyQ]; |
| 154 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 155 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 156 | @end |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 157 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 158 | #endif |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 159 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 160 | /////////////////////////////////////////////////////////////////////////////// |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 161 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 162 | static CFRunLoopTimerRef gTimer; |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 163 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 164 | static void TimerCallback(CFRunLoopTimerRef timer, void* info) { |
| 165 | gTimer = NULL; |
| 166 | SkEvent::ServiceQueueTimer(); |
| 167 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 168 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 169 | void SkEvent::SignalQueueTimer(SkMSec delay) |
| 170 | { |
| 171 | //We always release the timer right after we've added it to our RunLoop, |
| 172 | //thus we don't worry about freeing it later: if it fires our callback, |
| 173 | //it gets automatically freed, as it does if we call invalidate() |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 174 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 175 | if (gTimer) { |
| 176 | // our callback wasn't called, so invalidate it |
| 177 | CFRunLoopTimerInvalidate(gTimer); |
| 178 | gTimer = NULL; |
| 179 | } |
yangsu@google.com | 2e20c24 | 2011-07-07 19:26:42 +0000 | [diff] [blame] | 180 | |
yangsu@google.com | 1a2b4c1 | 2011-06-24 17:20:50 +0000 | [diff] [blame] | 181 | if (delay) { |
| 182 | gTimer = CFRunLoopTimerCreate(NULL, |
| 183 | CACurrentMediaTime() + delay/1000.0, |
| 184 | // CFAbsoluteTimeGetCurrent() + delay/1000.0, |
| 185 | 0, |
| 186 | 0, |
| 187 | 0, |
| 188 | TimerCallback, |
| 189 | NULL); |
| 190 | CFRunLoopAddTimer(CFRunLoopGetCurrent(), |
| 191 | gTimer, |
| 192 | kCFRunLoopCommonModes); |
| 193 | CFRelease(gTimer); |
| 194 | } |
| 195 | } |
| 196 | */ |
| 197 | /////////////////////////////////////////////////////////////////////////////////////// |
| 198 | |
| 199 | bool SkOSWindow::attachGL() |
| 200 | { |
| 201 | bool success = true; |
| 202 | return success; |
| 203 | } |
| 204 | |
| 205 | void SkOSWindow::detachGL() { |
| 206 | } |
| 207 | |
| 208 | void SkOSWindow::presentGL() { |
| 209 | glFlush(); |
| 210 | } |