code.witches.io/go/sdl2@v0.1.1/video.go (about)

     1  package sdl
     2  
     3  // #include <SDL2/SDL_video.h>
     4  // #include <SDL2/SDL_syswm.h>
     5  import "C"
     6  import (
     7  	"unsafe"
     8  
     9  	"code.witches.io/go/sdl2/internal"
    10  )
    11  
    12  type Window C.struct_SDL_Window
    13  
    14  type WindowFlags uint32
    15  
    16  const (
    17  	WindowFullscreen WindowFlags = 1 << iota
    18  	WindowOpenGL
    19  	WindowShown
    20  	WindowHidden
    21  	WindowBorderless
    22  	WindowResizable
    23  	WindowMinimized
    24  	WindowMaximized
    25  	WindowInputGrabbed
    26  	WindowInputFocus
    27  	WindowMouseFocus
    28  	WindowForeign
    29  	WindowFullscreenDesktop WindowFlags = 1<<iota + 1
    30  	WindowAllowHighDPI      WindowFlags = 1 << iota
    31  	WindowMouseCapture
    32  	WindowAlwaysOnTop
    33  	WindowSkipTaskbar
    34  	WindowUtility
    35  	WindowTooltip
    36  	WindowPopupMenu
    37  	WindowVulkan WindowFlags = 1 << 28
    38  )
    39  
    40  const (
    41  	WindowPositionCenteredMask  int = 0x2fff0000
    42  	WindowPositionCentered      int = WindowPositionCenteredMask
    43  	WindowPositionUndefinedMask int = 0x1fff0000
    44  	WindowPositionUndefined     int = WindowPositionUndefinedMask
    45  )
    46  
    47  func WindowPositionCenteredDisplay(displayIndex int) int {
    48  	return WindowPositionCenteredMask | displayIndex
    49  }
    50  
    51  func WindowPositionUndefinedDisplay(displayIndex int) int {
    52  	return WindowPositionUndefinedMask | displayIndex
    53  }
    54  
    55  type WindowEventID uint8
    56  
    57  const (
    58  	WindowEventNone WindowEventID = iota
    59  	WindowEventShown
    60  	WindowEventHidden
    61  	WindowEventExposed
    62  	WindowEventMoved
    63  	WindowEventResized
    64  	WindowEventSizeChanged
    65  	WindowEventMinimized
    66  	WindowEventMaximized
    67  	WindowEventRestored
    68  	WindowEventMouseEntered
    69  	WindowEventMouseLeft
    70  	WindowEventFocusGained
    71  	WindowEventFocusLost
    72  	WindowEventClose
    73  	WindowEventTakeFocus
    74  	WindowEventHitTest
    75  )
    76  
    77  var windowEventToStringMap = map[WindowEventID]string{
    78  	WindowEventNone:         "none",
    79  	WindowEventShown:        "shown",
    80  	WindowEventHidden:       "hidden",
    81  	WindowEventExposed:      "exposed",
    82  	WindowEventMoved:        "moved",
    83  	WindowEventResized:      "resized",
    84  	WindowEventSizeChanged:  "size changed",
    85  	WindowEventMinimized:    "minimized",
    86  	WindowEventMaximized:    "maximized",
    87  	WindowEventRestored:     "restored",
    88  	WindowEventMouseEntered: "mouse entered",
    89  	WindowEventMouseLeft:    "mouse left",
    90  	WindowEventFocusGained:  "focus gained",
    91  	WindowEventFocusLost:    "focus lost",
    92  	WindowEventClose:        "close",
    93  	WindowEventTakeFocus:    "take focus",
    94  	WindowEventHitTest:      "hit test",
    95  }
    96  
    97  func (i WindowEventID) String() string {
    98  	s, ok := windowEventToStringMap[i]
    99  	if !ok {
   100  		return "unknown window event id"
   101  	}
   102  	return s
   103  }
   104  
   105  func CreateWindow(title string, x, y, w, h int, flags WindowFlags) (*Window, error) {
   106  	nativeTitle := C.CString(title)
   107  	defer C.free(unsafe.Pointer(nativeTitle))
   108  
   109  	nativeWindow := C.SDL_CreateWindow(nativeTitle, C.int(x), C.int(y), C.int(w), C.int(h), C.Uint32(flags))
   110  	if nativeWindow == nil {
   111  		return nil, GetError()
   112  	}
   113  	return (*Window)(nativeWindow), nil
   114  }
   115  
   116  func (w *Window) Destroy() {
   117  	if w != nil {
   118  		C.SDL_DestroyWindow((*C.struct_SDL_Window)(w))
   119  	}
   120  }
   121  
   122  func (w *Window) Surface() (*Surface, error) {
   123  	nativeSurface := C.SDL_GetWindowSurface((*C.struct_SDL_Window)(w))
   124  	if nativeSurface == nil {
   125  		return nil, GetError()
   126  	}
   127  	return (*Surface)(nativeSurface), nil
   128  }
   129  
   130  func (w *Window) UpdateSurface() error {
   131  	if C.SDL_UpdateWindowSurface((*C.struct_SDL_Window)(w)) != 0 {
   132  		return GetError()
   133  	}
   134  	return nil
   135  }
   136  
   137  func (w *Window) PixelFormat() (PixelFormat, error) {
   138  	format := PixelFormat(C.SDL_GetWindowPixelFormat((*C.struct_SDL_Window)(w)))
   139  	if format == PixelFormatUnknown {
   140  		return 0, GetError()
   141  	}
   142  	return format, nil
   143  }
   144  
   145  type SubsystemType C.SDL_SYSWM_TYPE
   146  
   147  const (
   148  	SubsystemUnknown  SubsystemType = C.SDL_SYSWM_UNKNOWN
   149  	SubsystemWindows  SubsystemType = C.SDL_SYSWM_WINDOWS
   150  	SubsystemX11      SubsystemType = C.SDL_SYSWM_X11
   151  	SubsystemDirectFB SubsystemType = C.SDL_SYSWM_DIRECTFB
   152  	SubsystemCocoa    SubsystemType = C.SDL_SYSWM_COCOA
   153  	SubsystemUIKit    SubsystemType = C.SDL_SYSWM_UIKIT
   154  	SubsystemWayland  SubsystemType = C.SDL_SYSWM_WAYLAND
   155  	SubsystemMir      SubsystemType = C.SDL_SYSWM_MIR
   156  	SubsystemWinRT    SubsystemType = C.SDL_SYSWM_WINRT
   157  	SubsystemAndroid  SubsystemType = C.SDL_SYSWM_ANDROID
   158  	SubsystemVivante  SubsystemType = C.SDL_SYSWM_VIVANTE
   159  )
   160  
   161  func (s SubsystemType) String() string {
   162  	return map[SubsystemType]string{
   163  		SubsystemWindows:  "Windows",
   164  		SubsystemX11:      "X Window System",
   165  		SubsystemDirectFB: "DirectFB",
   166  		SubsystemCocoa:    "Apple Mac OS X",
   167  		SubsystemUIKit:    "Apple iOS",
   168  		SubsystemWayland:  "Wayland",
   169  		SubsystemMir:      "Mir",
   170  		SubsystemWinRT:    "WinRT",
   171  		SubsystemAndroid:  "Android",
   172  		SubsystemVivante:  "Vivante",
   173  	}[s]
   174  }
   175  
   176  type WMInfo struct {
   177  	Version   Version
   178  	Subsystem SubsystemType
   179  	_         [unsafe.Sizeof(C.struct_SDL_SysWMinfo{})]uint8
   180  }
   181  
   182  type WMInfoXlib struct {
   183  	Version   Version
   184  	Subsystem SubsystemType
   185  	Display   uintptr
   186  	Window    uintptr
   187  }
   188  
   189  type WMInfoCocoa struct {
   190  	Version   Version
   191  	Subsystem SubsystemType
   192  	Window    uintptr
   193  }
   194  
   195  type WMInfoWin32 struct {
   196  	Version       Version
   197  	Subsystem     SubsystemType
   198  	Window        uintptr
   199  	DeviceContext uintptr
   200  	Instance      uintptr
   201  }
   202  
   203  func (w *Window) GetWMInfo() (WMInfo, error) {
   204  	info := WMInfo{
   205  		Version: GetVersion(),
   206  	}
   207  	if C.SDL_GetWindowWMInfo((*C.struct_SDL_Window)(w), (*C.struct_SDL_SysWMinfo)(unsafe.Pointer(&info))) == 0 {
   208  		return WMInfo{}, GetError()
   209  	}
   210  	return info, nil
   211  }
   212  
   213  func GetDisplayBounds(displayIndex int, rect *Rect) error {
   214  	var r internal.Rect
   215  
   216  	if C.SDL_GetDisplayBounds(C.int(displayIndex), (*C.struct_SDL_Rect)(unsafe.Pointer(&r))) != 0 {
   217  		return GetError()
   218  	}
   219  
   220  	rect.fromInternal(r)
   221  
   222  	return nil
   223  }
   224  
   225  // GetDisplayUsableBounds gets the usable desktop area represented by a display.
   226  //
   227  // The primary display (`displayIndex` zero) is always located at 0,0.
   228  //
   229  // This is the same area as GetDisplayBounds reports, but with portions
   230  // reserved by the system removed. For example, on Apple's macOS, this
   231  // subtracts the area occupied by the menu bar and dock.
   232  //
   233  // Setting a window to be fullscreen generally bypasses these unusable areas,
   234  // so these are good guidelines for the maximum space available to a
   235  // non-fullscreen window.
   236  //
   237  // The parameter `rect` is ignored if it is nil.
   238  //
   239  // This function also returns -1 if the parameter `displayIndex` is out of
   240  // range.
   241  //
   242  // displayIndex is the index of the display to query the usable bounds from.
   243  // rect is the Rect structure filled in with the display bounds
   244  //
   245  // This function is available since SDL 2.0.5.
   246  func GetDisplayUsableBounds(displayIndex int, rect *Rect) error {
   247  	var r internal.Rect
   248  	if C.SDL_GetDisplayBounds(C.int(displayIndex), (*C.struct_SDL_Rect)(unsafe.Pointer(&r))) != 0 {
   249  		return GetError()
   250  	}
   251  	rect.fromInternal(r)
   252  	return nil
   253  }
   254  
   255  func GetNumVideoDisplays() (int, error) {
   256  	num := int(C.SDL_GetNumVideoDisplays())
   257  	if num < 0 {
   258  		return 0, GetError()
   259  	}
   260  	return num, nil
   261  }
   262  
   263  func GetNumVideoDrivers() (int, error) {
   264  	num := int(C.SDL_GetNumVideoDrivers())
   265  	if num < 0 {
   266  		return 0, GetError()
   267  	}
   268  	return num, nil
   269  }
   270  
   271  func GetVideoDriver(index int) string {
   272  	return C.GoString(C.SDL_GetVideoDriver(C.int(index)))
   273  }