mirror of
https://github.com/gnustep/libs-back.git
synced 2025-02-23 03:41:04 +00:00
Merge branch 'master' of github.com:gnustep/libs-back into android-back
This commit is contained in:
commit
b9248d19a8
4 changed files with 283 additions and 231 deletions
45
ChangeLog
45
ChangeLog
|
@ -1,3 +1,48 @@
|
||||||
|
2020-01-16 Sergii Stoian <stoyan255@gmail.com>
|
||||||
|
|
||||||
|
* Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): use
|
||||||
|
lowerCamelCase for objects and underscores for primitive types;
|
||||||
|
do not ignore TakeFocus request if no key window was set
|
||||||
|
and main application menu receives request.
|
||||||
|
|
||||||
|
2020-01-14 Sergii Stoian <stoyan255@gmail.com>
|
||||||
|
|
||||||
|
* Source/x11/XGServerWindow.m (alphaMaskForImage): renamed from
|
||||||
|
image_mask().
|
||||||
|
(swapColors): new function to convert colors from ARGB order into RGBA
|
||||||
|
(big-endian systems) or BGRA (little-endian systems).
|
||||||
|
(_createAppIconPixmaps): use swapColors() and remove unused code.
|
||||||
|
(restrictWindow:toImage:): use alphaMaskForImage().
|
||||||
|
(imagecursor:::): use swapColors() and remove unused code.
|
||||||
|
(ALPHA_THRESHOLD): removed duplicate of definition.
|
||||||
|
|
||||||
|
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
|
||||||
|
hinting and allow for all possible values to be set.
|
||||||
|
|
||||||
2019-05-19 Fred Kiefer <FredKiefer@gmx.de>
|
2019-05-19 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/cairo/CairoFontInfo.m,
|
* Source/cairo/CairoFontInfo.m,
|
||||||
|
|
|
@ -42,6 +42,80 @@
|
||||||
#include <fontconfig/fontconfig.h>
|
#include <fontconfig/fontconfig.h>
|
||||||
#include <fontconfig/fcfreetype.h>
|
#include <fontconfig/fcfreetype.h>
|
||||||
|
|
||||||
|
void set_font_options(cairo_font_options_t *options)
|
||||||
|
{
|
||||||
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||||
|
cairo_hint_metrics_t metrics = CAIRO_HINT_METRICS_ON;
|
||||||
|
cairo_hint_style_t style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
int hinting = [ud integerForKey: @"GSFontHinting"];
|
||||||
|
int subpixel = 0;
|
||||||
|
|
||||||
|
if (hinting == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This could be on purpose or a missing value.
|
||||||
|
* In the later case use the defaults.
|
||||||
|
*/
|
||||||
|
if (nil == [ud objectForKey: @"GSFontHinting"])
|
||||||
|
{
|
||||||
|
hinting = 33;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This part is only here to debug disabling the use of hinting for
|
||||||
|
* metrics, because doing so causes menus to get cut off on the right.
|
||||||
|
*/
|
||||||
|
switch (hinting >> 4)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
metrics = CAIRO_HINT_METRICS_DEFAULT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
metrics = CAIRO_HINT_METRICS_OFF;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
metrics = CAIRO_HINT_METRICS_ON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (hinting & 0x0f)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
style = CAIRO_HINT_STYLE_DEFAULT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
style = CAIRO_HINT_STYLE_SLIGHT;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
style = CAIRO_HINT_STYLE_MEDIUM;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
style = CAIRO_HINT_STYLE_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_font_options_set_hint_metrics(options, metrics);
|
||||||
|
cairo_font_options_set_hint_style(options, style);
|
||||||
|
|
||||||
|
if ((subpixel = [ud integerForKey: @"back-art-subpixel-text"]))
|
||||||
|
{
|
||||||
|
cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
|
||||||
|
|
||||||
|
if (subpixel == 2)
|
||||||
|
{
|
||||||
|
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_BGR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_RGB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@implementation CairoFontInfo
|
@implementation CairoFontInfo
|
||||||
|
|
||||||
- (BOOL) setupAttributes
|
- (BOOL) setupAttributes
|
||||||
|
@ -51,10 +125,6 @@
|
||||||
cairo_matrix_t font_matrix;
|
cairo_matrix_t font_matrix;
|
||||||
cairo_matrix_t ctm;
|
cairo_matrix_t ctm;
|
||||||
cairo_font_options_t *options;
|
cairo_font_options_t *options;
|
||||||
cairo_hint_metrics_t metrics = CAIRO_HINT_METRICS_ON;
|
|
||||||
cairo_hint_style_t style = CAIRO_HINT_STYLE_DEFAULT;
|
|
||||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
||||||
int hinting = 0, subpixel = 0;
|
|
||||||
|
|
||||||
if (![super setupAttributes])
|
if (![super setupAttributes])
|
||||||
{
|
{
|
||||||
|
@ -82,53 +152,7 @@
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hinting = [ud integerForKey: @"GSFontHinting"]))
|
set_font_options(options);
|
||||||
{ /*
|
|
||||||
* This part is only here to debug disabling the use of hinting for
|
|
||||||
* metrics, because doing so causes menus to get cut off on the right.
|
|
||||||
*/
|
|
||||||
switch (hinting >> 4)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
metrics = CAIRO_HINT_METRICS_OFF;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
metrics = CAIRO_HINT_METRICS_ON;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (hinting & 0x0f)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
style = CAIRO_HINT_STYLE_NONE;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
style = CAIRO_HINT_STYLE_SLIGHT;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
style = CAIRO_HINT_STYLE_MEDIUM;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
style = CAIRO_HINT_STYLE_FULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cairo_font_options_set_hint_metrics(options, metrics);
|
|
||||||
cairo_font_options_set_hint_style(options, style);
|
|
||||||
|
|
||||||
if ((subpixel = [ud integerForKey: @"back-art-subpixel-text"]))
|
|
||||||
{
|
|
||||||
cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
|
|
||||||
|
|
||||||
if (subpixel == 2)
|
|
||||||
{
|
|
||||||
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_BGR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_RGB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options);
|
_scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options);
|
||||||
cairo_font_options_destroy(options);
|
cairo_font_options_destroy(options);
|
||||||
|
|
|
@ -1911,20 +1911,14 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
|
||||||
- (NSEvent *)_handleTakeFocusAtom: (XEvent)xEvent
|
- (NSEvent *)_handleTakeFocusAtom: (XEvent)xEvent
|
||||||
forContext: (NSGraphicsContext *)gcontext
|
forContext: (NSGraphicsContext *)gcontext
|
||||||
{
|
{
|
||||||
int key_num;
|
NSWindow *keyWindow = [NSApp keyWindow];
|
||||||
NSWindow *key_win;
|
int key_num = [keyWindow windowNumber];
|
||||||
NSEvent *e = nil;
|
NSEvent *e = nil;
|
||||||
key_win = [NSApp keyWindow];
|
|
||||||
key_num = [key_win windowNumber];
|
|
||||||
NSDebugLLog(@"Focus", @"take focus:%lu (current=%lu key=%d)",
|
|
||||||
cWin->number, generic.currentFocusWindow, key_num);
|
|
||||||
|
|
||||||
/* Sometimes window managers lose the setinputfocus on the key window
|
NSDebugLLog(@"Focus",
|
||||||
* e.g. when ordering out a window with focus then ordering in the key window.
|
@"TakeFocus received by: %li (%lu) (focused = %lu, key = %d)",
|
||||||
* it might search for a window until one accepts its take focus request.
|
cWin->number, xEvent.xfocus.window,
|
||||||
*/
|
generic.currentFocusWindow, key_num);
|
||||||
if (key_num == cWin->number)
|
|
||||||
cWin->ignore_take_focus = NO;
|
|
||||||
|
|
||||||
/* Invalidate the previous request. It's possible the app lost focus
|
/* Invalidate the previous request. It's possible the app lost focus
|
||||||
before this request was fufilled and we are being focused again,
|
before this request was fufilled and we are being focused again,
|
||||||
|
@ -1933,6 +1927,20 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
|
||||||
generic.focusRequestNumber = 0;
|
generic.focusRequestNumber = 0;
|
||||||
generic.desiredFocusWindow = 0;
|
generic.desiredFocusWindow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sometimes window managers lose the setinputfocus on the key window
|
||||||
|
* e.g. when ordering out a window with focus then ordering in the key window.
|
||||||
|
* it might search for a window until one accepts its take focus request.
|
||||||
|
*/
|
||||||
|
if (key_num == 0)
|
||||||
|
{
|
||||||
|
cWin->ignore_take_focus = NO;
|
||||||
|
}
|
||||||
|
else if (cWin->number == [[[NSApp mainMenu] window] windowNumber])
|
||||||
|
{
|
||||||
|
cWin->ignore_take_focus = NO;
|
||||||
|
}
|
||||||
|
|
||||||
/* We'd like to send this event directly to the front-end to handle,
|
/* We'd like to send this event directly to the front-end to handle,
|
||||||
but the front-end polls events so slowly compared the speed at
|
but the front-end polls events so slowly compared the speed at
|
||||||
which X events could potentially come that we could easily get
|
which X events could potentially come that we could easily get
|
||||||
|
@ -1953,23 +1961,31 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
|
||||||
else if (cWin->number == key_num)
|
else if (cWin->number == key_num)
|
||||||
{
|
{
|
||||||
NSDebugLLog(@"Focus", @"Reasserting key window");
|
NSDebugLLog(@"Focus", @"Reasserting key window");
|
||||||
[GSServerForWindow(key_win) setinputfocus: key_num];
|
[GSServerForWindow(keyWindow) setinputfocus: key_num];
|
||||||
}
|
}
|
||||||
else if (key_num
|
else if (key_num
|
||||||
&& cWin->number == [[[NSApp mainMenu] window] windowNumber])
|
&& cWin->number == [[[NSApp mainMenu] window] windowNumber])
|
||||||
{
|
{
|
||||||
|
gswindow_device_t *key_window = [XGServer _windowWithTag:key_num];
|
||||||
/* This might occur when the window manager just wants someone
|
/* This might occur when the window manager just wants someone
|
||||||
to become key, so it tells the main menu (typically the first
|
to become key, so it tells the main menu (typically the first
|
||||||
menu in the list), but since we already have a window that
|
menu in the list), but since we already have a window that
|
||||||
was key before, use that instead */
|
was key before, use that instead */
|
||||||
NSDebugLLog(@"Focus", @"Key window is already %d", key_num);
|
NSDebugLLog(@"Focus", @"Key window is already %d", key_num);
|
||||||
[GSServerForWindow(key_win) setinputfocus: key_num];
|
if (key_window->map_state == IsUnmapped) {
|
||||||
|
/* `key_window` was unmapped by window manager.
|
||||||
|
this window and `key_window` are on the different workspace. */
|
||||||
|
[GSServerForWindow(keyWindow) setinputfocus: cWin->number];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[GSServerForWindow(keyWindow) setinputfocus: key_num];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSPoint eventLocation;
|
NSPoint eventLocation;
|
||||||
/*
|
/*
|
||||||
* Here the app asked for this (if key_win==nil) or there was a
|
* Here the app asked for this (if keyWindow==nil) or there was a
|
||||||
* click on the title bar or some other reason (window mapped,
|
* click on the title bar or some other reason (window mapped,
|
||||||
* etc). We don't necessarily want to forward the event for the
|
* etc). We don't necessarily want to forward the event for the
|
||||||
* last reason but we just have to deal with that since we can
|
* last reason but we just have to deal with that since we can
|
||||||
|
|
|
@ -1809,28 +1809,14 @@ _get_next_prop_new_event(Display *display, XEvent *event, char *arg)
|
||||||
// blue
|
// blue
|
||||||
B = d[2];
|
B = d[2];
|
||||||
// alpha
|
// alpha
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
For unclear reasons the alpha handling does not work, so we simulate it.
|
|
||||||
*/
|
|
||||||
if (samples == 4)
|
if (samples == 4)
|
||||||
{
|
{
|
||||||
A = d[4];
|
A = d[3];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
A = 255;
|
A = 255;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (R || G || B)
|
|
||||||
{
|
|
||||||
A = 255;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
A = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
iconPropertyData[index++] = A << 24 | R << 16 | G << 8 | B;
|
iconPropertyData[index++] = A << 24 | R << 16 | G << 8 | B;
|
||||||
d += samples;
|
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,
|
// For window managers supporting EWMH, but not Window Maker,
|
||||||
// where we use a different solution, set the window icon.
|
// where we use a different solution, set the window icon.
|
||||||
if (((generic.wm & XGWM_EWMH) != 0)
|
if ((generic.wm & XGWM_EWMH) != 0)
|
||||||
&& ((generic.wm & XGWM_WINDOWMAKER) == 0))
|
|
||||||
{
|
{
|
||||||
[self _setNetWMIconFor: window->ident];
|
[self _setNetWMIconFor: window->ident];
|
||||||
}
|
}
|
||||||
|
@ -2707,62 +2692,134 @@ static Pixmap xIconPixmap;
|
||||||
static Pixmap xIconMask;
|
static Pixmap xIconMask;
|
||||||
static BOOL didCreatePixmaps;
|
static BOOL didCreatePixmaps;
|
||||||
|
|
||||||
-(int) _createAppIconPixmaps
|
Pixmap
|
||||||
|
alphaMaskForImage(Display *xdpy, Drawable draw, const unsigned char *data,
|
||||||
|
int w, int h, int colors, int alpha_treshold)
|
||||||
{
|
{
|
||||||
NSImage *image;
|
int j, i;
|
||||||
NSBitmapImageRep *rep;
|
unsigned char ialpha;
|
||||||
int i, j, w, h, samples, screen;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert RGBA unpacked to ARGB packed.
|
||||||
|
// Packed ARGB values are layed out as ARGB on big endian systems
|
||||||
|
// and as BGRA on little endian systems
|
||||||
|
void
|
||||||
|
swapColors(unsigned char *image_data, int width, int height,
|
||||||
|
int samples_per_pixel, int bytes_per_row)
|
||||||
|
{
|
||||||
|
NSInteger x, y;
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
XColor pixelColor;
|
unsigned char *r, *g, *b, *a;
|
||||||
GC pixgc;
|
|
||||||
RColor pixelRColor;
|
data = image_data;
|
||||||
RContext *rcontext;
|
r = data;
|
||||||
|
g = data + 1;
|
||||||
|
b = data + 2;
|
||||||
|
a = data + 3;
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
unsigned char *d = data;
|
||||||
|
for (x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
#if GS_WORDS_BIGENDIAN
|
||||||
|
// RGBA -> ARGB
|
||||||
|
unsigned char _d = d[3];
|
||||||
|
*r = _d;
|
||||||
|
*g = d[0];
|
||||||
|
*b = d[1];
|
||||||
|
*a = d[2];
|
||||||
|
#else
|
||||||
|
// RGBA -> BGRA
|
||||||
|
unsigned char _d = d[0];
|
||||||
|
*r = d[2];
|
||||||
|
// *g = d[1];
|
||||||
|
*b = _d;
|
||||||
|
// *a = d[3];
|
||||||
|
#endif
|
||||||
|
r += 4;
|
||||||
|
g += 4;
|
||||||
|
b += 4;
|
||||||
|
a += 4;
|
||||||
|
d += samples_per_pixel;
|
||||||
|
}
|
||||||
|
data += bytes_per_row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (int) _createAppIconPixmaps
|
||||||
|
{
|
||||||
|
NSBitmapImageRep *rep;
|
||||||
|
int width, height, colors, screen;
|
||||||
|
RContext *rcontext;
|
||||||
|
RXImage *rxImage;
|
||||||
|
|
||||||
NSAssert(!didCreatePixmaps, @"called _createAppIconPixmap twice");
|
NSAssert(!didCreatePixmaps, @"called _createAppIconPixmap twice");
|
||||||
|
|
||||||
didCreatePixmaps = YES;
|
didCreatePixmaps = YES;
|
||||||
|
|
||||||
image = [NSApp applicationIconImage];
|
rep = getStandardBitmap([NSApp applicationIconImage]);
|
||||||
rep = getStandardBitmap(image);
|
|
||||||
if (rep == nil)
|
if (rep == nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
data = [rep bitmapData];
|
|
||||||
screen = [[[self screenList] objectAtIndex: 0] intValue];
|
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];
|
rcontext = [self xrContextForScreen: screen];
|
||||||
|
width = [rep pixelsWide];
|
||||||
|
height = [rep pixelsHigh];
|
||||||
|
colors = [rep samplesPerPixel];
|
||||||
|
|
||||||
for (i = 0; i < h; i++)
|
rxImage = RCreateXImage(rcontext, rcontext->depth, width, height);
|
||||||
{
|
memcpy((char*)rxImage->image->data, [rep bitmapData], width * height * colors);
|
||||||
unsigned char *d = data;
|
swapColors((unsigned char *)rxImage->image->data,
|
||||||
for (j = 0; j < w; j++)
|
width, height, colors, [rep bytesPerRow]);
|
||||||
{
|
|
||||||
pixelRColor.red = d[0];
|
|
||||||
pixelRColor.green = d[1];
|
|
||||||
pixelRColor.blue = d[2];
|
|
||||||
|
|
||||||
RGetClosestXColor(rcontext, &pixelRColor, &pixelColor);
|
xIconPixmap = XCreatePixmap(dpy, rcontext->drawable,
|
||||||
XSetForeground(dpy, pixgc, pixelColor. pixel);
|
width, height, rcontext->depth);
|
||||||
XDrawPoint(dpy, xIconPixmap, pixgc, j, i);
|
XPutImage(dpy, xIconPixmap, rcontext->copy_gc, rxImage->image,
|
||||||
d += samples;
|
0, 0, 0, 0, width, height);
|
||||||
}
|
RDestroyXImage(rcontext, rxImage);
|
||||||
data += [rep bytesPerRow];
|
|
||||||
}
|
|
||||||
|
|
||||||
XFreeGC(dpy, pixgc);
|
xIconMask = alphaMaskForImage(dpy, ROOT, [rep bitmapData], width, height, colors, 0);
|
||||||
|
|
||||||
xIconMask = xgps_cursor_mask(dpy, ROOT, [rep bitmapData],
|
|
||||||
[rep pixelsWide],
|
|
||||||
[rep pixelsHigh],
|
|
||||||
[rep samplesPerPixel]);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3072,10 +3129,11 @@ static BOOL didCreatePixmaps;
|
||||||
{
|
{
|
||||||
if ([rep samplesPerPixel] == 4)
|
if ([rep samplesPerPixel] == 4)
|
||||||
{
|
{
|
||||||
pixmap = xgps_cursor_mask(dpy, GET_XDRAWABLE(window),
|
pixmap = alphaMaskForImage(dpy, GET_XDRAWABLE(window),
|
||||||
[rep bitmapData],
|
[rep bitmapData],
|
||||||
[rep pixelsWide], [rep pixelsHigh],
|
[rep pixelsWide], [rep pixelsHigh],
|
||||||
[rep samplesPerPixel]);
|
[rep samplesPerPixel],
|
||||||
|
ALPHA_THRESHOLD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4017,55 +4075,7 @@ static BOOL cursor_hidden = NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ALPHA_THRESHOLD 158
|
#if !HAVE_XCURSOR
|
||||||
|
|
||||||
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
|
Pixmap
|
||||||
xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
|
xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
|
||||||
|
@ -4143,6 +4153,8 @@ xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
|
||||||
return pix;
|
return pix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void) hidecursor
|
- (void) hidecursor
|
||||||
{
|
{
|
||||||
if (cursor_hidden)
|
if (cursor_hidden)
|
||||||
|
@ -4261,55 +4273,10 @@ xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
|
||||||
xcursorImage->yhot = hotp.y;
|
xcursorImage->yhot = hotp.y;
|
||||||
|
|
||||||
// Copy the data from the image rep to the Xcursor structure
|
// Copy the data from the image rep to the Xcursor structure
|
||||||
{
|
memcpy((char*)xcursorImage->pixels, data, w * h * colors);
|
||||||
int bytesPerRow;
|
|
||||||
size_t row;
|
|
||||||
|
|
||||||
bytesPerRow = [rep bytesPerRow];
|
swapColors((unsigned char *)xcursorImage->pixels, w, h,
|
||||||
|
colors, [rep bytesPerRow]);
|
||||||
for (row = 0; row < h; row++)
|
|
||||||
{
|
|
||||||
memcpy((char*)xcursorImage->pixels + (row * (w * 4)),
|
|
||||||
data + (row * bytesPerRow),
|
|
||||||
bytesPerRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Factor this out
|
|
||||||
// Convert RGBA unpacked to ARGB packed
|
|
||||||
// NB Packed ARGB values are layed out as ARGB on big endian systems
|
|
||||||
// and as BDRA on low endian systems
|
|
||||||
{
|
|
||||||
NSInteger stride;
|
|
||||||
NSInteger x, y;
|
|
||||||
unsigned char *cdata;
|
|
||||||
|
|
||||||
stride = 4 * w;
|
|
||||||
cdata = (unsigned char *)xcursorImage->pixels;
|
|
||||||
|
|
||||||
for (y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
for (x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
NSInteger i = (y * stride) + (x * 4);
|
|
||||||
#if GS_WORDS_BIGENDIAN
|
|
||||||
unsigned char d = cdata[i + 3];
|
|
||||||
|
|
||||||
cdata[i + 3] = cdata[i + 2];
|
|
||||||
cdata[i + 2] = cdata[i + 1];
|
|
||||||
cdata[i + 1] = cdata[i];
|
|
||||||
cdata[i] = d;
|
|
||||||
#else
|
|
||||||
unsigned char d = cdata[i];
|
|
||||||
|
|
||||||
cdata[i] = cdata[i + 2];
|
|
||||||
//cdata[i + 1] = cdata[i + 1];
|
|
||||||
cdata[i + 2] = d;
|
|
||||||
//cdata[i + 3] = cdata[i + 3];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor = XcursorImageLoadCursor(dpy, xcursorImage);
|
cursor = XcursorImageLoadCursor(dpy, xcursorImage);
|
||||||
XcursorImageDestroy(xcursorImage);
|
XcursorImageDestroy(xcursorImage);
|
||||||
|
@ -4328,7 +4295,7 @@ xgps_cursor_image(Display *xdpy, Drawable draw, const unsigned char *data,
|
||||||
h = maxh;
|
h = maxh;
|
||||||
|
|
||||||
source = xgps_cursor_image(dpy, ROOT, data, w, h, colors, &fg, &bg);
|
source = xgps_cursor_image(dpy, ROOT, data, w, h, colors, &fg, &bg);
|
||||||
mask = xgps_cursor_mask(dpy, ROOT, data, w, h, colors);
|
mask = alphaMaskForImage(dpy, ROOT, data, w, h, colors, ALPHA_TRESHOLD);
|
||||||
bg = [self xColorFromColor: bg forScreen: defScreen];
|
bg = [self xColorFromColor: bg forScreen: defScreen];
|
||||||
fg = [self xColorFromColor: fg forScreen: defScreen];
|
fg = [self xColorFromColor: fg forScreen: defScreen];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue