private unsafe static void GetModes(LinuxDisplay display, DisplayResolution[] modes, out DisplayResolution current) { int mode_count = display.pConnector->count_modes; Debug.Print("[KMS] Display supports {0} mode(s)", mode_count); for (int i = 0; i < mode_count; i++) { ModeInfo *mode = display.pConnector->modes + i; if (mode != null) { Debug.Print("Mode {0}: {1}x{2} @{3}", i, mode->hdisplay, mode->vdisplay, mode->vrefresh); DisplayResolution res = GetDisplayResolution(mode); modes[i] = res; } } if (display.pCrtc->mode_valid != 0) { ModeInfo cmode = display.pCrtc->mode; current = GetDisplayResolution(&cmode); } else { current = GetDisplayResolution(display.pConnector->modes); } Debug.Print("Current mode: {0}", current.ToString()); }
/// \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 { bool has_displays = false; if (displays != null) { displays.Clear(); } ModeRes *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 (int i = 0; i < resources->count_connectors; i++) { connector = (ModeConnector *)Drm.ModeGetConnector(fd, *(resources->connectors + i)); if (connector != null) { bool 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); } }
public override bool TryRestoreResolution(DisplayDevice device) { unsafe { LinuxDisplay display = (LinuxDisplay)device.Id; ModeInfo mode = display.OriginalMode; int connector_id = display.pConnector->connector_id; return(Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0, &connector_id, 1, &mode) == 0); } }
private void UpdateCursor() { Point p = new Point( (int)Math.Round(CursorPosition.X + CursorOffset.X), (int)Math.Round(CursorPosition.Y + CursorOffset.Y)); DisplayDevice display = DisplayDevice.FromPoint(p.X, p.Y) ?? DisplayDevice.Default; if (display != null) { LinuxDisplay d = (LinuxDisplay)display.Id; Drm.MoveCursor(d.FD, d.Id, p.X, p.Y); } }
public LinuxWindowInfo(IntPtr display, int fd, IntPtr gbm, LinuxDisplay display_device) : base(IntPtr.Zero, display, IntPtr.Zero) { if (display_device == null) { throw new ArgumentNullException(); } FD = fd; BufferManager = gbm; DisplayDevice = display_device; // The window handle and surface handle must // be filled in manually once they are known. }
private unsafe static ModeInfo *GetModeInfo(LinuxDisplay display, DisplayResolution resolution) { for (int i = 0; i < display.pConnector->count_modes; i++) { ModeInfo *mode = display.pConnector->modes + i; if (mode != null && mode->hdisplay == resolution.Width && mode->vdisplay == resolution.Height) { return(mode); } } return(null); }
public override bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution) { unsafe { LinuxDisplay display = (LinuxDisplay)device.Id; ModeInfo * mode = GetModeInfo(display, resolution); int connector_id = display.pConnector->connector_id; if (mode != null) { return(Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0, &connector_id, 1, mode) == 0); } return(false); } }
private void UpdateDisplayIndices(LinuxDisplay display, DisplayDevice device) { if (!DisplayIds.ContainsKey(display.Id)) { Debug.Print("[KMS] Adding display {0} as {1}", display.Id, AvailableDevices.Count); DisplayIds.Add(display.Id, AvailableDevices.Count); } int index = DisplayIds[display.Id]; if (index >= AvailableDevices.Count) { AvailableDevices.Add(device); } else { AvailableDevices[index] = device; } }
private unsafe void AddDisplay(LinuxDisplay display) { DisplayResolution[] modes = new DisplayResolution[display.pConnector->count_modes]; DisplayResolution current; GetModes(display, modes, out current); bool is_primary = AvailableDevices.Count == 0; DisplayDevice device = new DisplayDevice(current, is_primary, modes, GetBounds(current), display); if (is_primary) { Primary = device; } UpdateDisplayIndices(display, device); Debug.Print("[KMS] Added DisplayDevice {0}", device); }
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); }