private unsafe static ModeEncoder *GetEncoder(int fd, ModeConnector *c) { ModeEncoder *encoder = null; for (int i = 0; i < c->count_encoders && encoder == null; i++) { ModeEncoder *e = (ModeEncoder *)Drm.ModeGetEncoder( fd, *(c->encoders + i)); if (e != null) { if (e->encoder_id == c->encoder_id) { encoder = e; } else { Drm.ModeFreeEncoder((IntPtr)e); } } } if (encoder != null) { Debug.Print("[KMS] Encoder {0} found for connector {1}", encoder->encoder_id, c->connector_id); } else { Debug.Print("[KMS] Failed to find encoder for connector {0}", c->connector_id); } return(encoder); }
/// \internal /// <summary> /// Queries the specified GPU for connected displays and, optionally, /// returns the list of displays. /// </summary> /// <returns><c>true</c>, if at least one display is connected, <c>false</c> otherwise.</returns> /// <param name="fd">The fd for the GPU to query, obtained through open("/dev/dri/card0").</param> /// <param name="displays"> /// If not null, this will contain a list <see cref="LinuxDisplay" /> instances, /// one for each connected display. /// </param> internal static bool QueryDisplays(int fd, List <LinuxDisplay> displays) { unsafe { var has_displays = false; if (displays != null) { displays.Clear(); } var resources = (ModeRes *)Drm.ModeGetResources(fd); if (resources == null) { Debug.Print("[KMS] Drm.ModeGetResources failed."); return(false); } Debug.Print("[KMS] DRM found {0} connectors", resources->count_connectors); // Search for a valid connector ModeConnector *connector = null; for (var i = 0; i < resources->count_connectors; i++) { connector = (ModeConnector *)Drm.ModeGetConnector(fd, *(resources->connectors + i)); if (connector != null) { var success = false; LinuxDisplay display = null; try { if (connector->connection == ModeConnection.Connected && connector->count_modes > 0) { success = QueryDisplay(fd, connector, out display); has_displays |= success; } } catch (Exception e) { Debug.Print("[KMS] Failed to add display. Error: {0}", e); } if (success && displays != null) { displays.Add(display); } else { Drm.ModeFreeConnector((IntPtr)connector); connector = null; } } } return(has_displays); } }
private unsafe static bool QueryDisplay(int fd, ModeConnector *c, out LinuxDisplay display) { display = null; // Find corresponding encoder ModeEncoder *encoder = GetEncoder(fd, c); if (encoder == null) { return(false); } ModeCrtc *crtc = GetCrtc(fd, encoder); if (crtc == null) { return(false); } display = new LinuxDisplay(fd, (IntPtr)c, (IntPtr)encoder, (IntPtr)crtc); return(true); }