PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/BasicMediaPlayer/Mac/BasicMediaPlayerPluginMac.mm

https://github.com/GordonSmith/FireBreath
Objective C++ | 332 lines | 228 code | 51 blank | 53 comment | 14 complexity | 3e928e67c389cb9b1c230e7524a444bc MD5 | raw file
  1. /**********************************************************\
  2. Original Author: Richard Bateman and Georg Fritzsche
  3. Created: December 3, 2009
  4. License: Dual license model; choose one of two:
  5. New BSD License
  6. http://www.opensource.org/licenses/bsd-license.php
  7. - or -
  8. GNU Lesser General Public License, version 2.1
  9. http://www.gnu.org/licenses/lgpl-2.1.html
  10. Copyright 2009 PacketPass Inc, Georg Fritzsche,
  11. Firebreath development team
  12. \**********************************************************/
  13. #include <boost/type_traits.hpp>
  14. #import <AppKit/AppKit.h>
  15. #include "Mac/PluginWindowMac.h"
  16. #include "Mac/PluginWindowMacQD.h"
  17. #include "Mac/PluginWindowMacCG.h"
  18. #include "Mac/PluginWindowMacCA.h"
  19. #include "Mac/PluginWindowMacICA.h"
  20. #include "BasicMediaPlayerPluginMac.h"
  21. @interface MyCAOpenGLLayer : CAOpenGLLayer {
  22. GLfloat m_angle;
  23. }
  24. @end
  25. @implementation MyCAOpenGLLayer
  26. - (id) init {
  27. if ([super init]) {
  28. m_angle = 0;
  29. }
  30. return self;
  31. }
  32. - (void)drawInCGLContext:(CGLContextObj)ctx pixelFormat:(CGLPixelFormatObj)pf forLayerTime:(CFTimeInterval)t displayTime:(const CVTimeStamp *)ts {
  33. m_angle += 1;
  34. GLsizei width = CGRectGetWidth([self bounds]), height = CGRectGetHeight([self bounds]);
  35. GLfloat halfWidth = width / 2, halfHeight = height / 2;
  36. glViewport(0, 0, width, height);
  37. glMatrixMode(GL_PROJECTION);
  38. glLoadIdentity();
  39. glScalef(1.0f, -1.0f, 1.0f);
  40. glOrtho(0, width, 0, height, -1.0, 1.0);
  41. glMatrixMode(GL_MODELVIEW);
  42. glLoadIdentity();
  43. glRotatef(m_angle, 0.0, 0.0, 1.0);
  44. // Clear the stage.
  45. glClearColor(0.0, 0.0, 0.0, 0.0);
  46. glClear(GL_COLOR_BUFFER_BIT);
  47. // Draw UL Quadrant 25% Red
  48. glBegin(GL_QUADS);
  49. glColor4f(1.0, 0.0, 0.0, 0.25);
  50. glVertex3f(0, 0, -1.0f);
  51. glVertex3f(halfWidth, 0, -1.0f);
  52. glVertex3f(halfWidth, halfHeight, -1.0f);
  53. glVertex3f(0, halfHeight, -1.0f);
  54. glEnd();
  55. // Draw UR Quadrant 50% Green
  56. glBegin(GL_QUADS);
  57. glColor4f(0.0, 1.0, 0.0, 0.5);
  58. glVertex3f(halfWidth, 0, -1.0f);
  59. glVertex3f(width, 0, -1.0f);
  60. glVertex3f(width, halfHeight, -1.0f);
  61. glVertex3f(halfWidth, halfHeight, -1.0f);
  62. glEnd();
  63. // Draw LR Quadrant 75% Blue
  64. glBegin(GL_QUADS);
  65. glColor4f(0.0, 0.0, 1.0, 0.75);
  66. glVertex3f(halfWidth, halfHeight, -1.0f);
  67. glVertex3f(width, halfHeight, -1.0f);
  68. glVertex3f(width, height, -1.0f);
  69. glVertex3f(halfWidth, height, -1.0f);
  70. glEnd();
  71. // Draw Center Quadrant 100% Magenta
  72. glBegin(GL_QUADS);
  73. glColor4f(1.0, 0.0, 1.0, 1.0);
  74. glVertex3f(width / 4, height / 4, -1.0f);
  75. glVertex3f(3 * width / 4, height / 4, -1.0f);
  76. glVertex3f(3 * width / 4, 3 * height / 4, -1.0f);
  77. glVertex3f(width / 4, 3 * height / 4, -1.0f);
  78. glEnd();
  79. [super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts];
  80. }
  81. @end
  82. BasicMediaPlayerPluginMac::BasicMediaPlayerPluginMac() : m_layer(NULL) {}
  83. BasicMediaPlayerPluginMac::~BasicMediaPlayerPluginMac()
  84. {
  85. if (m_layer) {
  86. [(CALayer*)m_layer removeFromSuperlayer];
  87. [(CALayer*)m_layer release];
  88. m_layer = NULL;
  89. }
  90. }
  91. bool BasicMediaPlayerPluginMac::onWindowAttached(FB::AttachedEvent* evt, FB::PluginWindowMac* wnd)
  92. {
  93. if (FB::PluginWindowMac::DrawingModelCoreAnimation == wnd->getDrawingModel() || FB::PluginWindowMac::DrawingModelInvalidatingCoreAnimation == wnd->getDrawingModel()) {
  94. // Setup CAOpenGL drawing.
  95. MyCAOpenGLLayer* layer = [MyCAOpenGLLayer new];
  96. layer.asynchronous = (FB::PluginWindowMac::DrawingModelInvalidatingCoreAnimation == wnd->getDrawingModel()) ? NO : YES;
  97. layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
  98. layer.needsDisplayOnBoundsChange = YES;
  99. m_layer = layer;
  100. if (FB::PluginWindowMac::DrawingModelInvalidatingCoreAnimation == wnd->getDrawingModel())
  101. wnd->StartAutoInvalidate(1.0/30.0);
  102. [(CALayer*) wnd->getDrawingPrimitive() addSublayer:layer];
  103. // Draw Label
  104. CATextLayer* txtlayer = [CATextLayer layer];
  105. txtlayer.string = (FB::PluginWindowMac::DrawingModelInvalidatingCoreAnimation == wnd->getDrawingModel()) ? @"CoreAnimation (Invalidating)" : @"CoreAnimation";
  106. txtlayer.fontSize = 14;
  107. txtlayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
  108. txtlayer.needsDisplayOnBoundsChange = YES;
  109. [(CALayer*) wnd->getDrawingPrimitive() addSublayer:txtlayer];
  110. }
  111. return BasicMediaPlayerPlugin::onWindowAttached(evt,wnd);
  112. }
  113. bool BasicMediaPlayerPluginMac::onWindowDetached(FB::DetachedEvent* evt, FB::PluginWindowMac* wnd)
  114. {
  115. return BasicMediaPlayerPlugin::onWindowDetached(evt,wnd);
  116. }
  117. #ifndef NP_NO_QUICKDRAW
  118. bool BasicMediaPlayerPluginMac::onDrawQD(FB::QuickDrawDraw *evt, FB::PluginWindowMacQD* wnd)
  119. {
  120. FB::Rect bounds(evt->bounds);
  121. FB::Rect clip(evt->clip);
  122. CGrafPtr port(evt->port);
  123. #if 0
  124. // Wrap a QuickDraw port with a CoreGraphics context.
  125. CGContextRef cgContext = NULL;
  126. OSStatus status = QDBeginCGContext(port, &cgContext);
  127. printf("%s() QDBeginCGContext=%ld\n", __func__, status);
  128. if (noErr == status) {
  129. status = SyncCGContextOriginWithPort(cgContext, port);
  130. printf("%s() SyncCGContextOriginWithPort=%ld\n", __func__, status);
  131. // Flip the coordinate space.
  132. CGContextTranslateCTM(cgContext, 0.0, bounds.bottom - bounds.top);
  133. CGContextScaleCTM(cgContext, 1.0, -1.0);
  134. DrawCoreGraphics(cgContext, bounds, clip);
  135. //CGContextFlush(cgContext);
  136. CGContextSynchronize(cgContext);
  137. status = QDEndCGContext(port, &cgContext);
  138. printf("%s() QDEndCGContext=%ld\n", __func__, status);
  139. //QDFlushPortBuffer(port, NULL);
  140. }
  141. else
  142. #endif
  143. {
  144. short width = bounds.right - bounds.left, height = bounds.bottom - bounds.top;
  145. short halfWidth = width / 2, halfHeight = height / 2;
  146. CGrafPtr cur_port = NULL;
  147. bool swappedport = QDSwapPort(port, &cur_port);
  148. ::Rect portBounds; (void) GetPortBounds(port, &portBounds);
  149. ::Rect clipRect = { clip.top, clip.left, clip.bottom, clip.right};
  150. OffsetRect(&clipRect, -bounds.left, -bounds.top);
  151. ClipRect(&clipRect);
  152. // Clear the stage.
  153. RGBColor color0 = { USHRT_MAX, USHRT_MAX, USHRT_MAX };
  154. RGBBackColor(&color0); //BackColor(whiteColor);
  155. ::Rect rect0 = { 0, 0, height, width };
  156. // EraseRect(&rect0);
  157. // Draw UL Quadrant 25% Red
  158. RGBColor color1 = { USHRT_MAX, 0, 0 };
  159. RGBForeColor(&color1); //ForeColor(redColor);
  160. ::Rect rect1 = { 0, 0, halfHeight, halfWidth };
  161. PaintRect(&rect1);
  162. // Draw UR Quadrant 50% Green
  163. RGBColor color2 = { 0, USHRT_MAX, 0 };
  164. RGBForeColor(&color2); //ForeColor(greenColor);
  165. ::Rect rect2 = { 0, halfWidth, halfHeight, width };
  166. PaintRect(&rect2);
  167. // Draw LR Quadrant 75% Blue
  168. RGBColor color3 = { 0, 0, USHRT_MAX };
  169. RGBForeColor(&color3); //ForeColor(blueColor);
  170. ::Rect rect3 = { halfHeight, halfWidth, height, width };
  171. PaintRect(&rect3);
  172. // Draw Center Quadrant 100% Magenta
  173. RGBColor color4 = { USHRT_MAX, 0, USHRT_MAX };
  174. RGBForeColor(&color4); //ForeColor(magentaColor);
  175. ::Rect rect4 = { halfHeight / 2, halfWidth / 2, 3 * height / 4, 3 * width / 4 };
  176. PaintRect(&rect4);
  177. // Draw Label
  178. RGBBackColor(&color1); //BackColor(redColor);
  179. RGBForeColor(&color0); //ForeColor(whiteColor);
  180. ::Rect rect5 = { 0, 0, 14, halfWidth };
  181. const char* label = "QuickDraw";
  182. TETextBox(label, strlen(label), &rect5, teJustLeft);
  183. SetOrigin(portBounds.left, portBounds.top);
  184. if (swappedport) QDSwapPort(port, NULL);
  185. }
  186. return true; // We have handled the event
  187. }
  188. #endif
  189. bool BasicMediaPlayerPluginMac::onDrawCG(FB::CoreGraphicsDraw *evt, FB::PluginWindowMacCG*)
  190. {
  191. FB::Rect bounds(evt->bounds);
  192. //FB::Rect clip(evt->clip);
  193. CGContextRef cgContext(evt->context);
  194. #if 0
  195. // Wrap a CoreGraphics context with a NSGraphics context.
  196. NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES];
  197. if (nsContext)
  198. DrawNSGraphicsContext(nsContext, bounds, clip);
  199. else
  200. #endif
  201. {
  202. short width = bounds.right - bounds.left, height = bounds.bottom - bounds.top;
  203. short halfWidth = width / 2, halfHeight = height / 2;
  204. CGContextSaveGState(cgContext);
  205. //CGRect clipRect = { {0,0}, {clip.right - clip.left, clip.bottom - clip.top} };
  206. //CGContextClipToRect(cgContext, clipRect);
  207. CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
  208. CGContextSetFillColorSpace(cgContext, colorspace);
  209. // Flip the coordinate space.
  210. //CGContextTranslateCTM(cgContext, 0.0, height);
  211. //CGContextScaleCTM(cgContext, 1.0, -1.0);
  212. // Clear the stage.
  213. //CGRect rect0 = { {0,0}, {width, height} };
  214. //CGContextClearRect(cgContext, rect0);
  215. // Draw UL Quadrant 25% Red
  216. CGFloat color1[] = { 1.0, 0.0, 0.0, 0.25 };
  217. CGContextSetFillColor(cgContext, color1);
  218. CGRect rect1 = { {0, 0}, {halfWidth, halfHeight} };
  219. CGContextFillRect(cgContext, rect1);
  220. // Draw UR Quadrant 50% Green
  221. CGFloat color2[] = { 0.0, 1.0, 0.0, 0.50 };
  222. CGContextSetFillColor(cgContext, color2);
  223. CGRect rect2 = { {halfWidth, 0}, {halfWidth, halfHeight} };
  224. CGContextFillRect(cgContext, rect2);
  225. // Draw LR Quadrant 75% Blue
  226. CGFloat color3[] = { 0.0, 0.0, 1.0, 0.75 };
  227. CGContextSetFillColor(cgContext, color3);
  228. CGRect rect3 = { {halfWidth, halfHeight}, {halfWidth, halfHeight} };
  229. CGContextFillRect(cgContext, rect3);
  230. // Draw Center Quadrant 100% Magenta
  231. CGFloat color4[] = { 1.0, 0.0, 1.0, 1.00 };
  232. CGContextSetFillColor(cgContext, color4);
  233. CGRect rect4 = { {halfWidth / 2, halfHeight / 2}, {halfWidth, halfHeight} };
  234. CGContextFillRect(cgContext, rect4);
  235. // Draw Label
  236. const char* label = "CoreGraphics";
  237. CGContextSetStrokeColorWithColor(cgContext, CGColorGetConstantColor(kCGColorWhite));
  238. CGContextSetFillColorWithColor(cgContext, CGColorGetConstantColor(kCGColorWhite));
  239. CGContextSetTextMatrix(cgContext, CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)); // Flip the text right-side up.
  240. CGContextSelectFont(cgContext, "Geneva", 14, kCGEncodingMacRoman);
  241. CGContextShowTextAtPoint(cgContext, 0, 14, label, strlen(label));
  242. CGColorSpaceRelease(colorspace);
  243. CGContextRestoreGState(cgContext);
  244. }
  245. return true; // This is handled
  246. }
  247. void BasicMediaPlayerPluginMac::DrawNSGraphicsContext(void *context, const FB::Rect& bounds, const FB::Rect& clip) {
  248. short width = bounds.right - bounds.left, height = bounds.bottom - bounds.top;
  249. short halfWidth = width / 2, halfHeight = height / 2;
  250. NSGraphicsContext *nsContext = (NSGraphicsContext *) context;
  251. NSGraphicsContext *oldContext = [NSGraphicsContext currentContext];
  252. [NSGraphicsContext setCurrentContext:nsContext];
  253. [nsContext saveGraphicsState];
  254. // Clear the stage.
  255. [[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:0.0 alpha:0.00] set];
  256. NSRect rect0 = NSMakeRect(0, 0, width, height);
  257. [NSBezierPath fillRect:rect0];
  258. // Draw UL Quadrant 25% Red
  259. [[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.25] set];
  260. NSRect rect1 = NSMakeRect(0, 0, halfWidth, halfHeight);
  261. [NSBezierPath fillRect:rect1];
  262. // Draw UR Quadrant 50% Green
  263. [[NSColor colorWithCalibratedRed:0.0 green:1.0 blue:0.0 alpha:0.50] set];
  264. NSRect rect2 = NSMakeRect(halfWidth, 0, halfWidth, halfHeight);
  265. [NSBezierPath fillRect:rect2];
  266. // Draw LR Quadrant 75% Blue
  267. [[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:0.75] set];
  268. NSRect rect3 = NSMakeRect(halfWidth, halfHeight, halfWidth, halfHeight);
  269. [NSBezierPath fillRect:rect3];
  270. // Draw Center Quadrant 100% Magenta
  271. [[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:1.0 alpha:1.00] set];
  272. NSRect rect4 = NSMakeRect(halfWidth / 2, halfHeight / 2, halfWidth, halfHeight);
  273. [NSBezierPath fillRect:rect4];
  274. // Draw Label
  275. NSString *label = @"NSGraphicsContext";
  276. [label drawInRect:rect1 withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Geneva" size:14], NSFontAttributeName, [NSColor whiteColor], NSForegroundColorAttributeName, NULL]];
  277. [nsContext restoreGraphicsState];
  278. [NSGraphicsContext setCurrentContext:oldContext];
  279. }