blob: f076641b27660861f812e1f51beae85022f3f093 [file] [log] [blame]
yangsu@google.com1a2b4c12011-06-24 17:20:50 +00001#import <UIKit/UIKit.h>
2#import <OpenGLES/EAGL.h>
3#import <OpenGLES/ES1/gl.h>
yangsu@google.com1a2b4c12011-06-24 17:20:50 +00004#include "SkCanvas.h"
yangsu@google.com2e20c242011-07-07 19:26:42 +00005#include "SkGraphics.h"
6#import "SkIOSNotifier.h"
yangsu@google.com1a2b4c12011-06-24 17:20:50 +00007#include "SkOSMenu.h"
8#include "SkTime.h"
yangsu@google.com2e20c242011-07-07 19:26:42 +00009#include "SkTypes.h"
yangsu@google.comc5aeccd2011-07-17 14:42:08 +000010#import "SkUIView.h"
yangsu@google.com2e20c242011-07-07 19:26:42 +000011#include "SkWindow.h"
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000012
13#define kINVAL_UIVIEW_EventType "inval-uiview"
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000014
15SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd) {
16 fInvalEventIsPending = false;
17 fNotifier = [[SkIOSNotifier alloc] init];
18}
19SkOSWindow::~SkOSWindow() {
20 [(SkIOSNotifier*)fNotifier release];
21}
22
23void SkOSWindow::onHandleInval(const SkIRect& r) {
24 if (!fInvalEventIsPending) {
25 fInvalEventIsPending = true;
26 (new SkEvent(kINVAL_UIVIEW_EventType))->post(this->getSinkID());
27 }
28}
29
30bool SkOSWindow::onEvent(const SkEvent& evt) {
31 if (evt.isType(kINVAL_UIVIEW_EventType)) {
32 fInvalEventIsPending = false;
33 const SkIRect& r = this->getDirtyBounds();
yangsu@google.comc5aeccd2011-07-17 14:42:08 +000034 [(SkUIView*)fHWND postInvalWithRect:&r];
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000035 return true;
36 }
yangsu@google.comc5aeccd2011-07-17 14:42:08 +000037 if ([(SkUIView*)fHWND onHandleEvent:evt]) {
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000038 return true;
39 }
yangsu@google.com2e20c242011-07-07 19:26:42 +000040 return this->INHERITED::onEvent(evt);
41}
42
43bool SkOSWindow::onDispatchClick(int x, int y, Click::State state, void* owner) {
44 return this->INHERITED::onDispatchClick(x, y, state, owner);
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000045}
46
47void SkOSWindow::onSetTitle(const char title[]) {
yangsu@google.comc5aeccd2011-07-17 14:42:08 +000048 [(SkUIView*)fHWND setSkTitle:title];
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000049}
50
yangsu@google.com2e20c242011-07-07 19:26:42 +000051void SkOSWindow::onAddMenu(const SkOSMenu* sk_menu) {
52
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000053}
54
55///////////////////////////////////////////////////////////////////////////////////////
56/*
57 #if 1
58 static void NonEmptyCallback(CFRunLoopTimerRef timer, void*) {
59 // printf("------- event queue depth = %d\n", SkEvent::CountEventsOnQueue());
yangsu@google.com2e20c242011-07-07 19:26:42 +000060
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000061 if (!SkEvent::ProcessEvent()) {
62 CFRunLoopTimerInvalidate(timer);
63 }
64 }
yangsu@google.com2e20c242011-07-07 19:26:42 +000065
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000066 void SkEvent::SignalNonEmptyQueue() {
67 double tinyDelay = 1.0 / 60;
68 CFRunLoopTimerRef timer;
yangsu@google.com2e20c242011-07-07 19:26:42 +000069
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000070 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.com2e20c242011-07-07 19:26:42 +000091
yangsu@google.com1a2b4c12011-06-24 17:20:50 +000092 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.com2e20c242011-07-07 19:26:42 +0000101
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000102 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.com2e20c242011-07-07 19:26:42 +0000110
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000111 void SkEvent::SignalNonEmptyQueue() {
112 if (NULL == gNonEmptySource) {
113 gNoneEmptyRunLoop = CFRunLoopGetMain();
yangsu@google.com2e20c242011-07-07 19:26:42 +0000114
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000115 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.com2e20c242011-07-07 19:26:42 +0000123
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000124 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.com2e20c242011-07-07 19:26:42 +0000134
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000135 @implementation NonEmptyHandler
yangsu@google.com2e20c242011-07-07 19:26:42 +0000136
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000137 - (void)callProccessEvent {
138 // printf("----- callProcessEvent\n");
139 if (SkEvent::ProcessEvent()) {
140 [self signalNonEmptyQ];
141 }
142 }
yangsu@google.com2e20c242011-07-07 19:26:42 +0000143
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000144 - (void)signalNonEmptyQ {
145 [self performSelectorOnMainThread:@selector(callProccessEvent) withObject:nil waitUntilDone:NO];
146 }
yangsu@google.com2e20c242011-07-07 19:26:42 +0000147
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000148 void SkEvent::SignalNonEmptyQueue() {
149 static id gNonEmptyQueueObject;
150 if (nil == gNonEmptyQueueObject) {
151 gNonEmptyQueueObject = [[NonEmptyHandler alloc] init];
152 }
153 [gNonEmptyQueueObject signalNonEmptyQ];
154 }
yangsu@google.com2e20c242011-07-07 19:26:42 +0000155
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000156 @end
yangsu@google.com2e20c242011-07-07 19:26:42 +0000157
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000158 #endif
yangsu@google.com2e20c242011-07-07 19:26:42 +0000159
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000160 ///////////////////////////////////////////////////////////////////////////////
yangsu@google.com2e20c242011-07-07 19:26:42 +0000161
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000162 static CFRunLoopTimerRef gTimer;
yangsu@google.com2e20c242011-07-07 19:26:42 +0000163
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000164 static void TimerCallback(CFRunLoopTimerRef timer, void* info) {
165 gTimer = NULL;
166 SkEvent::ServiceQueueTimer();
167 }
yangsu@google.com2e20c242011-07-07 19:26:42 +0000168
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000169 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.com2e20c242011-07-07 19:26:42 +0000174
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000175 if (gTimer) {
176 // our callback wasn't called, so invalidate it
177 CFRunLoopTimerInvalidate(gTimer);
178 gTimer = NULL;
179 }
yangsu@google.com2e20c242011-07-07 19:26:42 +0000180
yangsu@google.com1a2b4c12011-06-24 17:20:50 +0000181 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
199bool SkOSWindow::attachGL()
200{
201 bool success = true;
202 return success;
203}
204
205void SkOSWindow::detachGL() {
206}
207
208void SkOSWindow::presentGL() {
209 glFlush();
210}