* Source/x11/XGServerWindow.m (_createNetIcon:result:size:): fixed

off-by-one mistake during alpha handling. Enable disabled code and
  remove temprorary one.
  (window::::): set NetWM icon to window for all EWMH capable WMs even
  it's WindowMaker.
  (image_mask): new function to create alpha mask for image. It's based
  on xgps_cursor_mask() code with additional argument `alpha_treshold`.
  This function may be used for images (alpha_treshold == 0) with real
  alpha mask and for cursors (if no Xcursor library is used - no alpha
  is used, no shadows in cursors, alpha_treshold == 158 is used to cut
  transparent pixels).
  (_createAppIconPixmaps): icon pixmap creation rewritten to support
  images with alpha channel using wraster functions. Use image_mask().
  (restrictWindow:toImage:): use image_mask() instead of
  xgps_cursor_mask().
  (xgps_cursor_mask): removed as image_mask() replaced it.
  Guard xgps_cursor_image( with #if - will not be compiled if Xcursor
  is used.
  (imagecursor:::): use image_mask() instead of xgps_cursor_mask().
This commit is contained in:
Sergii Stoian 2020-01-13 01:34:11 +02:00
parent de86246567
commit 528660834c
2 changed files with 117 additions and 106 deletions

View file

@ -1,3 +1,25 @@
2020-01-13 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_createNetIcon:result:size:): fixed
off-by-one mistake during alpha handling. Enable disabled code and
remove temprorary one.
(window::::): set NetWM icon to window for all EWMH capable WMs even
it's WindowMaker.
(image_mask): new function to create alpha mask for image. It's based
on xgps_cursor_mask() code with additional argument `alpha_treshold`.
This function may be used for images (alpha_treshold == 0) with real
alpha mask and for cursors (if no Xcursor library is used - no alpha
is used, no shadows in cursors, alpha_treshold == 158 is used to cut
transparent pixels).
(_createAppIconPixmaps): icon pixmap creation rewritten to support
images with alpha channel using wraster functions. Use image_mask().
(restrictWindow:toImage:): use image_mask() instead of
xgps_cursor_mask().
(xgps_cursor_mask): removed as image_mask() replaced it.
Guard xgps_cursor_image( with #if - will not be compiled if Xcursor
is used.
(imagecursor:::): use image_mask() instead of xgps_cursor_mask().
2019-12-24 Fred Kiefer <FredKiefer@gmx.de>
* Source/cairo/CairoFontInfo.m: Revert to the old defaults for

View file

@ -1809,28 +1809,14 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
// blue
B = d[2];
// alpha
#if 0
/*
For unclear reasons the alpha handling does not work, so we simulate it.
*/
if (samples == 4)
{
A = d[4];
A = d[3];
}
else
{
A = 255;
}
#else
if (R || G || B)
{
A = 255;
}
else
{
A = 0;
}
#endif
iconPropertyData[index++] = A << 24 | R << 16 | G << 8 | B;
d += samples;
@ -2018,8 +2004,7 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
// For window managers supporting EWMH, but not Window Maker,
// where we use a different solution, set the window icon.
if (((generic.wm & XGWM_EWMH) != 0)
&& ((generic.wm & XGWM_WINDOWMAKER) == 0))
if ((generic.wm & XGWM_EWMH) != 0)
{
[self _setNetWMIconFor: window->ident];
}
@ -2707,62 +2692,109 @@ static Pixmap xIconPixmap;
static Pixmap xIconMask;
static BOOL didCreatePixmaps;
-(int) _createAppIconPixmaps
Pixmap
image_mask(Display *xdpy, Drawable draw, const unsigned char *data,
int w, int h, int colors, int alpha_treshold)
{
int j, i;
unsigned char ialpha;
Pixmap pix;
int bitmapSize = ((w + 7) >> 3) * h; // (w/8) rounded up times height
char *aData = calloc(1, bitmapSize);
char *cData = aData;
if (colors == 4)
{
int k;
for (j = 0; j < h; j++)
{
k = 0;
for (i = 0; i < w; i++, k++)
{
if (k > 7)
{
cData++;
k = 0;
}
data += 3; // skip R, G, B
ialpha = (unsigned short)((char)*data++);
if (ialpha > alpha_treshold)
{
*cData |= (0x01 << k);
}
}
cData++;
}
}
else
{
for (j = 0; j < bitmapSize; j++)
{
*cData++ = 0xff;
}
}
pix = XCreatePixmapFromBitmapData(xdpy, draw, (char *)aData, w, h,
1L, 0L, 1);
free(aData);
return pix;
}
- (int) _createAppIconPixmaps
{
NSImage *image;
NSBitmapImageRep *rep;
int i, j, w, h, samples, screen;
unsigned char *data;
XColor pixelColor;
GC pixgc;
RColor pixelRColor;
RContext *rcontext;
int i, j, width, height, samples, screen;
unsigned char *data;
RContext *rcontext;
RXImage *rxImage;
char *r, *g, *b, *a;
NSAssert(!didCreatePixmaps, @"called _createAppIconPixmap twice");
didCreatePixmaps = YES;
image = [NSApp applicationIconImage];
rep = getStandardBitmap(image);
rep = getStandardBitmap([NSApp applicationIconImage]);
if (rep == nil)
return 0;
data = [rep bitmapData];
screen = [[[self screenList] objectAtIndex: 0] intValue];
xIconPixmap = XCreatePixmap(dpy,
[self xDisplayRootWindowForScreen: screen],
[rep pixelsWide], [rep pixelsHigh],
DefaultDepth(dpy, screen));
pixgc = XCreateGC(dpy, xIconPixmap, 0, NULL);
h = [rep pixelsHigh];
w = [rep pixelsWide];
samples = [rep samplesPerPixel];
rcontext = [self xrContextForScreen: screen];
width = [rep pixelsWide];
height = [rep pixelsHigh];
samples = [rep samplesPerPixel];
for (i = 0; i < h; i++)
/**/
rxImage = RCreateXImage(rcontext, rcontext->depth, width, height);
xIconPixmap = XCreatePixmap(dpy, rcontext->drawable,
width, height, rcontext->depth);
r = rxImage->image->data;
g = rxImage->image->data + 1;
b = rxImage->image->data + 2;
a = rxImage->image->data + 3;
data = [rep bitmapData];
for (i = 0; i < height; i++)
{
unsigned char *d = data;
for (j = 0; j < w; j++)
for (j = 0; j < width; j++)
{
pixelRColor.red = d[0];
pixelRColor.green = d[1];
pixelRColor.blue = d[2];
RGetClosestXColor(rcontext, &pixelRColor, &pixelColor);
XSetForeground(dpy, pixgc, pixelColor. pixel);
XDrawPoint(dpy, xIconPixmap, pixgc, j, i);
*r = d[2];
*g = d[1];
*b = d[0];
*a = d[3];
r += 4;
g += 4;
b += 4;
a += 4;
d += samples;
}
data += [rep bytesPerRow];
}
XFreeGC(dpy, pixgc);
xIconMask = xgps_cursor_mask(dpy, ROOT, [rep bitmapData],
[rep pixelsWide],
[rep pixelsHigh],
[rep samplesPerPixel]);
XPutImage(dpy, xIconPixmap, rcontext->copy_gc, rxImage->image,
0, 0, 0, 0, width, height);
RDestroyXImage(rcontext, rxImage);
/**/
xIconMask = image_mask(dpy, ROOT, [rep bitmapData], width, height, samples, 0);
return 1;
}
@ -3072,10 +3104,11 @@ static BOOL didCreatePixmaps;
{
if ([rep samplesPerPixel] == 4)
{
pixmap = xgps_cursor_mask(dpy, GET_XDRAWABLE(window),
[rep bitmapData],
[rep pixelsWide], [rep pixelsHigh],
[rep samplesPerPixel]);
pixmap = image_mask(dpy, GET_XDRAWABLE(window),
[rep bitmapData],
[rep pixelsWide], [rep pixelsHigh],
[rep samplesPerPixel],
ALPHA_THRESHOLD);
}
}
}
@ -4017,56 +4050,10 @@ static BOOL cursor_hidden = NO;
}
}
#if !HAVE_XCURSOR
#define ALPHA_THRESHOLD 158
Pixmap
xgps_cursor_mask(Display *xdpy, Drawable draw, const unsigned char *data,
int w, int h, int colors)
{
int j, i;
unsigned char ialpha;
Pixmap pix;
int bitmapSize = ((w + 7) >> 3) * h; // (w/8) rounded up times height
char *aData = calloc(1, bitmapSize);
char *cData = aData;
if (colors == 4)
{
int k;
for (j = 0; j < h; j++)
{
k = 0;
for (i = 0; i < w; i++, k++)
{
if (k > 7)
{
cData++;
k = 0;
}
data += 3;
ialpha = (unsigned short)((char)*data++);
if (ialpha > ALPHA_THRESHOLD)
{
*cData |= (0x01 << k);
}
}
cData++;
}
}
else
{
for (j = 0; j < bitmapSize; j++)
{
*cData++ = 0xff;
}
}
pix = XCreatePixmapFromBitmapData(xdpy, draw, (char *)aData, w, h,
1L, 0L, 1);
free(aData);
return pix;
}
Pixmap
xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
int w, int h, int colors, XColor *fg, XColor *bg)
@ -4143,6 +4130,8 @@ xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
return pix;
}
#endif
- (void) hidecursor
{
if (cursor_hidden)
@ -4328,7 +4317,7 @@ xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
h = maxh;
source = xgps_cursor_image(dpy, ROOT, data, w, h, colors, &fg, &bg);
mask = xgps_cursor_mask(dpy, ROOT, data, w, h, colors);
mask = image_mask(dpy, ROOT, data, w, h, colors, ALPHA_TRESHOLD);
bg = [self xColorFromColor: bg forScreen: defScreen];
fg = [self xColorFromColor: fg forScreen: defScreen];