Page 1 of 2

DesktopDepth with OpenScreen

Posted: Sun Jul 07, 2013 11:57 pm
by Danilo
Hello,

my name is Danilo and i am new to MacOSX programming. Found a behavior that
usually worked correctly on Windows OS:

Code: Select all

EnableExplicit

ExamineDesktops()
Define.i dw = DesktopWidth(0)
Define.i dh = DesktopHeight(0)
Define.i dd = DesktopDepth(0)

Debug dw
Debug dh
Debug dd

;dd = 32

If InitSprite()=0 Or InitKeyboard()=0 Or OpenScreen(dw, dh, dd, "TestScreen")=0
  MessageRequester("ERROR","Failed To 'InitSprite/InitKeyboard/OpenScreen'")
  End
EndIf

Repeat
   ClearScreen(RGB(255,255,0))
      
   FlipBuffers()
   ExamineKeyboard()
   
   If KeyboardPushed(#PB_Key_Escape) : End : EndIf
ForEver
DesktopDepth() returns 24 here, and OpenScreen() fails with depth of 24 bits.
So I have to use the line "dd = 32" explicitly.

Is this normal on MacOSX? Or is DesktopDepth() wrong and should return 32, too?

This works:

Code: Select all

EnableExplicit

ExamineDesktops()
Define.i dw = DesktopWidth(0)
Define.i dh = DesktopHeight(0)

#title = "ScreenTest"

Debug dw
Debug dh

If InitSprite()=0 Or InitKeyboard()=0
  MessageRequester("ERROR","Failed To 'InitSprite/InitKeyboard'")
  End
EndIf

If OpenScreen(dw,dh,32,#title)=0
  If OpenScreen(dw,dh,24,#title)=0
    If OpenScreen(dw,dh,16,#title)=0
      MessageRequester("ERROR","'OpenScreen' failed")
      End
:EndIf:EndIf:EndIf

Repeat
   ClearScreen(RGB(255,255,0))
      
   FlipBuffers()
   ExamineKeyboard()
   
   If KeyboardPushed(#PB_Key_Escape) : End : EndIf
ForEver
PureBasic 5.20 beta5 x86

Mac Mini Server, i7 QuadCore 2.6GHz, 16GB mem, Intel HD4000 graphics, OS X 10.8.4

Re: DesktopDepth with OpenScreen

Posted: Mon Jul 08, 2013 4:19 am
by J. Baker
I haven't looked into this in depth but my guess is that Apple has it so it only returns the number of actual colors (24 bit), as the other 8 bits would be for alpha information per image. I guess it should report 32 bit though as that is what it's capable of displaying.

Secondly, there is no 24 bit screen mode as it's covered by 32 bit. 16 bit also works.

Welcome to OS X! ;)

Re: DesktopDepth with OpenScreen

Posted: Mon Jul 08, 2013 9:55 am
by Danilo
J. Baker wrote:Welcome to OS X! ;)
Thx! ;)

My Screen Modes:

Code: Select all

1920x1080 - Depth:  32 @ 60 Hz
1920x1080 - Depth:  32 @ 50 Hz
1600x1200 - Depth:  32 @ 60 Hz
1344x1008 - Depth:  32 @ 60 Hz
1280x1024 - Depth:  32 @ 75 Hz
1280x 960 - Depth:  32 @ 60 Hz
1280x1024 - Depth:  32 @ 60 Hz
1280x 720 - Depth:  32 @ 60 Hz
1280x 720 - Depth:  32 @ 50 Hz
1152x 870 - Depth:  32 @ 75 Hz
1024x 768 - Depth:  32 @ 75 Hz
1024x 768 - Depth:  32 @ 70 Hz
1024x 768 - Depth:  32 @ 60 Hz
 832x 624 - Depth:  32 @ 75 Hz
 800x 600 - Depth:  32 @ 75 Hz
 800x 600 - Depth:  32 @ 72 Hz
 800x 600 - Depth:  32 @ 60 Hz
 800x 600 - Depth:  32 @ 56 Hz
 720x 576 - Depth:  32 @ 50 Hz
 720x 480 - Depth:  32 @ 60 Hz
 640x 480 - Depth:  32 @ 75 Hz
 640x 480 - Depth:  32 @ 73 Hz
 640x 480 - Depth:  32 @ 67 Hz
 640x 480 - Depth:  32 @ 60 Hz
(no 16bit screen modes available?)

Code:

Code: Select all

Structure ScreenModeInfo
  width.i
  height.i
  depth.i
  hz.i
EndStructure

NewList modes.ScreenModeInfo()

If InitSprite()
  If ExamineScreenModes()
      While NextScreenMode()
        If AddElement(modes())
          modes()\width  = ScreenModeWidth()
          modes()\height = ScreenModeHeight()
          modes()\depth  = ScreenModeDepth()
          modes()\hz     = ScreenModeRefreshRate()
        EndIf
      Wend
  EndIf
  
  SortStructuredList( modes(), #PB_Sort_Descending, OffsetOf(ScreenModeInfo\width), #PB_Integer)
  
  ForEach modes()
    Debug RSet(Str(modes()\width),4) + "x" + RSet(Str(modes()\height),4) + " - Depth: " + RSet(Str(modes()\depth),3) + " @ " + Str(modes()\hz) + " Hz"
  Next
  
EndIf
Maybe DesktopDepth() should return 32, too?

Re: DesktopDepth with OpenScreen

Posted: Mon Jul 08, 2013 10:11 am
by wilbert
My screen modes list returns 16 bit also

Code: Select all

1920x1080 - Depth:  16 @ 0 Hz
1920x1080 - Depth:  32 @ 0 Hz
1680x1050 - Depth:  16 @ 0 Hz
1680x1050 - Depth:  32 @ 0 Hz
1600x 900 - Depth:  16 @ 0 Hz
1600x 900 - Depth:  32 @ 0 Hz
1344x 756 - Depth:  16 @ 0 Hz
1344x 756 - Depth:  32 @ 0 Hz
1280x1024 - Depth:  16 @ 0 Hz
1280x1024 - Depth:  32 @ 0 Hz
1280x 720 - Depth:  16 @ 0 Hz
1280x 720 - Depth:  32 @ 0 Hz
1024x 768 - Depth:  16 @ 0 Hz
1024x 768 - Depth:  32 @ 0 Hz
 960x 540 - Depth:  16 @ 0 Hz
 960x 540 - Depth:  32 @ 0 Hz
 840x 525 - Depth:  16 @ 0 Hz
 840x 525 - Depth:  32 @ 0 Hz
 800x 600 - Depth:  16 @ 0 Hz
 800x 600 - Depth:  32 @ 0 Hz
 800x 450 - Depth:  16 @ 0 Hz
 800x 450 - Depth:  32 @ 0 Hz
 640x 480 - Depth:  16 @ 0 Hz
 640x 480 - Depth:  32 @ 0 Hz
Getting information from NSScreen returns 8, 24 and 128 on my iMac

Code: Select all

ImportC ""
  NSBitsPerPixelFromDepth(depth)
EndImport

*SupportedWindowDepths.Integer = CocoaMessage(0, CocoaMessage(0, 0, "NSScreen mainScreen"), "supportedWindowDepths")

While *SupportedWindowDepths\i
  Debug NSBitsPerPixelFromDepth(*SupportedWindowDepths\i)
  *SupportedWindowDepths + SizeOf(Integer)
Wend

Re: DesktopDepth with OpenScreen

Posted: Mon Jul 08, 2013 10:17 am
by Danilo
wilbert wrote:Getting information from NSScreen returns 8, 24 and 128 on my iMac

Code: Select all

ImportC ""
  NSBitsPerPixelFromDepth(depth)
EndImport

*SupportedWindowDepths.Integer = CocoaMessage(0, CocoaMessage(0, 0, "NSScreen mainScreen"), "supportedWindowDepths")

While *SupportedWindowDepths\i
  Debug NSBitsPerPixelFromDepth(*SupportedWindowDepths\i)
  *SupportedWindowDepths + SizeOf(Integer)
Wend
Thx wilbert!

My Output:

Code: Select all

8
12
24
64
128
Now 32bit screen modes are missing entirely? And 64bit and 128bit screen modes? Doesn't look correct to me.

All your screen modes return 0 Hz. Can't you run @ 50Hz or 60Hz?

Re: DesktopDepth with OpenScreen

Posted: Mon Jul 08, 2013 10:38 am
by wilbert
Danilo wrote:All your screen modes return 0 Hz. Can't you run @ 50Hz or 60Hz?
The PureBasic manual mentions that the returned frequency for DesktopFrequency() can be 0.
I think my iMac always uses the same refresh rate. It might be different for an external monitor.
128 is probably a floating point mode that PB doesn't support anyway.

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 09, 2013 5:30 am
by Danilo
Had the Mac connected to the monitor by using the Apple HDMI-DVI-Adapter.
Now the Mini-DisplayPort > DisplayPort cable arrived and the screen modes are different:

Code: Select all

2560x1440 - Depth:  32 @ 60 Hz
2048x1152 - Depth:  32 @ 60 Hz
1920x1440 - Depth:  32 @ 60 Hz
1600x1200 - Depth:  32 @ 60 Hz
1600x 900 - Depth:  32 @ 60 Hz
1344x1008 - Depth:  32 @ 60 Hz
1344x 756 - Depth:  32 @ 60 Hz
1280x1024 - Depth:  32 @ 75 Hz
1280x 960 - Depth:  32 @ 60 Hz
1280x1024 - Depth:  32 @ 60 Hz
1280x 720 - Depth:  32 @ 60 Hz
1152x 870 - Depth:  32 @ 75 Hz
1024x 768 - Depth:  32 @ 75 Hz
1024x 768 - Depth:  32 @ 70 Hz
1024x 768 - Depth:  32 @ 60 Hz
1024x 576 - Depth:  32 @ 60 Hz
 832x 624 - Depth:  32 @ 75 Hz
 800x 600 - Depth:  32 @ 75 Hz
 800x 600 - Depth:  32 @ 72 Hz
 800x 600 - Depth:  32 @ 60 Hz
 800x 600 - Depth:  32 @ 56 Hz
 640x 480 - Depth:  32 @ 75 Hz
 640x 480 - Depth:  32 @ 73 Hz
 640x 480 - Depth:  32 @ 67 Hz
 640x 480 - Depth:  32 @ 60 Hz
My Desktop is "2560x1440x32 @ 60 Hz", but DesktopDepth() still returns 24. I think that's wrong, looks like a bug to me.

Re: DesktopDepth with OpenScreen

Posted: Wed Jul 10, 2013 10:04 pm
by Andre
Danilo is using a Mac, and PB for MacOS.... cool! :mrgreen:

And welcome in the MacOS sub-forums! :D

Do you also develop Multi-OS applications now? (like we do with GeoWorld for Windows and MacOS...)

Re: DesktopDepth with OpenScreen

Posted: Thu Jul 11, 2013 5:56 am
by Danilo
Andre wrote:Danilo is using a Mac, and PB for MacOS.... cool! :mrgreen:

And welcome in the MacOS sub-forums! :D
Thx!
Andre wrote:Do you also develop Multi-OS applications now? (like we do with GeoWorld for Windows and MacOS...)
That's the plan, but first I have to learn some Mac OS X APIs. Just got the Mac Mini Server and 3 new 27" displays 2 weeks ago.

After 2 weeks I like it so much that I just ordered the 17 best developer books I could find about Mac OS X programming yesterday.
Objective-C, Cocoa, Quartz, Core Audio, Core Animation, Core Data, AppleScript, game programming with Cocoa and OpenGL on Mac,
Unix side of Mac OS X, and Mac OS X and iOS Internals.

The best thing is, I can use much of the software I bought for Windows on the Mac now, because many are cross-platform.
Ableton Live, Propellerheads Reason, Poser, Maxon Cinema4D, PureBasic, ...
Also, Apple's developer environment XCode is free, for coding Mac OS X and iOS (iPhone, iPad) stuff. There is also Lightweight IDE
for development in Pascal, Object Pascal, Objective Pascal, C, C++, Objective C, CUDA, Java, Ada and shellscripts.

Just takes some time to learn all the new stuff. I think it will be much better in round about 2-3 month, after reading some books
and playing with the new APIs. ;)

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 7:10 am
by Danilo
Found the correct information ( DesktopDepth() is wrong here, returns 24 instead 32 ):

Code: Select all

ImportC ""
    CGMainDisplayID()

    CGDisplayPixelsWide(display)
    CGDisplayPixelsHigh(display)
    CGDisplayBitsPerPixel( display ) ;  (Available in OS X v10.0 through OS X v10.6. Use CGDisplayModeCopyPixelEncoding instead.)
    
    CGDisplayRelease( display )
EndImport

mainScreen = CGMainDisplayID()
    Debug CGDisplayPixelsWide( mainScreen )
    Debug CGDisplayPixelsHigh( mainScreen )
    Debug CGDisplayBitsPerPixel( mainScreen )
CGDisplayRelease( mainScreen )
Output:

Code: Select all

2560
1440
32
...but CGDisplayBitsPerPixel() is deprecated and I don't know how to use CGDisplayModeCopyPixelEncoding(), yet.

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 7:57 am
by wilbert
@Danilo, here's an example of CGDisplayModeCopyPixelEncoding(). The information it returns is very different.
Since a CFString and NSString are interchangeable, I used some Cocoa to convert the string CGDisplayModeCopyPixelEncoding() returns to a PureBasic string.
It's a bit easier compared to using the CFString functions.

Code: Select all

#IO1BitIndexedPixels = "P"
#IO2BitIndexedPixels = "PP"
#IO4BitIndexedPixels = "PPPP"
#IO8BitIndexedPixels = "PPPPPPPP"
#IO16BitDirectPixels = "-RRRRRGGGGGBBBBB"
#IO32BitDirectPixels = "--------RRRRRRRRGGGGGGGGBBBBBBBB"
#kIO30BitDirectPixels = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB"
#kIO64BitDirectPixels = "-16R16G16B16"
#kIO16BitFloatPixels = "-16FR16FG16FB16"
#kIO32BitFloatPixels = "-32FR32FG32FB32"

Import ""
  CFRelease(cf)
  CGDisplayCopyDisplayMode(display)
  CGDisplayIsBuiltin(display)
  CGDisplayModeCopyPixelEncoding(mode)
  CGDisplayModeRelease(mode)
  CGDisplayPixelsHigh(display)
  CGDisplayPixelsWide(display)
  CGMainDisplayID()
EndImport

Dim BooleanString.s(1)
BooleanString(0) = "No"
BooleanString(1) = "Yes"

mainScreen = CGMainDisplayID()
displayMode = CGDisplayCopyDisplayMode( mainScreen )

pixelEncoding = CGDisplayModeCopyPixelEncoding( displayMode )
pixelEncodingString.s = PeekS(CocoaMessage(0, pixelEncoding, "UTF8String"), -1, #PB_UTF8)
CFRelease( pixelEncoding )

Debug CGDisplayPixelsWide( mainScreen )
Debug CGDisplayPixelsHigh( mainScreen )
Debug pixelEncodingString
Debug "Builtin display : " + BooleanString(CGDisplayIsBuiltin( display ))

CGDisplayModeRelease( displayMode )

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 8:58 am
by Fred
From what I understand from this: http://lukassen.wordpress.com/2010/01/1 ... prication/ there is no native 24bit mode on OSX anyway, so we can safely assume than if we get 24bit from NSBitsPerPixelFromDepth() it's a 32bit mode, right ? If yes, I will do the patch so it returns the correct value.

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 9:16 am
by wilbert
Fred wrote:so we can safely assume than if we get 24bit from NSBitsPerPixelFromDepth() it's a 32bit mode, right ?
I believe you are right Fred.

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 10:18 am
by Fred
Changed.

Re: DesktopDepth with OpenScreen

Posted: Tue Jul 16, 2013 4:19 pm
by Danilo
wilbert wrote:@Danilo, here's an example of CGDisplayModeCopyPixelEncoding(). The information it returns is very different.
Since a CFString and NSString are interchangeable, I used some Cocoa to convert the string CGDisplayModeCopyPixelEncoding() returns to a PureBasic string.
It's a bit easier compared to using the CFString functions.
Many thanks for the example code, wilbert! Got a weird stack corruption with PB x86 (x64 worked out of the box)...
but after changing "Import" to "ImportC" everything works fine. ;) Thanks again!