monitor.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. package glfw
  2. //#define GLFW_INCLUDE_NONE
  3. //#include "glfw/include/GLFW/glfw3.h"
  4. //GLFWmonitor* GetMonitorAtIndex(GLFWmonitor **monitors, int index);
  5. //GLFWvidmode GetVidmodeAtIndex(GLFWvidmode *vidmodes, int index);
  6. //void glfwSetMonitorCallbackCB();
  7. //unsigned int GetGammaAtIndex(unsigned short *color, int i);
  8. //void SetGammaAtIndex(unsigned short *color, int i, unsigned short value);
  9. import "C"
  10. import (
  11. "unsafe"
  12. )
  13. // Monitor represents a monitor.
  14. type Monitor struct {
  15. data *C.GLFWmonitor
  16. }
  17. // PeripheralEvent corresponds to a peripheral(Monitor or Joystick)
  18. // configuration event.
  19. type PeripheralEvent int
  20. // GammaRamp describes the gamma ramp for a monitor.
  21. type GammaRamp struct {
  22. Red []uint16 // A slice of value describing the response of the red channel.
  23. Green []uint16 // A slice of value describing the response of the green channel.
  24. Blue []uint16 // A slice of value describing the response of the blue channel.
  25. }
  26. // PeripheralEvent events.
  27. const (
  28. Connected PeripheralEvent = C.GLFW_CONNECTED
  29. Disconnected PeripheralEvent = C.GLFW_DISCONNECTED
  30. )
  31. // VidMode describes a single video mode.
  32. type VidMode struct {
  33. Width int // The width, in pixels, of the video mode.
  34. Height int // The height, in pixels, of the video mode.
  35. RedBits int // The bit depth of the red channel of the video mode.
  36. GreenBits int // The bit depth of the green channel of the video mode.
  37. BlueBits int // The bit depth of the blue channel of the video mode.
  38. RefreshRate int // The refresh rate, in Hz, of the video mode.
  39. }
  40. var fMonitorHolder func(monitor *Monitor, event PeripheralEvent)
  41. //export goMonitorCB
  42. func goMonitorCB(monitor unsafe.Pointer, event C.int) {
  43. fMonitorHolder(&Monitor{(*C.GLFWmonitor)(monitor)}, PeripheralEvent(event))
  44. }
  45. // GetMonitors returns a slice of handles for all currently connected monitors.
  46. func GetMonitors() []*Monitor {
  47. var length int
  48. mC := C.glfwGetMonitors((*C.int)(unsafe.Pointer(&length)))
  49. panicError()
  50. if mC == nil {
  51. return nil
  52. }
  53. m := make([]*Monitor, length)
  54. for i := 0; i < length; i++ {
  55. m[i] = &Monitor{C.GetMonitorAtIndex(mC, C.int(i))}
  56. }
  57. return m
  58. }
  59. // GetPrimaryMonitor returns the primary monitor. This is usually the monitor
  60. // where elements like the Windows task bar or the OS X menu bar is located.
  61. func GetPrimaryMonitor() *Monitor {
  62. m := C.glfwGetPrimaryMonitor()
  63. panicError()
  64. if m == nil {
  65. return nil
  66. }
  67. return &Monitor{m}
  68. }
  69. // GetPos returns the position, in screen coordinates, of the upper-left
  70. // corner of the monitor.
  71. func (m *Monitor) GetPos() (x, y int) {
  72. var xpos, ypos C.int
  73. C.glfwGetMonitorPos(m.data, &xpos, &ypos)
  74. panicError()
  75. return int(xpos), int(ypos)
  76. }
  77. // GetWorkarea returns the position, in screen coordinates, of the upper-left
  78. // corner of the work area of the specified monitor along with the work area
  79. // size in screen coordinates. The work area is defined as the area of the
  80. // monitor not occluded by the operating system task bar where present. If no
  81. // task bar exists then the work area is the monitor resolution in screen
  82. // coordinates.
  83. //
  84. // This function must only be called from the main thread.
  85. func (m *Monitor) GetWorkarea() (x, y, width, height int) {
  86. var cX, cY, cWidth, cHeight C.int
  87. C.glfwGetMonitorWorkarea(m.data, &cX, &cY, &cWidth, &cHeight)
  88. x, y, width, height = int(cX), int(cY), int(cWidth), int(cHeight)
  89. return
  90. }
  91. // GetContentScale function retrieves the content scale for the specified monitor.
  92. // The content scale is the ratio between the current DPI and the platform's
  93. // default DPI. If you scale all pixel dimensions by this scale then your content
  94. // should appear at an appropriate size. This is especially important for text
  95. // and any UI elements.
  96. //
  97. // This function must only be called from the main thread.
  98. func (m *Monitor) GetContentScale() (float32, float32) {
  99. var x, y C.float
  100. C.glfwGetMonitorContentScale(m.data, &x, &y)
  101. return float32(x), float32(y)
  102. }
  103. // SetUserPointer sets the user-defined pointer of the monitor. The current value
  104. // is retained until the monitor is disconnected. The initial value is nil.
  105. //
  106. // This function may be called from the monitor callback, even for a monitor
  107. // that is being disconnected.
  108. //
  109. // This function may be called from any thread. Access is not synchronized.
  110. func (m *Monitor) SetUserPointer(pointer unsafe.Pointer) {
  111. C.glfwSetMonitorUserPointer(m.data, pointer)
  112. }
  113. // GetUserPointer returns the current value of the user-defined pointer of the
  114. // monitor. The initial value is nil.
  115. //
  116. // This function may be called from the monitor callback, even for a monitor
  117. // that is being disconnected.
  118. //
  119. // This function may be called from any thread. Access is not synchronized.
  120. func (m *Monitor) GetUserPointer() unsafe.Pointer {
  121. return C.glfwGetMonitorUserPointer(m.data)
  122. }
  123. // GetPhysicalSize returns the size, in millimetres, of the display area of the
  124. // monitor.
  125. //
  126. // Note: Some operating systems do not provide accurate information, either
  127. // because the monitor's EDID data is incorrect, or because the driver does not
  128. // report it accurately.
  129. func (m *Monitor) GetPhysicalSize() (width, height int) {
  130. var wi, h C.int
  131. C.glfwGetMonitorPhysicalSize(m.data, &wi, &h)
  132. panicError()
  133. return int(wi), int(h)
  134. }
  135. // GetName returns a human-readable name of the monitor, encoded as UTF-8.
  136. func (m *Monitor) GetName() string {
  137. mn := C.glfwGetMonitorName(m.data)
  138. panicError()
  139. if mn == nil {
  140. return ""
  141. }
  142. return C.GoString(mn)
  143. }
  144. // MonitorCallback is the signature for monitor configuration callback
  145. // functions.
  146. type MonitorCallback func(monitor *Monitor, event PeripheralEvent)
  147. // SetMonitorCallback sets the monitor configuration callback, or removes the
  148. // currently set callback. This is called when a monitor is connected to or
  149. // disconnected from the system.
  150. //
  151. // This function must only be called from the main thread.
  152. func SetMonitorCallback(cbfun MonitorCallback) MonitorCallback {
  153. previous := fMonitorHolder
  154. fMonitorHolder = cbfun
  155. if cbfun == nil {
  156. C.glfwSetMonitorCallback(nil)
  157. } else {
  158. C.glfwSetMonitorCallbackCB()
  159. }
  160. return previous
  161. }
  162. // GetVideoModes returns an array of all video modes supported by the monitor.
  163. // The returned array is sorted in ascending order, first by color bit depth
  164. // (the sum of all channel depths) and then by resolution area (the product of
  165. // width and height).
  166. func (m *Monitor) GetVideoModes() []*VidMode {
  167. var length int
  168. vC := C.glfwGetVideoModes(m.data, (*C.int)(unsafe.Pointer(&length)))
  169. panicError()
  170. if vC == nil {
  171. return nil
  172. }
  173. v := make([]*VidMode, length)
  174. for i := 0; i < length; i++ {
  175. t := C.GetVidmodeAtIndex(vC, C.int(i))
  176. v[i] = &VidMode{int(t.width), int(t.height), int(t.redBits), int(t.greenBits), int(t.blueBits), int(t.refreshRate)}
  177. }
  178. return v
  179. }
  180. // GetVideoMode returns the current video mode of the monitor. If you
  181. // are using a full screen window, the return value will therefore depend on
  182. // whether it is focused.
  183. func (m *Monitor) GetVideoMode() *VidMode {
  184. t := C.glfwGetVideoMode(m.data)
  185. if t == nil {
  186. return nil
  187. }
  188. panicError()
  189. return &VidMode{int(t.width), int(t.height), int(t.redBits), int(t.greenBits), int(t.blueBits), int(t.refreshRate)}
  190. }
  191. // SetGamma generates a 256-element gamma ramp from the specified exponent and then calls
  192. // SetGamma with it.
  193. func (m *Monitor) SetGamma(gamma float32) {
  194. C.glfwSetGamma(m.data, C.float(gamma))
  195. panicError()
  196. }
  197. // GetGammaRamp retrieves the current gamma ramp of the monitor.
  198. func (m *Monitor) GetGammaRamp() *GammaRamp {
  199. var ramp GammaRamp
  200. rampC := C.glfwGetGammaRamp(m.data)
  201. panicError()
  202. if rampC == nil {
  203. return nil
  204. }
  205. length := int(rampC.size)
  206. ramp.Red = make([]uint16, length)
  207. ramp.Green = make([]uint16, length)
  208. ramp.Blue = make([]uint16, length)
  209. for i := 0; i < length; i++ {
  210. ramp.Red[i] = uint16(C.GetGammaAtIndex(rampC.red, C.int(i)))
  211. ramp.Green[i] = uint16(C.GetGammaAtIndex(rampC.green, C.int(i)))
  212. ramp.Blue[i] = uint16(C.GetGammaAtIndex(rampC.blue, C.int(i)))
  213. }
  214. return &ramp
  215. }
  216. // SetGammaRamp sets the current gamma ramp for the monitor.
  217. func (m *Monitor) SetGammaRamp(ramp *GammaRamp) {
  218. var rampC C.GLFWgammaramp
  219. length := len(ramp.Red)
  220. for i := 0; i < length; i++ {
  221. C.SetGammaAtIndex(rampC.red, C.int(i), C.ushort(ramp.Red[i]))
  222. C.SetGammaAtIndex(rampC.green, C.int(i), C.ushort(ramp.Green[i]))
  223. C.SetGammaAtIndex(rampC.blue, C.int(i), C.ushort(ramp.Blue[i]))
  224. }
  225. C.glfwSetGammaRamp(m.data, &rampC)
  226. panicError()
  227. }