++ (id)imageWithWarningIcon
+{
+ static NSImage * imageWithWarningIcon = nil;
+ if( !imageWithWarningIcon )
+ {
+ imageWithWarningIcon = [[[self class] imageWithSystemName:'caut'] retain];
+ }
+ return imageWithWarningIcon;
+}
+
++ (id)imageWithErrorIcon
+{
+ static NSImage * imageWithErrorIcon = nil;
+ if( !imageWithErrorIcon )
+ {
+ imageWithErrorIcon = [[[self class] imageWithSystemName:'stop'] retain];
+ }
+ return imageWithErrorIcon;
+}
+
+@end
+/*****************************************************************************
+ * NSAnimation (VLCAdditions)
+ *
+ * Missing extension to NSAnimation
+ *****************************************************************************/
+
+@implementation NSAnimation (VLCAdditions)
+/* fake class attributes */
+static NSMapTable *VLCAdditions_userInfo = NULL;
+
++ (void)load
+{
+ /* init our fake object attribute */
+ VLCAdditions_userInfo = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 16);
+}
+
+- (void)dealloc
+{
+ NSMapRemove(VLCAdditions_userInfo, self);
+ [super dealloc];
+}
+
+- (void)setUserInfo: (void *)userInfo
+{
+ NSMapInsert(VLCAdditions_userInfo, self, (void*)userInfo);
+}
+
+- (void *)userInfo
+{
+ return NSMapGet(VLCAdditions_userInfo, self);
+}
+@end
+
+/*****************************************************************************
+ * NSScreen (VLCAdditions)
+ *
+ * Missing extension to NSScreen
+ *****************************************************************************/
+
+@implementation NSScreen (VLCAdditions)
+
+static NSMutableArray *blackoutWindows = NULL;
+
++ (void)load
+{
+ /* init our fake object attribute */
+ blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
+}
+
++ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
+{
+ int i;
+
+ for( i = 0; i < [[NSScreen screens] count]; i++ )
+ {
+ NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
+ if([screen displayID] == displayID)
+ return screen;
+ }
+ return nil;
+}
+
+- (BOOL)isMainScreen
+{
+ return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
+}
+
+- (BOOL)isScreen: (NSScreen*)screen
+{
+ return ([self displayID] == [screen displayID]);
+}
+
+- (CGDirectDisplayID)displayID
+{
+ return (CGDirectDisplayID)_screenNumber;
+}
+
+- (void)blackoutOtherScreens
+{
+ unsigned int i;
+
+ /* Free our previous blackout window (follow blackoutWindow alloc strategy) */
+ [blackoutWindows makeObjectsPerformSelector:@selector(close)];
+ [blackoutWindows removeAllObjects];
+
+ for(i = 0; i < [[NSScreen screens] count]; i++)
+ {
+ NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
+ VLCWindow *blackoutWindow;
+ NSRect screen_rect;
+
+ if([self isScreen: screen])
+ continue;
+
+ screen_rect = [screen frame];
+ screen_rect.origin.x = screen_rect.origin.y = 0;
+
+ /* blackoutWindow alloc strategy
+ - The NSMutableArray blackoutWindows has the blackoutWindow references
+ - blackoutOtherDisplays is responsible for alloc/releasing its Windows
+ */
+ blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered defer: NO screen: screen];
+ [blackoutWindow setBackgroundColor:[NSColor blackColor]];
+ [blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
+
+ [blackoutWindow displayIfNeeded];
+ [blackoutWindow orderFront: self animate: YES];
+
+ [blackoutWindows addObject: blackoutWindow];
+ [blackoutWindow release];
+
+ if( [screen isMainScreen ] )
+ SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+ }
+}
+
++ (void)unblackoutScreens
+{
+ unsigned int i;
+
+ for(i = 0; i < [blackoutWindows count]; i++)
+ {
+ VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
+ [blackoutWindow closeAndAnimate: YES];
+ }
+
+ SetSystemUIMode( kUIModeNormal, 0);
+}
+
+@end
+
+/*****************************************************************************
+ * VLCWindow
+ *
+ * Missing extension to NSWindow
+ *****************************************************************************/