x11dga2displayi.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. {$IFDEF ENABLE_X11_EXTENSION_XF86DGA2}
  2. Constructor TX11DGA2Display.Create(ADisplay : PDisplay; AScreen : Integer; Const AFlags : TX11Flags);
  3. Var
  4. dummy1, dummy2 : cint;
  5. Begin
  6. Inherited;
  7. LOG('trying to open a DGA 2.0 display');
  8. { Check if the DGA extension can be used }
  9. LOG('checking if the DGA extension can be used (XDGAQueryExtension)');
  10. If Not XDGAQueryExtension(FDisplay, @dummy1, @dummy2) Then
  11. Raise TPTCError.Create('DGA extension not available');
  12. End;
  13. Destructor TX11DGA2Display.Destroy;
  14. Begin
  15. Close;
  16. Inherited Destroy;
  17. End;
  18. Procedure TX11DGA2Display.open(title : String; _width, _height : Integer; Const _format : TPTCFormat);
  19. Var
  20. vml : PXF86VidModeModeLine;
  21. dotclock : Integer;
  22. i : Integer;
  23. found : Boolean;
  24. root : TWindow;
  25. e : TXEvent;
  26. tmpArea : TPTCArea;
  27. r, g, b : Single;
  28. found_mode : Integer;
  29. min_diff : Integer;
  30. d_x, d_y : Integer;
  31. Begin
  32. FWidth := _width;
  33. FHeight := _height;
  34. LOG('trying to open framebuffer (XDGAOpenFramebuffer)');
  35. If Not XDGAOpenFramebuffer(FDisplay, FScreen) Then
  36. Raise TPTCError.Create('Cannot open framebuffer - insufficient privileges?');
  37. FFramebufferIsOpen := True;
  38. { Get all availabe video modes }
  39. LOG('querying available display modes (XDGAQueryModes)');
  40. FXDGAModes := XDGAQueryModes(FDisplay, FScreen, @FXDGAModesNum);
  41. LOG('number of display modes', FXDGAModesNum);
  42. For I := 0 To FXDGAModesNum - 1 Do
  43. Begin
  44. LOG('mode#', I);
  45. LOG('num', FXDGAModes[I].num);
  46. LOG('name: ' + FXDGAModes[I].name);
  47. End;
  48. found_mode := 0; // todo: find a video mode
  49. Raise TPTCError.Create('break! dga 2.0 code unfinished');
  50. FXDGADevice := XDGASetMode(FDisplay, FScreen, found_mode);
  51. If FXDGADevice = Nil Then
  52. Raise TPTCError.Create('XDGASetMode failed (returned nil)');
  53. If FXDGADevice^.data = Nil Then
  54. Raise TPTCError.Create('The pointer to the framebuffer, returned by XDGA is nil?!');
  55. FModeIsSet := True;
  56. { Check if the requested colour mode is available }
  57. FFormat := GetX11Format(_format);
  58. { Grab exclusive control over the keyboard and mouse }
  59. { root := XRootWindow(FDisplay, FScreen);
  60. XGrabKeyboard(FDisplay, root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
  61. XGrabPointer(FDisplay, root, True, PointerMotionMask Or ButtonPressMask Or
  62. ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None,
  63. CurrentTime);}
  64. XFlush(FDisplay);
  65. { Get Display information }
  66. { XF86DGAGetVideo(FDisplay, FScreen, @dga_addr, @dga_linewidth,
  67. @dga_banksize, @dga_memsize);}
  68. { Don't have to be root anymore }
  69. { setuid(getuid);...}
  70. // XF86DGAGetViewPortSize(FDisplay, FScreen, @dga_width, @dga_height);
  71. { If XF86DGAForkApp(FScreen) <> 0 Then
  72. Raise TPTCError.Create('cannot do safety fork')
  73. Else
  74. Begin
  75. If XF86DGADirectVideo(FDisplay, FScreen, XF86DGADirectGraphics Or
  76. XF86DGADirectKeyb Or XF86DGADirectMouse) = 0 Then
  77. Raise TPTCError.Create('cannot switch to DGA mode');
  78. End;}
  79. // m_indirect := True;
  80. // FillChar(dga_addr^, dga_linewidth * dga_height * (FFormat.bits Div 8), 0);
  81. XSelectInput(FDisplay, DefaultRootWindow(FDisplay),
  82. KeyPressMask Or KeyReleaseMask);
  83. XF86DGASetViewPort(FDisplay, FScreen, 0, 0); { Important.. sort of =) }
  84. found := False;
  85. Repeat
  86. { Stupid loop. The key }
  87. { events were causing }
  88. { problems.. }
  89. found := XCheckMaskEvent(FDisplay, KeyPressMask Or KeyReleaseMask, @e);
  90. Until Not found;
  91. { Create colour map in 8 bit mode }
  92. If FFormat.bits = 8 Then
  93. Begin
  94. FColours := GetMem(256 * SizeOf(TXColor));
  95. If FColours = Nil Then
  96. Raise TPTCError.Create('Cannot allocate colour map cells');
  97. FCMap := XCreateColormap(FDisplay, RootWindow(FDisplay, FScreen),
  98. DefaultVisual(FDisplay, FScreen), AllocAll);
  99. If FCMap = 0 Then
  100. Raise TPTCError.Create('Cannot create colour map');
  101. End
  102. Else
  103. FCMap := 0;
  104. { Set 332 palette, for now }
  105. If (FFormat.bits = 8) And FFormat.direct Then
  106. Begin
  107. {Taken from PTC 0.72, i hope it's fine}
  108. For i := 0 To 255 Do
  109. Begin
  110. r := ((i And $E0) Shr 5) * 255 / 7;
  111. g := ((i And $1C) Shr 2) * 255 / 7;
  112. b := (i And $03) * 255 / 3;
  113. FColours[i].pixel := i;
  114. FColours[i].red := Round(r) Shl 8;
  115. FColours[i].green := Round(g) Shl 8;
  116. FColours[i].blue := Round(b) Shl 8;
  117. Byte(FColours[i].flags) := DoRed Or DoGreen Or DoBlue;
  118. End;
  119. XStoreColors(FDisplay, FCMap, FColours, 256);
  120. XF86DGAInstallColormap(FDisplay, FScreen, FCMap);
  121. End;
  122. { Set clipping area }
  123. tmpArea := TPTCArea.Create(0, 0, FWidth, FHeight);
  124. Try
  125. FClip.Assign(tmpArea);
  126. Finally
  127. tmpArea.Free;
  128. End;
  129. End;
  130. { Not in DGA mode }
  131. Procedure TX11DGA2Display.open(w : TWindow; Const _format : TPTCFormat);
  132. Begin
  133. If w = 0 Then; { Prevent warnings }
  134. If _format = Nil Then;
  135. End;
  136. Procedure TX11DGA2Display.open(_window : TWindow; Const _format : TPTCFormat; x, y, w, h : Integer);
  137. Begin
  138. If (_window = 0) Or (_format = Nil) Or (x = 0) Or
  139. (y = 0) Or (w = 0) Or (h = 0) Then;
  140. End;
  141. Procedure TX11DGA2Display.close;
  142. Var
  143. tmp : Pointer;
  144. Begin
  145. If FModeIsSet Then
  146. Begin
  147. FModeIsSet := False;
  148. { restore the original mode }
  149. XDGASetMode(FDisplay, FScreen, 0); { returns PXDGADevice }
  150. { XUngrabKeyboard(FDisplay, CurrentTime);
  151. XUngrabPointer(FDisplay, CurrentTime);}
  152. End;
  153. If FFramebufferIsOpen Then
  154. Begin
  155. FFramebufferIsOpen := False;
  156. XDGACloseFramebuffer(FDisplay, FScreen);
  157. End;
  158. If FDisplay <> Nil Then
  159. XFlush(FDisplay);
  160. If FCMap <> 0 Then
  161. Begin
  162. XFreeColormap(FDisplay, FCMap);
  163. FCMap := 0;
  164. End;
  165. FreeMemAndNil(FColours);
  166. If FXDGADevice <> Nil Then
  167. Begin
  168. tmp := FXDGADevice;
  169. FXDGADevice := Nil;
  170. XFree(tmp);
  171. End;
  172. If FXDGAModes <> Nil Then
  173. Begin
  174. tmp := FXDGAModes;
  175. FXDGAModes := Nil;
  176. XFree(tmp);
  177. End;
  178. End;
  179. Procedure TX11DGA2Display.GetModes(Var AModes : TPTCModeDynArray);
  180. Begin
  181. SetLength(AModes, 1);
  182. AModes[0] := TPTCMode.Create;
  183. {todo...}
  184. End;
  185. Procedure TX11DGA2Display.update;
  186. Begin
  187. End;
  188. Procedure TX11DGA2Display.update(Const _area : TPTCArea);
  189. Begin
  190. End;
  191. Procedure TX11DGA2Display.HandleEvents;
  192. Var
  193. e : TXEvent;
  194. NewFocus : Boolean;
  195. NewFocusSpecified : Boolean;
  196. Function UsefulEventsPending : Boolean;
  197. Var
  198. tmpEvent : TXEvent;
  199. Begin
  200. If XCheckTypedEvent(FDisplay, ClientMessage, @tmpEvent) Then
  201. Begin
  202. Result := True;
  203. XPutBackEvent(FDisplay, @tmpEvent);
  204. Exit;
  205. End;
  206. If XCheckMaskEvent(FDisplay, FocusChangeMask Or
  207. KeyPressMask Or KeyReleaseMask Or
  208. ButtonPressMask Or ButtonReleaseMask Or
  209. PointerMotionMask Or ExposureMask, @tmpEvent) Then
  210. Begin
  211. Result := True;
  212. XPutBackEvent(FDisplay, @tmpEvent);
  213. Exit;
  214. End;
  215. Result := False;
  216. End;
  217. Procedure HandleKeyEvent;
  218. Var
  219. sym : TKeySym;
  220. sym_modded : TKeySym; { modifiers like shift are taken into account here }
  221. press : Boolean;
  222. alt, shift, ctrl : Boolean;
  223. uni : Integer;
  224. key : TPTCKeyEvent;
  225. buf : Array[1..16] Of Char;
  226. Begin
  227. sym := XLookupKeySym(@e.xkey, 0);
  228. XLookupString(@e.xkey, @buf, SizeOf(buf), @sym_modded, Nil);
  229. uni := X11ConvertKeySymToUnicode(sym_modded);
  230. alt := (e.xkey.state And Mod1Mask) <> 0;
  231. shift := (e.xkey.state And ShiftMask) <> 0;
  232. ctrl := (e.xkey.state And ControlMask) <> 0;
  233. If e._type = KeyPress Then
  234. press := True
  235. Else
  236. press := False;
  237. key := Nil;
  238. Case sym Shr 8 Of
  239. 0 : key := TPTCKeyEvent.Create(FNormalKeys[sym And $FF], uni, alt, shift, ctrl, press);
  240. $FF : key := TPTCKeyEvent.Create(FFunctionKeys[sym And $FF], uni, alt, shift, ctrl, press);
  241. Else
  242. key := TPTCKeyEvent.Create;
  243. End;
  244. FEventQueue.AddEvent(key);
  245. End;
  246. Begin
  247. NewFocusSpecified := False;
  248. While UsefulEventsPending Do
  249. Begin
  250. XNextEvent(FDisplay, @e);
  251. Case e._type Of
  252. FocusIn : Begin
  253. NewFocus := True;
  254. NewFocusSpecified := True;
  255. End;
  256. FocusOut : Begin
  257. NewFocus := False;
  258. NewFocusSpecified := True;
  259. End;
  260. ClientMessage : Begin
  261. { If (e.xclient.format = 32) And (TAtom(e.xclient.data.l[0]) = m_atom_close) Then
  262. Halt(0);}
  263. End;
  264. Expose : Begin
  265. {...}
  266. End;
  267. KeyPress, KeyRelease : HandleKeyEvent;
  268. ButtonPress, ButtonRelease : Begin
  269. {...}
  270. End;
  271. MotionNotify : Begin
  272. {...}
  273. End;
  274. End;
  275. End;
  276. // HandleChangeFocus(NewFocus);
  277. End;
  278. Function TX11DGA2Display.NextEvent(Var event : TPTCEvent; wait : Boolean; Const EventMask : TPTCEventMask) : Boolean;
  279. Var
  280. tmpEvent : TXEvent;
  281. Begin
  282. FreeAndNil(event);
  283. Repeat
  284. { process all events from the X queue and put them on our FEventQueue }
  285. HandleEvents;
  286. { try to find an event that matches the EventMask }
  287. event := FEventQueue.NextEvent(EventMask);
  288. If wait And (event = Nil) Then
  289. Begin
  290. { if the X event queue is empty, block until an event is received }
  291. XPeekEvent(FDisplay, @tmpEvent);
  292. End;
  293. Until (Not Wait) Or (event <> Nil);
  294. Result := event <> Nil;
  295. End;
  296. Function TX11DGA2Display.PeekEvent(wait : Boolean; Const EventMask : TPTCEventMask) : TPTCEvent;
  297. Var
  298. tmpEvent : TXEvent;
  299. Begin
  300. Repeat
  301. { process all events from the X queue and put them on our FEventQueue }
  302. HandleEvents;
  303. { try to find an event that matches the EventMask }
  304. Result := FEventQueue.PeekEvent(EventMask);
  305. If wait And (Result = Nil) Then
  306. Begin
  307. { if the X event queue is empty, block until an event is received }
  308. XPeekEvent(FDisplay, @tmpEvent);
  309. End;
  310. Until (Not Wait) Or (Result <> Nil);
  311. End;
  312. Function TX11DGA2Display.lock : Pointer;
  313. Begin
  314. lock := PByte(FXDGADevice^.data) +
  315. FXDGADevice^.mode.bytesPerScanline * m_desty +
  316. m_destx * (FXDGADevice^.mode.bitsPerPixel Div 8);
  317. End;
  318. Procedure TX11DGA2Display.unlock;
  319. Begin
  320. End;
  321. Procedure TX11DGA2Display.palette(Const _palette : TPTCPalette);
  322. Var
  323. pal : PUint32;
  324. i : Integer;
  325. Begin
  326. pal := _palette.data;
  327. If Not FFormat.indexed Then
  328. Exit;
  329. For i := 0 To 255 Do
  330. Begin
  331. FColours[i].pixel := i;
  332. FColours[i].red := ((pal[i] Shr 16) And $FF) Shl 8;
  333. FColours[i].green := ((pal[i] Shr 8) And $FF) Shl 8;
  334. FColours[i].blue := (pal[i] And $FF) Shl 8;
  335. Byte(FColours[i].flags) := DoRed Or DoGreen Or DoBlue;
  336. End;
  337. XStoreColors(FDisplay, FCMap, FColours, 256);
  338. XF86DGAInstallColormap(FDisplay, FScreen, FCMap);
  339. End;
  340. Function TX11DGA2Display.GetPitch : Integer;
  341. Begin
  342. Result := FXDGADevice^.mode.bytesPerScanline;
  343. End;
  344. Function TX11DGA2Display.getX11Window : TWindow;
  345. Begin
  346. Result := DefaultRootWindow(FDisplay);
  347. End;
  348. Function TX11DGA2Display.isFullScreen : Boolean;
  349. Begin
  350. { DGA is always fullscreen }
  351. Result := True;
  352. End;
  353. Procedure TX11DGA2Display.SetCursor(visible : Boolean);
  354. Begin
  355. {nothing... raise exception if visible=true?}
  356. End;
  357. {$ENDIF ENABLE_X11_EXTENSION_XF86DGA2}