x11imagei.inc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. Const
  2. {$WARNING this belongs to the ipc unit}
  3. IPC_PRIVATE = 0;
  4. Constructor TX11Image.Create(ADisplay : PDisplay; AScreen, AWidth, AHeight : Integer; AFormat : TPTCFormat);
  5. Begin
  6. FWidth := AWidth;
  7. FHeight := AHeight;
  8. FDisplay := ADisplay;
  9. End;
  10. Constructor TX11NormalImage.Create(ADisplay : PDisplay; AScreen, AWidth, AHeight : Integer; AFormat : TPTCFormat);
  11. Var
  12. xpad, xpitch : Integer;
  13. tmp_FPixels : PChar;
  14. Begin
  15. Inherited;
  16. xpad := AFormat.Bits;
  17. If AFormat.Bits = 24 Then
  18. xpad := 32;
  19. xpitch := AWidth * AFormat.Bits Div 8;
  20. Inc(xpitch, 3);
  21. xpitch := xpitch And (Not 3);
  22. FPixels := GetMem(xpitch * AHeight);
  23. Pointer(tmp_FPixels) := Pointer(FPixels);
  24. FImage := XCreateImage(ADisplay, DefaultVisual(ADisplay, AScreen),
  25. DefaultDepth(ADisplay, AScreen),
  26. ZPixmap, 0, tmp_FPixels,
  27. AWidth, AHeight, xpad, 0);
  28. If FImage = Nil Then
  29. Raise TPTCError.Create('cannot create XImage');
  30. End;
  31. Destructor TX11NormalImage.Destroy;
  32. Begin
  33. If FImage <> Nil Then
  34. Begin
  35. { Restore XImage's buffer pointer }
  36. FImage^.data := Nil;
  37. XDestroyImage(FImage);
  38. End;
  39. If FPixels <> Nil Then
  40. FreeMem(FPixels);
  41. Inherited Destroy;
  42. End;
  43. Procedure TX11NormalImage.Put(AWindow : TWindow; AGC : TGC; AX, AY : Integer);
  44. Begin
  45. XPutImage(FDisplay, AWindow, AGC, FImage, 0, 0, AX, AY, FWidth, FHeight);
  46. XSync(FDisplay, False);
  47. End;
  48. Procedure TX11NormalImage.Put(AWindow : TWindow; AGC : TGC; ASX, ASY, ADX, ADY,
  49. AWidth, AHeight : Integer);
  50. Begin
  51. XPutImage(FDisplay, AWindow, AGC, FImage, ASX, ASY, ADX, ADY, AWidth, AHeight);
  52. XSync(FDisplay, False);
  53. End;
  54. Function TX11NormalImage.Lock : Pointer;
  55. Begin
  56. Result := FPixels;
  57. End;
  58. Function TX11NormalImage.Pitch : Integer;
  59. Begin
  60. Result := FImage^.bytes_per_line;
  61. End;
  62. Function TX11NormalImage.Name : String;
  63. Begin
  64. Result := 'XImage';
  65. End;
  66. {$IFDEF ENABLE_X11_EXTENSION_XSHM}
  67. Var
  68. Fshm_error : Boolean;
  69. Fshm_oldhandler : Function(disp : PDisplay; xev : PXErrorEvent) : Integer; CDecl;
  70. Function Fshm_errorhandler(disp : PDisplay; xev : PXErrorEvent) : Integer; CDecl;
  71. Begin
  72. If xev^.error_code=BadAccess Then
  73. Begin
  74. Fshm_error := True;
  75. Result := 0;
  76. End
  77. Else
  78. Result := Fshm_oldhandler(disp, xev);
  79. End;
  80. Constructor TX11ShmImage.Create(ADisplay : PDisplay; AScreen, AWidth, AHeight : Integer; AFormat : TPTCFormat);
  81. Begin
  82. Inherited;
  83. FShmInfo.shmid := -1;
  84. FShmInfo.shmaddr := Pointer(-1);
  85. FImage := XShmCreateImage(ADisplay, DefaultVisual(ADisplay, AScreen),
  86. DefaultDepth(ADisplay, AScreen),
  87. ZPixmap, Nil, @FShmInfo, AWidth, AHeight);
  88. If FImage = Nil Then
  89. Raise TPTCError.Create('cannot create SHM image');
  90. FShmInfo.shmid := shmget(IPC_PRIVATE, FImage^.bytes_per_line * FImage^.height,
  91. IPC_CREAT Or &777);
  92. If FShmInfo.shmid = -1 Then
  93. Raise TPTCError.Create('cannot get shared memory segment');
  94. FShmInfo.shmaddr := shmat(FShmInfo.shmid, Nil, 0);
  95. FShmInfo.readOnly := False;
  96. FImage^.data := FShmInfo.shmaddr;
  97. If Pointer(FShmInfo.shmaddr) = Pointer(-1) Then
  98. Raise TPTCError.Create('cannot allocate shared memory');
  99. // Try and attach the segment to the server. Bugfix: Have to catch
  100. // bad access errors in case it runs over the net.
  101. Fshm_error := False;
  102. Fshm_oldhandler := XSetErrorHandler(@Fshm_errorhandler);
  103. Try
  104. If XShmAttach(ADisplay, @FShmInfo) = 0 Then
  105. Raise TPTCError.Create('cannot attach shared memory segment to display');
  106. XSync(ADisplay, False);
  107. If Fshm_error Then
  108. Raise TPTCError.Create('cannot attach shared memory segment to display');
  109. FShmAttached := True;
  110. Finally
  111. XSetErrorHandler(Fshm_oldhandler);
  112. End;
  113. End;
  114. Destructor TX11ShmImage.Destroy;
  115. Begin
  116. If FShmAttached Then
  117. Begin
  118. XShmDetach(FDisplay, @FShmInfo);
  119. XSync(FDisplay, False);
  120. End;
  121. If FImage <> Nil Then
  122. XDestroyImage(FImage);
  123. If Pointer(FShmInfo.shmaddr) <> Pointer(-1) Then
  124. shmdt(FShmInfo.shmaddr);
  125. If FShmInfo.shmid <> -1 Then
  126. shmctl(FShmInfo.shmid, IPC_RMID, Nil);
  127. Inherited Destroy;
  128. End;
  129. Procedure TX11ShmImage.Put(AWindow : TWindow; AGC : TGC; AX, AY : Integer);
  130. Begin
  131. XShmPutImage(FDisplay, AWindow, AGC, FImage, 0, 0, AX, AY, FWidth, FHeight, False);
  132. XSync(FDisplay, False);
  133. End;
  134. Procedure TX11ShmImage.Put(AWindow : TWindow; AGC : TGC; ASX, ASY, ADX, ADY,
  135. AWidth, AHeight : Integer);
  136. Begin
  137. XShmPutImage(FDisplay, AWindow, AGC, FImage, ASX, ASY, ADX, ADY, FWidth, FHeight, False);
  138. XSync(FDisplay, False);
  139. End;
  140. Function TX11ShmImage.Lock : Pointer;
  141. Begin
  142. Result := Pointer(FShmInfo.shmaddr);
  143. End;
  144. Function TX11ShmImage.Pitch : Integer;
  145. Begin
  146. Result := FImage^.bytes_per_line;
  147. End;
  148. Function TX11ShmImage.Name : String;
  149. Begin
  150. Result := 'MIT-Shm';
  151. End;
  152. {$ENDIF ENABLE_X11_EXTENSION_XSHM}