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