chaos.mod/desktopext.mod can do that, and more:
Public Domain by hamZta, Suco-X, d-bug
See below:
'-- HEADER ----------------------------------------------------------------------------------------------------------------------
Rem
bbdoc: DesktopExt
about: DesktopExt dient der Komunikation zwischen BMax und dem Desktop,
ohne dabei auf MaxGUI Funktionen zurück greifen zu müssen.
End Rem
Module chaos.desktopext
ModuleInfo "Version: 1.13"
ModuleInfo "Author: hamZta, Suco-X, d-bug"
ModuleInfo "License: Public Domain"
ModuleInfo "Contact: d-bug@..."
ModuleInfo "Homepage: www.chaos-interactive.de"
ModuleInfo "History: 1.13 DesktopRatio hinzu"
ModuleInfo "History: 1.12 Macos 'identifer screen not found' bug behoben"
ModuleInfo "History: 1.11 Win32 Unterstützung mehrerer Desktops überarbeitet (danke klepto2 und Suco-X)"
ModuleInfo "History: 1.10 Unterstützung mehrerer Monitore für Win32 implementiert"
ModuleInfo "History: 1.09 Pixmap wird wieder konvertiert"
ModuleInfo "History: 1.08 Optionaler Flip und Pixmapformatierung bei DesktopPixmap implementiert"
ModuleInfo "History: 1.07 Unterstützung mehrerer Monitore für MacOS implementiert"
ModuleInfo "History: 1.06 'TPixmap not found' repariert"
ModuleInfo "History: 1.05 DesktopMouseX() bzw DesktopMouseY() für Win32"
ModuleInfo "History: 1.04 DesktopPixmap() für Win32"
ModuleInfo "History: 1.03 Dokumentation ist ab jetzt in deutsch"
ModuleInfo "History: 1.02 Scope von dbug. nach chaos. geändert"
ModuleInfo "History: 1.01 ReleaseDC eingefügt"
ModuleInfo "History: 1.00 Erster Release (16.05.2006)"
SuperStrict
Import brl.standardio
Import brl.pixmap
Import brl.linkedlist
?Win32
Import pub.win32
Private
Const SM_CXVIRTUALSCREEN:Int = 78
Const SM_CYVIRTUALSCREEN:Int = 79
Const SM_CMONITORS:Int = 80
Const SM_SAMEDISPLAYFORMAT:Int = 81
Type TDisplay
Global List:TList = New TList
Field id:Int
Field handle:Int
Field x:Int
Field y:Int
Field width:Int
Field height:Int
End Type
Type TRect
Field rLeft:Int
Field rTop:Int
Field rRight:Int
Field rBottom:Int
End Type
Extern "Win32"
Function GetSystemMetrics:Int (nIndex:Int)"Win32"
Function EnumDisplayMonitors:Int (hdc:Int, lprcClip:Byte Ptr, lpfnEnum:Byte Ptr, dwData:Byte Ptr)"Win32"
Function GetCursorPos(lpPoint:Byte Ptr)"Win32" = "GetCursorPos@4"
Function GetDIBits(hdc:Int, bitmap:Int, Start:Int, Num:Int, bits:Byte Ptr, lpbi:Byte Ptr, usage:Int)"Win32"
Function GetWindowDC(hwnd:Int)"Win32"
Function ReleaseDC(hwnd:Int, hdc:Int)"Win32"
End Extern
Function MonitorEnumProc:Byte (hMonitor:Int,hdcMonitor:Int,lprcMonitor:Byte Ptr,dwData:Int)
Local tempRect:TRect = New TRect
MemCopy(tempRect, lprcMonitor, SizeOf(tempRect))
Local display:TDisplay = New TDisplay
TDisplay.List.AddLast(display)
display.id = TDisplay.List.Count()
display.handle = hMonitor
display.x = tempRect.rLeft
display.y = tempRect.rTop
display.width = tempRect.rRight - display.x
display.height = tempRect.rBottom - display.y
Return True
End Function
EnumDisplayMonitors (Null , Null , MonitorEnumProc , Null)
Public
?MacOS
Import "macscreen.c"
Private
Extern
Function CGDisplayCurrentMode:Byte Ptr(displayID:Byte Ptr)"MacOS"
Function CGGetActiveDisplayList:Byte Ptr(kMaxDisplays:Int, display:Byte Ptr, numDisplays:Int Var)"MacOS"
Function MACOS_GetWidth:Int(mode:Byte Ptr)"C"
Function MACOS_GetHeight:Int(mode:Byte Ptr)"C"
Function MACOS_GetBPP:Int(mode:Byte Ptr)"C"
Function MACOS_GetHertz:Int(mode:Byte Ptr)"C"
End Extern
Public
?Linux
Import brl.graphics
?
Rem
bbdoc: Aspekt-Ratio des Desktops (Monitors) abfragen
returns: AspektRatio als String
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopRatio:String (screen:Int=0)
Function DAR:Int (a:Int, b:Int)
Local fudge:Int = 0
Local Result:Int
If b mod a <= fudge
Result = a
Else
Result = DAR (b, a mod b)
EndIf
Return Result
End Function
Local X:Int = DesktopWidth(screen)
Local Y:Int = DesktopHeight(screen)
Local Div:Int = DAR(X,Y)
Local Result:String = String (X/Div) + ":" + String(Y/Div)
Select Result
Case "8:5" ; Return "16:10"
Default ; Return Result
End Select
End Function
Rem
bbdoc: Anzahl der Desktops (Monitore) abfragen
returns: Anzahl als Integer
about: <table>
<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>X</td><td>X</td><td></td></tr>
</table>
End Rem
Function DesktopCount:Int ()
?Win32
Return GetSystemMetrics (SM_CMONITORS)
?MacOS
Local display:Byte Ptr[] = New Byte Ptr[1]
Local iMode:Byte Ptr = Null
Local iCount:Int
CGGetActiveDisplayList 1, display, iCount
Return iCount
?Linux
Return 0
?
End Function
Rem
bbdoc: X-Koordinate des Desktops (Monitors) abfragen
returns: X-koordinate als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopX:Int (screen:Int = 0)
If screen < 0 Then screen = 0
?Win32
For Local display:TDisplay = EachIn TDisplay.List
If display.id = screen+1
Return display.X
EndIf
Next
Return 0
?MacOS
Return 0
?Linux
Return 0
?
End Function
Rem
bbdoc: Y-Koordinate des Desktops (Monitors) abfragen
returns: Y-koordinate als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopY:Int (screen:Int = 0)
If screen < 0 Then screen = 0
?Win32
For Local display:TDisplay = EachIn TDisplay.List
If display.id = screen+1
Return display.Y
EndIf
Next
Return 0
?MacOS
Return 0
?Linux
Return 0
?
End Function
Rem
bbdoc: Breite des Desktops (Monitors) abfragen
returns: Breite als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>-1</td><td>Gesammtbreite aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr>
</table>
End Rem
Function DesktopWidth:Int (screen:Int=0)
Local width:Int,height:Int,depth:Int,hertz:Int
GetDesktopMode (width, height, depth, hertz, screen)
Return width
End Function
Rem
bbdoc: Höhe des Desktops (Monitors) abfragen
returns: Höhe als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>-1</td><td>Gesammthöhe aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr>
</table>
End Rem
Function DesktopHeight:Int (screen:Int=0)
Local width:Int,height:Int,depth:Int,hertz:Int
GetDesktopMode (width, height, depth, hertz, screen)
Return height
End Function
Rem
bbdoc: Tiefe des Desktops (Monitors) abfragen
returns: Tiefe als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr>
</table>
End Rem
Function DesktopDepth:Int (screen:Int=0)
Local width:Int,height:Int,depth:Int,hertz:Int
GetDesktopMode (width, height, depth, hertz, screen)
Return depth
End Function
Rem
bbdoc: Wiederholrate des Desktops (Monitors) abfragen
returns: Wiederholrate als Integer
about: <table>
<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr>
</table>
End Rem
Function DesktopHertz:Int (screen:Int=0)
Local width:Int,height:Int,depth:Int,hertz:Int
GetDesktopMode (width, height, depth, hertz, screen)
Return hertz
End Function
Rem
bbdoc: Breite, Höhe, Tiefe und Wiederholrate des Desktops (Monitors) abfragen
about: Kompatibilität siehe DesktopWidth(), DesktopHeight(), DesktopDepth() und DesktopHertz()
End Rem
Function GetDesktopMode:Int (width:Int Var, height:Int Var, depth:Int Var, hertz:Int Var, screen:Int=0)
?Win32
Local hwnd:Int = GetDesktopWindow()
Local hdc:Int = GetDC(hwnd)
If hdc = Null Then Return -1
depth = GetDeviceCaps(hdc, BITSPIXEL)
hertz = GetDeviceCaps(hdc, VREFRESH)
ReleaseDC(hwnd,hdc)
If screen = -1
width = GetSystemMetrics (SM_CXVIRTUALSCREEN)
height = GetSystemMetrics (SM_CYVIRTUALSCREEN)
Else
Local valid:Byte = True
For Local display:TDisplay = EachIn TDisplay.List
If display.id = screen+1
width = display.width
height = display.height
Exit
EndIf
Next
EndIf
?MacOS
Local display:Byte Ptr[] = New Byte Ptr[screen+1]
Local iMode:Byte Ptr = Null
Local iCount:Int
CGGetActiveDisplayList screen+1, display, iCount
If (screen < iCount)
iMode = CGDisplayCurrentMode(display[screen])
Else
Throw " [DesktopExt] Screen '"+screen+"' does not exist!"
End If
width = MACOS_GetWidth(iMode)
height = MACOS_GetHeight(iMode)
depth = MACOS_GetBPP(iMode)
hertz = MACOS_GetHertz(iMode)
?Linux
CountGraphicsModes()
GetGraphicsMode (0,width,height,depth,hertz)
?
End Function
Rem
bbdoc: Screenshot des Desktops in einer Pixmap erstellen
returns: Screenshot als TPixmap
about: <table>
<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopPixmap:TPixmap (flag:Byte = True)
'Original Funktion von Suco-X
?Linux
Return Null
?MacOS
Return Null
?Win32
Local hwnd:Int = GetDesktopWindow()
If Not hwnd Return Null
Local hdc:Int = GetWindowDC(hwnd)
If Not hdc Return Null
Local hdcmem:Int = CreateCompatibleDC(hdc)
If Not hdcmem Return Null
Local info:BITMAPINFOHEADER = New BITMAPINFOHEADER
info.biSize = SizeOf(info)
info.biPlanes = 1
info.biCompression = 0
Local hertz:Int,depth:Int
GetDesktopMode:Int (info.biWidth,info.biHeight,depth,hertz,-1)
info.biBitCount = depth
Local bmpmem:Int = CreateCompatibleBitmap(hdc, info.biWidth, info.biHeight)
If (Not bmpmem) Or (Not SelectObject(hdcmem, bmpmem)) Return Null
If Not BitBlt(hdcmem,0,0,info.biWidth,info.biHeight,hdc,0,0,ROP_SRCCOPY) Return Null
Local out:TPixmap = CreatePixmap(info.biWidth, info.biHeight, PF_BGRA8888)
If Not GetDIBits(hdcmem, bmpmem, 0, info.biHeight, out.PixelPtr(0,0), info, 0) Return Null
DeleteDC(hdcmem)
DeleteObject(bmpmem)
ReleaseDC(hwnd, hdc)
out = out.Convert(PF_BGR888) 'dumm gelaufen, man kann nicht direkt in dem Format grabben
If flag = True out = YFlipPixmap(out)
Return out
?
End Function
Rem
bbdoc: Globale Maus X-Koordinate abfragen
returns: X-Koordinate als Integer
about: <table>
<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopMouseX:Int ()
?Linux
Return 0
?MacOS
Return 0
?Win32
Local Coord:Int[2]
GetCursorPos(Coord)
Return Coord[0]
?
End Function
Rem
bbdoc: Globale Maus Y-Koordinate abfragen
returns: Y-Koordinate als Integer
about: <table>
<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
<tr><td>X</td><td></td><td></td></tr>
</table>
End Rem
Function DesktopMouseY:Int ()
?Linux
Return 0
?MacOS
Return 0
?Win32
Local Coord:Int[2]
GetCursorPos(Coord)
Return Coord[1]
?
End Function