github.com/racerxdl/gonx@v0.0.0-20210103083128-c5afc43bcbd2/services/vi/display.go (about) 1 package vi 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "github.com/racerxdl/gonx/internal" 7 "github.com/racerxdl/gonx/nx/nxerrors" 8 "github.com/racerxdl/gonx/nx/nxtypes" 9 "github.com/racerxdl/gonx/services/ipc" 10 "unsafe" 11 ) 12 13 type Display struct { 14 ID uint64 15 VSync nxtypes.ReventHandle 16 } 17 18 func OpenDisplay(name string) (*Display, error) { 19 if viDebug { 20 fmt.Printf("VI::OpenDisplay(%s)\n", name) 21 } 22 if viInitializations <= 0 { 23 return nil, nxerrors.VINotInitialized 24 } 25 26 raw := make([]byte, 0x40) 27 copy(raw, name) 28 l := len(name) + 1 29 if l > 0x40 { 30 l = 0x40 31 } 32 raw[l-1] = 0x00 // force null-terminated 33 34 if viDebug { 35 println("VI::OpenDisplay() - IPC Call") 36 fmt.Printf("%+v\n", raw) 37 } 38 rq := ipc.MakeDefaultRequest(requestOpenDisplay) 39 rq.RawData = raw 40 41 disp := &Display{} 42 43 rs := ipc.ResponseFmt{} 44 rs.RawData = make([]byte, 8) // uint64 45 46 err := ipc.Send(iadsObject, &rq, &rs) 47 if err != nil { 48 if viDebug { 49 fmt.Printf("Error calling IPC: %s\n", err) 50 } 51 return nil, err 52 } 53 54 disp.ID = binary.LittleEndian.Uint64(rs.RawData) 55 56 return disp, nil 57 } 58 59 func CloseDisplay(d *Display) error { 60 if viDebug { 61 fmt.Printf("VI::CloseDisplay(%d)\n", d.ID) 62 } 63 if viInitializations <= 0 { 64 return nxerrors.VINotInitialized 65 } 66 67 if d == nil { 68 return nil 69 } 70 71 rq := ipc.MakeDefaultRequest(requestCloseDisplay) 72 rq.SetRawDataFromUint64(d.ID) 73 74 rs := ipc.ResponseFmt{} 75 76 return ipc.Send(iadsObject, &rq, &rs) 77 } 78 79 func GetDisplayVsyncEvent(d *Display) error { 80 if viDebug { 81 fmt.Printf("VI::GetDisplayVsyncEvent(%d)\n", d.ID) 82 } 83 if viInitializations <= 0 { 84 return nxerrors.VINotInitialized 85 } 86 87 rq := ipc.MakeDefaultRequest(requestDisplayVsyncEvent) 88 rq.SetRawDataFromUint64(d.ID) 89 90 rs := ipc.ResponseFmt{} 91 rs.CopyHandles = make([]nxtypes.Handle, 1) 92 93 err := ipc.Send(iadsObject, &rq, &rs) 94 if err != nil { 95 return err 96 } 97 98 d.VSync = nxtypes.ReventHandle(rs.CopyHandles[0]) 99 100 return nil 101 } 102 103 func CreateManagedLayer(display *Display, flags uint32, aruid nxtypes.ARUID) (uint64, error) { 104 if viDebug { 105 fmt.Printf("VI::CreateManagedLayer(%s, %d, %d)\n", display.ID, flags, aruid) 106 } 107 if viInitializations <= 0 { 108 return 0, nxerrors.VINotInitialized 109 } 110 111 rqArgs := struct { 112 layerFlags uint32 113 displayId uint64 114 aruid nxtypes.ARUID 115 }{ 116 displayId: display.ID, 117 layerFlags: flags, 118 aruid: aruid, 119 } 120 121 rq := ipc.MakeDefaultRequest(requestCreateManagedLayer) 122 rq.RawData = make([]byte, unsafe.Sizeof(rqArgs)) 123 internal.Memcpy(unsafe.Pointer(&rq.RawData[0]), unsafe.Pointer(&rqArgs), unsafe.Sizeof(rqArgs)) 124 125 rs := ipc.ResponseFmt{} 126 rs.RawData = make([]byte, 8) // one uint64 127 128 err := ipc.Send(imdsObject, &rq, &rs) 129 if err != nil { 130 return 0, err 131 } 132 133 return binary.LittleEndian.Uint64(rs.RawData), nil 134 } 135 136 func OpenLayer(displayName string, layerId uint64, aruid nxtypes.ARUID) (*IGBP, error) { 137 if viDebug { 138 fmt.Printf("VI::OpenLayer(%s, %d, %d)\n", displayName, layerId, aruid) 139 } 140 if viInitializations <= 0 { 141 return nil, nxerrors.VINotInitialized 142 } 143 144 parcelBuff := [0x210]byte{} 145 146 ipcBuff := &ipc.Buffer{ 147 Addr: uintptr(unsafe.Pointer(&parcelBuff[0])), 148 Size: 0x210, 149 Type: 6, 150 } 151 152 rqArgs := struct { 153 displayName [0x40]byte 154 layerId uint64 155 aruid nxtypes.ARUID 156 }{} 157 158 rqArgs.layerId = layerId 159 rqArgs.aruid = aruid 160 copy(rqArgs.displayName[:], displayName) 161 rqArgs.displayName[0x3F] = 0 // ensure at least last char is null 162 163 buff := make([]byte, unsafe.Sizeof(rqArgs)) 164 internal.Memcpy(unsafe.Pointer(&buff[0]), unsafe.Pointer(&rqArgs), uintptr(len(buff))) 165 166 rq := ipc.MakeDefaultRequest(requestOpenLayer) 167 rq.Buffers = []*ipc.Buffer{ipcBuff} 168 rq.RawData = buff 169 rq.SendPID = true 170 171 rs := ipc.ResponseFmt{} 172 rs.RawData = make([]byte, 8) // one uint64 173 174 err := ipc.Send(iadsObject, &rq, &rs) 175 if err != nil { 176 return nil, err 177 } 178 179 p, err := ParcelLoad(parcelBuff[:]) 180 if err != nil { 181 return nil, err 182 } 183 184 b, err := p.ReadBinder() 185 if err != nil { 186 return nil, err 187 } 188 189 igbp := &IGBP{ 190 IgbpBinder: *b, 191 } 192 193 return igbp, nil 194 } 195 196 func CloseLayer(layerId uint64) error { 197 if viDebug { 198 fmt.Printf("VI::CloseLayer(%d)\n", layerId) 199 } 200 if viInitializations <= 0 { 201 return nxerrors.VINotInitialized 202 } 203 204 rq := ipc.MakeDefaultRequest(requestCloseLayer) 205 rq.SetRawDataFromUint64(layerId) 206 207 rs := ipc.ResponseFmt{} 208 209 return ipc.Send(iadsObject, &rq, &rs) 210 } 211 212 func DestroyManagedLayer(layerId uint64) error { 213 if viDebug { 214 fmt.Printf("VI::DestroyManagedLayer(%d)\n", layerId) 215 } 216 if viInitializations <= 0 { 217 return nxerrors.VINotInitialized 218 } 219 220 rq := ipc.MakeDefaultRequest(requestDestroyManagedLayer) 221 rq.SetRawDataFromUint64(layerId) 222 223 rs := ipc.ResponseFmt{} 224 225 return ipc.Send(imdsObject, &rq, &rs) 226 } 227 228 func IadsSetLayerScalingMode(scalingMode ScalingMode, layerId uint64) error { 229 if viDebug { 230 fmt.Printf("VI::IadsSetLayerScalingMode(%d, %d)\n", scalingMode, layerId) 231 } 232 if viInitializations <= 0 { 233 return nxerrors.VINotInitialized 234 } 235 236 params := struct { 237 scalingMode uint32 238 layerId uint64 239 }{ 240 scalingMode: uint32(scalingMode), 241 layerId: layerId, 242 } 243 244 buff := make([]byte, unsafe.Sizeof(params)) 245 internal.Memcpy(unsafe.Pointer(&buff[0]), unsafe.Pointer(¶ms), uintptr(len(buff))) 246 247 rq := ipc.MakeDefaultRequest(requestSetLayerScalingMode) 248 rq.RawData = buff 249 250 rs := ipc.ResponseFmt{} 251 252 return ipc.Send(iadsObject, &rq, &rs) 253 }