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