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(&params), 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  }