public GbmDisplay(string drmDevice) { _close = false; IntPtr udev = LibUdev.New(); _drmFd = LibC.Open(drmDevice, LibC.O_RDWR); if (_drmFd == -1) { IntPtr udevMonitor = LibUdev.MonitorNewFromNetlink(udev, "udev"); LibUdev.MonitorFilterAddMatchSubsystemDevtype(udevMonitor, "drm", null); LibUdev.MonitorEnableReceiving(udevMonitor); int udevMonitorFd = LibUdev.MonitorGetFd(udevMonitor); LibC.PollFd fd = new LibC.PollFd(); fd.fd = udevMonitorFd; fd.events = LibC.POLLIN | LibC.POLLPRI; LibC.PollFd[] fds = { fd }; while (_drmFd == -1) { int rc = LibC.Poll(fds, -1); if (rc > 0) { IntPtr device = LibUdev.MonitorReceiveDevice(udevMonitor); if (device == IntPtr.Zero) { break; } IntPtr deviceAction = LibUdev.DeviceGetAction(device); IntPtr deviceName = LibUdev.DeviceGetDevnode(device); string devAction = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(deviceAction); if (devAction == "add") { _drmFd = LibC.Open(drmDevice, LibC.O_RDWR); } LibUdev.DeviceUnref(device); } } LibUdev.MonitorUnref(udevMonitor); } LibUdev.Unref(udev); IntPtr resourcesPtr = Drm.ModeGetResources(_drmFd); Drm.ModeRes resources = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeRes>(resourcesPtr); for (int i = 0; i < resources.countConnectors; ++i) { uint connectorId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.connectors, i * sizeof(uint)); IntPtr connectorPtr = Drm.ModeGetConnector(_drmFd, connectorId); Drm.ModeConnector connector = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeConnector>(connectorPtr); if (connector.connection == Drm.MODE_CONNECTED) { _drmConnectorId = connector.connectorId; int SizeOfDrmModeModeInfo = System.Runtime.InteropServices.Marshal.SizeOf <Drm.ModeModeInfo>(); int area = 0; for (int j = 0; j < connector.countModes; ++j) { Drm.ModeModeInfo drmMode = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeModeInfo>(IntPtr.Add(connector.modes, j * SizeOfDrmModeModeInfo)); if ((drmMode.type & Drm.MODE_TYPE_PREFERRED) != 0) { int modeArea = drmMode.hdisplay * drmMode.vdisplay; if (modeArea > area) { _drmMode = drmMode; _width = drmMode.hdisplay; _height = drmMode.vdisplay; area = modeArea; } } } for (int j = 0; j < resources.countEncoders; ++j) { uint encoderId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.encoders, j * sizeof(uint)); IntPtr encoderPtr = Drm.ModeGetEncoder(_drmFd, encoderId); Drm.ModeEncoder encoder = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeEncoder>(encoderPtr); for (int k = 0; k < resources.countCrtcs; ++k) { uint crtcMask = (uint)(1 << k); if ((encoder.possibleCrtcs & crtcMask) != 0) { uint crtcId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.crtcs, k * sizeof(uint)); _drmEncoderCrtcId = crtcId; } } Drm.ModeFreeEncoder(encoderPtr); } break; } Drm.ModeFreeConnector(connectorPtr); } Drm.ModeFreeResources(resourcesPtr); Drm.SetClientCap(_drmFd, Drm.CLIENT_CAP_UNIVERSAL_PLANES, 1); _gbmDevice = Gbm.CreateDevice(_drmFd); _gbmSurface = Gbm.SurfaceCreate(_gbmDevice, (uint)_width, (uint)_height, Drm.FORMAT_ARGB8888, Gbm.BO_USE_SCANOUT | Gbm.BO_USE_RENDERING); _gbmBoToDrmFb = new Dictionary <IntPtr, uint>(); }
public GbmDisplay(string drmDevice) { _drmFd = LibC.Open(drmDevice, LibC.O_RDWR); IntPtr resourcesPtr = Drm.ModeGetResources(_drmFd); Drm.ModeRes resources = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeRes>(resourcesPtr); for (int i = 0; i < resources.countConnectors; ++i) { uint connectorId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.connectors, i * sizeof(uint)); IntPtr connectorPtr = Drm.ModeGetConnector(_drmFd, connectorId); Drm.ModeConnector connector = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeConnector>(connectorPtr); if (connector.connection == Drm.MODE_CONNECTED) { _drmConnectorId = connector.connectorId; int SizeOfDrmModeModeInfo = System.Runtime.InteropServices.Marshal.SizeOf <Drm.ModeModeInfo>(); for (int j = 0; j < connector.countModes; ++j) { _drmMode = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeModeInfo>(IntPtr.Add(connector.modes, j * SizeOfDrmModeModeInfo)); if ((_drmMode.type & Drm.MODE_TYPE_PREFERRED) != 0) { _width = _drmMode.hdisplay; _height = _drmMode.vdisplay; break; } } for (int j = 0; j < resources.countEncoders; ++j) { uint encoderId = (uint)System.Runtime.InteropServices.Marshal.ReadInt32(resources.encoders, j * sizeof(uint)); IntPtr encoderPtr = Drm.ModeGetEncoder(_drmFd, encoderId); Drm.ModeEncoder encoder = System.Runtime.InteropServices.Marshal.PtrToStructure <Drm.ModeEncoder>(encoderPtr); if (encoder.encoderId == connector.encoderId) { _drmEncoderCrtcId = encoder.crtcId; break; } Drm.ModeFreeEncoder(encoderPtr); } break; } Drm.ModeFreeConnector(connectorPtr); } Drm.ModeFreeResources(resourcesPtr); Drm.SetClientCap(_drmFd, Drm.CLIENT_CAP_UNIVERSAL_PLANES, 1); _gbmDevice = Gbm.CreateDevice(_drmFd); _gbmSurface = Gbm.SurfaceCreate(_gbmDevice, (uint)_width, (uint)_height, Drm.FORMAT_ARGB8888, Gbm.BO_USE_SCANOUT | Gbm.BO_USE_RENDERING); _gbmBoToDrmFb = new Dictionary <IntPtr, uint>(); LibEvdev.KeyDown += OnKeyDown; LibEvdev.KeyUp += OnKeyUp; LibEvdev.TouchDown += OnTouchDown; LibEvdev.TouchUp += OnTouchUp; LibEvdev.TouchMove += OnTouchMove; }