x11modesi.inc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. Constructor TX11Modes.Create(ADisplay : PDisplay; AScreen : cint);
  2. Begin
  3. FDisplay := ADisplay;
  4. FScreen := AScreen;
  5. End;
  6. Constructor TX11ModesNoModeSwitching.Create(ADisplay : PDisplay; AScreen : cint);
  7. Begin
  8. Inherited;
  9. FWidth := DisplayWidth(FDisplay, FScreen);
  10. FHeight := DisplayHeight(FDisplay, FScreen);
  11. End;
  12. Procedure TX11ModesNoModeSwitching.GetModes(Var AModes : TPTCModeDynArray; ACurrentDesktopFormat : TPTCFormat);
  13. Begin
  14. SetLength(AModes, 2);
  15. AModes[0] := TPTCMode.Create(FWidth,
  16. FHeight,
  17. ACurrentDesktopFormat);
  18. AModes[1] := TPTCMode.Create;
  19. End;
  20. Procedure TX11ModesNoModeSwitching.SetBestMode(AWidth, AHeight : Integer);
  21. Begin
  22. FWidth := DisplayWidth(FDisplay, FScreen);
  23. FHeight := DisplayHeight(FDisplay, FScreen);
  24. End;
  25. Procedure TX11ModesNoModeSwitching.RestorePreviousMode;
  26. Begin
  27. { do nothing }
  28. End;
  29. Function TX11ModesNoModeSwitching.GetWidth : Integer;
  30. Begin
  31. Result := FWidth;
  32. End;
  33. Function TX11ModesNoModeSwitching.GetHeight : Integer;
  34. Begin
  35. Result := FHeight;
  36. End;
  37. {$IFDEF ENABLE_X11_EXTENSION_XRANDR}
  38. Constructor TX11ModesXrandr.Create(ADisplay : PDisplay; AScreen : cint);
  39. Var
  40. dummy1, dummy2 : cint;
  41. Major, Minor : cint;
  42. Begin
  43. Inherited;
  44. If Not XRRQueryExtension(FDisplay, @dummy1, @dummy2) Then
  45. Raise TPTCError.Create('Xrandr extension not available');
  46. XRRQueryVersion(FDisplay, @Major, @Minor); // todo: check
  47. LOG('Xrandr version: ' + IntToStr(Major) + '.' + IntToStr(Minor));
  48. FRoot := RootWindow(FDisplay, FScreen);
  49. FXRRConfig := XRRGetScreenInfo(FDisplay, FRoot);
  50. If FXRRConfig = Nil Then
  51. Raise TPTCError.Create('XRRGetScreenInfo failed');
  52. Raise TPTCError.Create('Xrandr mode switcher is not yet implemented...');
  53. End;
  54. Destructor TX11ModesXrandr.Destroy;
  55. Begin
  56. If FXRRConfig <> Nil Then
  57. XRRFreeScreenConfigInfo(FXRRConfig);
  58. Inherited;
  59. End;
  60. Procedure TX11ModesXrandr.GetModes(Var AModes : TPTCModeDynArray; ACurrentDesktopFormat : TPTCFormat);
  61. Begin
  62. {...}
  63. End;
  64. Procedure TX11ModesXrandr.SetBestMode(AWidth, AHeight : Integer);
  65. Begin
  66. {todo...}
  67. End;
  68. Procedure TX11ModesXrandr.RestorePreviousMode;
  69. Begin
  70. {todo...}
  71. End;
  72. Function TX11ModesXrandr.GetWidth : Integer;
  73. Begin
  74. // todo...
  75. End;
  76. Function TX11ModesXrandr.GetHeight : Integer;
  77. Begin
  78. // todo...
  79. End;
  80. {$ENDIF ENABLE_X11_EXTENSION_XRANDR}
  81. {$IFDEF ENABLE_X11_EXTENSION_XF86VIDMODE}
  82. Constructor TX11ModesXF86VidMode.Create(ADisplay : PDisplay; AScreen : Integer);
  83. Var
  84. dummy1, dummy2 : cint;
  85. Begin
  86. Inherited;
  87. FSavedMode := Nil;
  88. FSavedDotClock := 0;
  89. FModeList := Nil;
  90. FModeListCount := 0;
  91. If Not XF86VidModeQueryExtension(FDisplay, @dummy1, @dummy2) Then
  92. Raise TPTCError.Create('VidMode extension not available');
  93. End;
  94. Destructor TX11ModesXF86VidMode.Destroy;
  95. Begin
  96. If FSavedMode <> Nil Then
  97. Begin
  98. RestorePreviousMode;
  99. If FSavedMode^.privsize <> 0 Then
  100. XFree(FSavedMode^.c_private);
  101. Dispose(FSavedMode);
  102. End;
  103. If FModeList <> Nil Then
  104. XFree(FModeList);
  105. Inherited Destroy;
  106. End;
  107. {todo: move the saving of the previous mode to a separate function...}
  108. Procedure TX11ModesXF86VidMode.RetrieveModeList;
  109. Begin
  110. { If we have been called before, do nothing }
  111. If FModeList <> Nil Then
  112. Exit;
  113. { Save previous mode }
  114. New(FSavedMode);
  115. FillChar(FSavedMode^, SizeOf(FSavedMode^), 0);
  116. XF86VidModeGetModeLine(FDisplay, FScreen, @FSavedDotClock, FSavedMode);
  117. { Get all available video modes }
  118. XF86VidModeGetAllModeLines(FDisplay, FScreen, @FModeListCount, @FModeList);
  119. End;
  120. Procedure TX11ModesXF86VidMode.GetModes(Var AModes : TPTCModeDynArray; ACurrentDesktopFormat : TPTCFormat);
  121. Var
  122. I : Integer;
  123. Begin
  124. RetrieveModeList;
  125. SetLength(AModes, FModeListCount + 1);
  126. AModes[FModeListCount] := TPTCMode.Create;
  127. For I := 0 To FModeListCount - 1 Do
  128. AModes[I] := TPTCMode.Create(FModeList[I]^.hdisplay, FModeList[I]^.vdisplay, ACurrentDesktopFormat);
  129. End;
  130. Function TX11ModesXF86VidMode.FindNumberOfBestMode(AWidth, AHeight : Integer) : Integer;
  131. Var
  132. min_diff : Integer;
  133. d_x, d_y : Integer;
  134. found_mode : Integer;
  135. I : Integer;
  136. Begin
  137. { Try an exact match }
  138. For I := 0 To FModeListCount - 1 Do
  139. If (FModeList[I]^.hdisplay = AWidth) And (FModeList[I]^.vdisplay = AHeight) Then
  140. Exit(I);
  141. { Try to find a mode that matches the width first }
  142. For I := 0 To FModeListCount - 1 Do
  143. If (FModeList[I]^.hdisplay = AWidth) And (FModeList[I]^.vdisplay >= AHeight) Then
  144. Exit(I);
  145. { Next try to match the height }
  146. For I := 0 To FModeListCount - 1 Do
  147. If (FModeList[I]^.hdisplay >= AWidth) And (FModeList[I]^.vdisplay = AHeight) Then
  148. Exit(I);
  149. { Finally, find the mode that is bigger than the requested one and makes }
  150. { the least difference }
  151. found_mode := -1;
  152. min_diff := High(Integer);
  153. For I := 0 To FModeListCount - 1 Do
  154. If (FModeList[I]^.hdisplay >= AWidth) And (FModeList[I]^.vdisplay >= AHeight) Then
  155. Begin
  156. d_x := Sqr(FModeList[I]^.hdisplay - AWidth);
  157. d_y := Sqr(FModeList[I]^.vdisplay - AHeight);
  158. If (d_x + d_y) < min_diff Then
  159. Begin
  160. min_diff := d_x + d_y;
  161. found_mode := I;
  162. End;
  163. End;
  164. If found_mode <> -1 Then
  165. Result := found_mode
  166. Else
  167. Raise TPTCError.Create('Cannot find matching video mode');
  168. End;
  169. Procedure TX11ModesXF86VidMode.SetBestMode(AWidth, AHeight : Integer);
  170. Var
  171. BestMode : Integer;
  172. Begin
  173. RetrieveModeList;
  174. BestMode := FindNumberOfBestMode(AWidth, AHeight);
  175. If Not XF86VidModeSwitchToMode(FDisplay, FScreen, FModeList[BestMode]) Then
  176. Raise TPTCError.Create('Error switching to the requested video mode');
  177. FWidth := FModeList[BestMode]^.hdisplay;
  178. FHeight := FModeList[BestMode]^.vdisplay;
  179. XWarpPointer(FDisplay, None, RootWindow(FDisplay, FScreen), 0, 0, 0, 0,
  180. FWidth Div 2,
  181. FHeight Div 2);
  182. If Not XF86VidModeSetViewPort(FDisplay, FScreen, 0, 0) Then
  183. Raise TPTCError.Create('Error moving the viewport to the upper-left corner');
  184. End;
  185. Procedure TX11ModesXF86VidMode.RestorePreviousMode;
  186. Var
  187. ModeInfo : TXF86VidModeModeInfo;
  188. Begin
  189. If FSavedMode <> Nil Then
  190. Begin
  191. {FSavedMode is a TXF86VidModeModeLine, but XF86VidModeSwitchToMode wants a
  192. TXF86VidModeModeInfo :}
  193. FillChar(ModeInfo, SizeOf(ModeInfo), 0);
  194. ModeInfo.dotclock := FSavedDotClock;
  195. ModeInfo.hdisplay := FSavedMode^.hdisplay;
  196. ModeInfo.hsyncstart := FSavedMode^.hsyncstart;
  197. ModeInfo.hsyncend := FSavedMode^.hsyncend;
  198. ModeInfo.htotal := FSavedMode^.htotal;
  199. ModeInfo.vdisplay := FSavedMode^.vdisplay;
  200. ModeInfo.vsyncstart := FSavedMode^.vsyncstart;
  201. ModeInfo.vsyncend := FSavedMode^.vsyncend;
  202. ModeInfo.vtotal := FSavedMode^.vtotal;
  203. ModeInfo.flags := FSavedMode^.flags;
  204. ModeInfo.privsize := FSavedMode^.privsize;
  205. ModeInfo.c_private := FSavedMode^.c_private;
  206. XF86VidModeSwitchToMode(FDisplay, FScreen, @ModeInfo);
  207. End;
  208. End;
  209. Function TX11ModesXF86VidMode.GetWidth : Integer;
  210. Begin
  211. Result := FWidth;
  212. End;
  213. Function TX11ModesXF86VidMode.GetHeight : Integer;
  214. Begin
  215. Result := FHeight;
  216. End;
  217. {$ENDIF ENABLE_X11_EXTENSION_XF86VIDMODE}