Results 1 to 5 of 5

Thread: OS/X how to get physical display handle

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: OS/X how to get physical display handle

    I'm not sure if you can do this solely with qt, but have you looked into what CVDisplayLinkCreateWithActiveCGDisplays&friends can do?
    It returns a display link associated with all the active display. Therefore if you alter this link( gamma, or whatever), you alter all the displays.

    Here are the links too:
    http://developer.apple.com/documenta...tiveCGDisplays
    Some samples:
    http://developer.apple.com/documenta...section_2.html

    Regards

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    8
    Thanked 541 Times in 521 Posts

    Default Re: OS/X how to get physical display handle

    Oh, and of course, this is how you get the active display list and their respective IDs:
    http://developer.apple.com/documenta...0-CH202-251664

    Each physical display has an unique ID associated with it( by Quartz I think ). So if you get these, then you can get thei CGDirectDisplayIDs.

    Actually, I think it is pretty clear:
    CGGetActiveDisplayList
    Provides a list of displays that are active (or drawable).
    CGDisplayErr CGGetActiveDisplayList (
    CGDisplayCount maxDisplays,
    CGDirectDisplayID * displays,
    CGDisplayCount * displayCount
    );
    Parameters
    maxDisplays
    The size of the displays array. This value determines the maximum number of displays that can be returned.
    displays
    A pointer to storage provided by the caller for an array of display IDs. On return, this storage contains a list of active displays.
    displayCount
    A pointer to a CGDisplayCount variable provided by the caller. On return, the variable contains the actual number of displays returned in the displays array. If displays is NULL, this variable contains the total number of active displays.
    Return Value
    A result code. See “Quartz Display Services Result Codes”.
    Discussion
    The first entry in the list of active displays is the main display. In case of mirroring, the first entry is the largest drawable display or, if all are the same size, the display with the greatest pixel depth.
    Availability
    • Available in Mac OS X version 10.0 and later.
    Declared In
    CGDirectDisplay.h
    Regards

  3. #3
    Join Date
    Mar 2006
    Posts
    74
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    1

    Default Re: OS/X how to get physical display handle

    I found one source that says the following about OS/X:

    "In Qt 4, every widget is an HIView, so you calling winId() will
    return you the HIViewRef, you can then use Carbon functions like HIViewGetWindow() to get a WindowPtr.

    In Qt 3, you can get a WindowPtr by calling handle() on the top-level widget."

    But looking at the Qt3 docs I can't find handle() anywhere. So I don't trust this source. If it were correct once I had a WindowPtr I could call GetWindowBounds to get the coordinates for the window and then a call to either CGGetDisplaysWithPoint or CGGetDisplaysWithRect using the window coordinates should get the correct CGDirectDisplayID.

    This is frustrating since I found it fairly easy to find OK docs about this, meaning how to map either winId() or screenNumber() to get the native display handle, for both Windows and X11 and the complete absence of any information on how this should be programmed on OS/X is frustrating. In addition, I don't have a machine I can test any of this on so I have to work with other programmers who have access to an OS/X machine. If I had an OS/X machine I could play around with these things and figure out how to make it work. I would like to be able to say to the OS/X programmer "Look here and here ... for some information about how this can be handled." But what I have is not enough that I am willing to bother them with this at this point.

    I have a few more clues now about how this might be made to work. Your information was helpful. Maybe someone else here will see this and either confirm that the above is on the right track or that it is off base.

  4. #4
    Join Date
    Mar 2006
    Posts
    74
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows
    Thanks
    1

    Default Re: OS/X how to get physical display handle

    For those interested in how this issue is solved I have this working. So I will post some code snippets.

    The header file looks like this:

    Qt Code:
    1. typedef double ramp_type;
    2.  
    3. #ifdef __WIN32__
    4. #include <windows.h>
    5. typedef unsigned short ramp_type_private;
    6. typedef HDC displayHandle;
    7. #elif defined (__APPLE__)
    8. #ifndef DEBUG
    9. #define DEBUG 0
    10. #endif
    11. #include <Carbon/Carbon.h>
    12. #include <CoreServices/CoreServices.h>
    13. #include <IOKit/Graphics/IOGraphicsLib.h>
    14. typedef CGGammaValue ramp_type_private;
    15. typedef CGDirectDisplayID displayHandle;
    16. #elif defined (UNIX)
    17. typedef unsigned short ramp_type_private;
    18. typedef int displayHandle;
    19. #else
    20. #error "no typedef for ramp_type_private and displayHandle are available for your platform"
    21. #endif
    22.  
    23. class gamma_ramp
    24. {
    25. public:
    26. int size;
    27. ramp_type *red, *green, *blue;
    28.  
    29. gamma_ramp(int screen, int leftIn, int topIn); // screen is ignored on OS/X and Windows
    30. // leftIn and topIn are ignored on X11
    31.  
    32. ~gamma_ramp();
    33. void getGammaRamp(); // returns size
    34. void setGammaRamp();
    35.  
    36. void setLinearGammaRamp();
    37.  
    38. private:
    39. int getGammaRampSize();
    40. void convertPrivShort2ramp_type();
    41. void convert_ramp_type2short();
    42.  
    43. ramp_type_private* ramp_buffer;
    44. int screen, left, top;
    45. displayHandle display;
    46. };
    To copy to clipboard, switch view to plain text mode 

    The main thing of interest is how the code gets the handle to the display device so that it manipulates the correct video card gamma table.

    For OS/X it looks like this:

    Qt Code:
    1. CGPoint point;
    2.  
    3. CGDirectDisplayID getDisplay()
    4. {
    5. const int maxDisplays = 64; // 64 should be enough for any system
    6. CGDisplayErr displayStatus;
    7. CGDisplayCount displayCount; // Total number of display IDs
    8. CGDirectDisplayID displayIDs[maxDisplays]; // Array of display IDs
    9.  
    10. displayStatus = CGGetDisplaysWithPoint ( point, maxDisplays, displayIDs, &displayCount);
    11. if (displayStatus != kCGErrorSuccess || displayCount!= 1)
    12. {
    13. printf("CGGetDisplaysWithPoint returned error or the wrong number of displays\n");
    14. return NULL;
    15. }
    16. else
    17. return displayIDs[0];
    18. }
    19.  
    20. gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
    21. {
    22. // screen = Screen;
    23. left = leftIn;
    24. top = topIn;
    25. point.y = float(top);
    26. point.x = float(left);
    27.  
    28. display = getDisplay();
    29. screen = 0;
    30. if (display == NULL)
    31. {
    32. ramp_buffer = 0;
    33. red = 0;
    34. green = 0;
    35. blue = 0;
    36. printf("gamma_ramp::gamma_ramp - error failed to get display handle");
    37. }
    38. else // do what needs to be done to set up the gamma tables
    39. }
    To copy to clipboard, switch view to plain text mode 

    On Windows it looks like this:

    Qt Code:
    1. static int numMatchingDisplays;
    2. static RECT clipRegion;
    3.  
    4. static BOOL CALLBACK MonitorEnumProc(
    5. HMONITOR hMonitor, // handle to display monitor
    6. HDC hdcMonitor, // NULL, because EnumDisplayMonitors hdc is NULL
    7. LPRECT displayCoordintes, // Virtual screen coordinates of this monitor
    8. LPARAM name // Context data used to pass back display name in our case
    9. )
    10. {
    11. MONITORINFOEX pmi;
    12.  
    13. if (displayCoordintes -> left <= clipRegion.left &&
    14. displayCoordintes -> bottom >= clipRegion.top &&
    15. displayCoordintes -> right >= clipRegion.left &&
    16. displayCoordintes -> top <= clipRegion.top)
    17. {
    18. // display contains the widget
    19. pmi.cbSize = sizeof(MONITORINFOEX);
    20. if (GetMonitorInfo(hMonitor, (MONITORINFO *)&pmi) == 0)
    21. {
    22. printf("MonitorEnumProc - get_displays failed GetMonitorInfo\n");
    23. return FALSE;
    24. }
    25. else // it worked we have the device we want
    26. {
    27. numMatchingDisplays++;
    28. return TRUE;
    29. }
    30. }
    31. else // this is OK as the device is not the one we want
    32. {
    33. return TRUE;
    34. }
    35. }
    36.  
    37. HDC getDisplay()
    38. {
    39.  
    40. BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
    41. char name[256];
    42. HDC dispHand;
    43.  
    44. pEnumDisplayDevices = (BOOL (WINAPI*)(PVOID,DWORD,PVOID,DWORD)) GetProcAddress(LoadLibrary("USER32"), "EnumDisplayDevicesA");
    45.  
    46. numMatchingDisplays = 0;
    47. if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&name) == 0)
    48. {
    49. printf("getDisplay - EnumDisplayMonitors failed\n");
    50. return NULL;
    51. }
    52.  
    53. if (numMatchingDisplays != 1 ) // there is a problem we should only have one
    54. {
    55. printf("getDisplay - wrong number of displays %i", numMatchingDisplays);
    56. return NULL;
    57. }
    58. else
    59. {
    60. if ((dispHand = CreateDC(name, name, NULL, NULL)) == NULL)
    61. {
    62. printf("getDisplay - CreateDC failed");
    63. return NULL;
    64. }
    65. else
    66. {
    67. return dispHand;
    68. }
    69. }
    70. }
    71.  
    72.  
    73. gamma_ramp::gamma_ramp(int Screen, int leftIn, int topIn)
    74. {
    75. screen = Screen;
    76. left = leftIn;
    77. top = topIn;
    78. clipRegion.left = left;
    79. clipRegion.top = top;
    80.  
    81. display = getDisplay();
    82. if (display == NULL)
    83. {
    84. ramp_buffer = 0;
    85. red = 0;
    86. green = 0;
    87. blue = 0;
    88. printf("gamma_ramp::gamma_ramp - error failed to get display handle");
    89. }
    90. else // set up the gamma tables
    91. }
    To copy to clipboard, switch view to plain text mode 

    On X11 I just pass in the desktop -> screenNumber since X11 uses this to allow access to the video card gamma table. For for OS/X and Windows I needed to pass in a set of coordinates that were located on the display I wanted to manipulate the gamma table for and then parse through a list of devices to find the one that contained these coordinates and then get it's handle to use internal in the gamma_ramp class.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.