void Init() { fixed(void *pnfo = &_varInfo) { if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOGET_VSCREENINFO, pnfo)) { throw new Exception("FBIOGET_VSCREENINFO error: " + Marshal.GetLastWin32Error()); } SetBpp(); _varInfo.yoffset = 100; if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOPUT_VSCREENINFO, pnfo)) { _varInfo.transp = new fb_bitfield(); } if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOPUT_VSCREENINFO, pnfo)) { throw new Exception("FBIOPUT_VSCREENINFO error: " + Marshal.GetLastWin32Error()); } if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOGET_VSCREENINFO, pnfo)) { throw new Exception("FBIOGET_VSCREENINFO error: " + Marshal.GetLastWin32Error()); } if (_varInfo.bits_per_pixel != 32) { throw new Exception("Unable to set 32-bit display mode"); } } fixed(void *pnfo = &_fixedInfo) if (-1 == NativeUnsafeMethods.ioctl(_fd, FbIoCtl.FBIOGET_FSCREENINFO, pnfo)) { throw new Exception("FBIOGET_FSCREENINFO error: " + Marshal.GetLastWin32Error()); } _mappedLength = new IntPtr(_fixedInfo.line_length * _varInfo.yres); _mappedAddress = NativeUnsafeMethods.mmap(IntPtr.Zero, _mappedLength, 3, 1, _fd, IntPtr.Zero); if (_mappedAddress == new IntPtr(-1)) { throw new Exception($"Unable to mmap {_mappedLength} bytes, error {Marshal.GetLastWin32Error()}"); fixed(fb_fix_screeninfo *pnfo = &_fixedInfo) { int idlen; for (idlen = 0; idlen < 16 && pnfo->id[idlen] != 0; idlen++) { ; } Id = Encoding.ASCII.GetString(pnfo->id, idlen); } } void SetBpp() { _varInfo.bits_per_pixel = 32; _varInfo.grayscale = 0; _varInfo.red = _varInfo.blue = _varInfo.green = _varInfo.transp = new fb_bitfield { length = 8 }; _varInfo.green.offset = 8; _varInfo.blue.offset = 16; _varInfo.transp.offset = 24; }
void VSync() { NativeUnsafeMethods.ioctl(_fb, FbIoCtl.FBIO_WAITFORVSYNC, null); }