Forum > BGRABitmap and LazPaint

How to get xlib's window icon using BGRABitmap?

(1/3) > >>

AFFRIZA 亜風実:
So, long story short, I'm interested to make my own docked taskbar for KDE :-[

I tried to C++ mimic code from here to read the icon: https://stackoverflow.com/questions/55413341/get-applications-icon-using-xlib

and the result is like this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var  bmp: TBGRABitmap;  a, r, g, b: byte;  argb: PByte;  x, y: Integer;begin  bmp := TBGRABitmap.Create(w, h);  argb := Val;  for y := 0 to H -1 do  begin    for x := 0 to W -1 do    begin      a := argb[3];      r := argb[2] * a div 255;      g := argb[1] * a div 255;      b := argb[0] * a div 255;      //bmp.Canvas.DrawPixel(x, y, FPImage.FPColor(r, g, b, a));      bmp.DrawPixel(x, y, BGRA(r, g, b, a));       Inc(argb, 4);    end;  end;   Result := bmp;end; function TWindowData.GetIcon: TBGRABitmap;var  ActualTypeReturn: TAtom;  ActualFormatReturn: LongInt;  NItemsReturn, BytesAfterReturn: Cardinal;  Ptr: PByte;  IconAtom: TAtom;  PropResult: boolean;  i: integer;  Width, Height, Size: Cardinal;begin  Width := 0;  Height := 0;  IconAtom := XInternAtom(fXWindowList.Display, '_NET_WM_ICON', LongBool(1));   PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom,    0, 1, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn,    @NItemsReturn, @BytesAfterReturn, @Ptr) = Success;  if PropResult then    Width := PCardinal(Ptr)^;  if Assigned(Ptr) then XFree(Ptr);   PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom,    1, 1, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn,    @NItemsReturn, @BytesAfterReturn, @Ptr) = Success;  if PropResult then    Height := PCardinal(Ptr)^;  Size := Width * Height;  if Assigned(Ptr) then XFree(Ptr);   PropResult := XGetWindowProperty(fXWindowList.Display, fWindow, IconAtom,    2, Size, 0, AnyPropertyType, @ActualTypeReturn, @ActualFormatReturn,    @NItemsReturn, @BytesAfterReturn, @Ptr) = Success;   if PropResult then  begin    Result := ReadBitmap(Ptr, Width, Height, Size);  end;  if Assigned(Ptr) then XFree(Ptr);end; 
The icons is kind of broken in the result (in the attachment). Maybe someone can help?  :D

I really want to attach the full source but it's become big, so I put that in a Github:
https://github.com/kirana-a2district/samarinda-dock
https://github.com/kirana-a2district/kiranacore-pkg

AFFRIZA 亜風実:
I just modified the code to:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var  bmp: TBGRABitmap;  a, r, g, b: byte;  argb: PByte;  i, f, x, y: Integer;  imgBuffer: TBytes;begin  bmp := TBGRABitmap.Create(w, h);  SetLength(imgBuffer, Length(TBytes(Val)) div 2);  argb := PByte(imgBuffer);  i := 0;  while i < Length(TBytes(Val)) div 2 do  begin    argb[i] := Val[(i*2)];    argb[i+1] := Val[(i*2)+1];    argb[i+2] := Val[(i*2)+2];    argb[i+3] := Val[(i*2)+3];    i += 4;  end;  for y := 0 to H -1 do  begin    for x := 0 to W -1 do    begin      a := argb[3];      r := argb[2];      g := argb[1];      b := argb[0];      //bmp.Canvas.DrawPixel(x, y, FPImage.FPColor(r, g, b, a));      bmp.DrawPixel(x, y, BGRA(r, g, b, a));       Inc(argb, 4);    end;  end;   Result := bmp;end; 
The colors is much better now  :D
But the icons are still has distortion thingy  %)

Roland57:
Hello! Very interesting stuff.

Unfortunately, I get an access violation at application start. (I had to remove the reference to qt5 unit. My Lazarus is gtk2.)

AFFRIZA 亜風実:

--- Quote from: Roland57 on June 14, 2022, 05:44:19 pm ---Hello! Very interesting stuff.

Unfortunately, I get an access violation at application start. (I had to remove the reference to qt5 unit. My Lazarus is gtk2.)

--- End quote ---
Sorry but it supposed to run under Qt5, since I wrote this for KDE, and also... I need the Qt5's translucent window thing to make the form transparent without affecting the components inside.

If you want, maybe I can help you to setup the Lazarus to run with Qt5.  :D

circular:
Ok so each pixel is represented by 8 bytes. Well 4 bytes padded with 4 more bytes if the CPU is 64bits.

First version was almost correct except step between values.

I suppose the following would work as well:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function ReadBitmap(Val: PByte; W, H, Size: integer): TBGRABitmap;var  bmp: TBGRABitmap;  argb: PByte;  pdest: PBGRAPixel;  x, y: Integer;begin  bmp := TBGRABitmap.Create(w, h);  argb := Val;  for y := 0 to H -1 do  begin    pdest := bmp.ScanLine[y];    for x := 0 to W -1 do    begin      pdest^.alpha := argb[3];      pdest^.red := argb[2];      pdest^.green := argb[1];      pdest^.blue := argb[0];       Inc(argb, {$IFDEF CPU64}8{$ELSE}4{$ENDIF});      inc(pdest);    end;  end;  bmp.InvalidateBitmap;  Result := bmp;end;
I am not sure about the distortion but maybe you can assume that alpha is in fact 255 when alpha is zero and red/green/blue are non zero.

Navigation

[0] Message Index

[#] Next page

Go to full version