Skip to content

Commit 96757f2

Browse files
SiegeLordExSiegeLord
authored andcommitted
Remove the use of XPM from the X11 backend.
This enables the setting of higher quality icons. Idea and some implementation from #1375
1 parent d53cc97 commit 96757f2

File tree

8 files changed

+110
-226
lines changed

8 files changed

+110
-226
lines changed

CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -752,13 +752,6 @@ if(SUPPORT_X11)
752752
message(FATAL_ERROR "X11 support requires Xcursor library.")
753753
endif(CAN_XCURSOR)
754754

755-
check_library_exists(Xpm XpmCreatePixmapFromData "" CAN_XPM)
756-
if(CAN_XPM)
757-
set(ALLEGRO_XWINDOWS_WITH_XPM 1)
758-
find_library(XPM_LIB "Xpm")
759-
list(APPEND X11_LIBRARIES "${XPM_LIB}")
760-
endif(CAN_XPM)
761-
762755
check_include_file("X11/extensions/XInput2.h" CAN_XINPUT2)
763756
run_c_compile_test("
764757
#include <X11/extensions/XInput2.h>

include/allegro5/platform/alplatf.h.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@
109109
/* Define if XInput 2.2 X11 extension is supported. */
110110
#cmakedefine ALLEGRO_XWINDOWS_WITH_XINPUT2
111111

112-
/* Define if Xpm is found. Useful on Ubuntu Unity to set icon. */
113-
#cmakedefine ALLEGRO_XWINDOWS_WITH_XPM
114112

115113
/*---------------------------------------------------------------------------*/
116114

misc/make_icon.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env python3
2+
"""Generate the icon.c file used for the default icon.
3+
4+
Usage:
5+
6+
make_icon.py in_file.png out_file.inc
7+
"""
8+
9+
import numpy as np
10+
import PIL.Image
11+
import sys
12+
13+
image = np.array(PIL.Image.open(sys.argv[1]).convert("RGBA"))
14+
15+
with open(sys.argv[2], "w") as f:
16+
f.write("/* Generated using make_icon.py */\n")
17+
f.write(f"#define ICON_WIDTH {image.shape[1]}\n")
18+
f.write(f"#define ICON_HEIGHT {image.shape[0]}\n")
19+
f.write("static uint32_t icon_data[] = {\n")
20+
for i, row in enumerate(image):
21+
for j, col in enumerate(row):
22+
# Premultiply alpha.
23+
col = col.astype(np.float32) / 255.
24+
col = (col * col[-1] * 255.).astype(np.uint32)
25+
col = (col[0] << 24) + (col[1] << 16) + (col[2] << 8) + col[3]
26+
f.write(f"{col:#010x}")
27+
if i + 1 < image.shape[0] or j + 1 < image.shape[1]:
28+
f.write(",")
29+
f.write("\n")
30+
f.write("};\n")

src/x/icon.inc

Lines changed: 53 additions & 0 deletions
Large diffs are not rendered by default.

src/x/icon.xpm

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/x/xdisplay.c

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,8 @@
1818
#include <X11/extensions/XInput2.h>
1919
#endif
2020

21-
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
22-
#include <X11/xpm.h>
23-
#endif
24-
2521
#include "xicon.h"
22+
#include "icon.inc"
2623

2724
ALLEGRO_DEBUG_CHANNEL("display")
2825

@@ -529,27 +526,6 @@ static ALLEGRO_DISPLAY_XGLX *xdpy_create_display_locked(
529526
return NULL;
530527
}
531528

532-
static void set_initial_icon(Display *x11display, Window window)
533-
{
534-
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
535-
XWMHints *wm_hints;
536-
537-
if (x11_xpm == NULL)
538-
return;
539-
540-
wm_hints = XAllocWMHints();
541-
542-
wm_hints->flags |= IconPixmapHint | IconMaskHint;
543-
XpmCreatePixmapFromData(x11display, window, x11_xpm,
544-
&wm_hints->icon_pixmap, &wm_hints->icon_mask, NULL);
545-
546-
XSetWMHints(x11display, window, wm_hints);
547-
XFree(wm_hints);
548-
#else
549-
(void)x11display;
550-
(void)window;
551-
#endif
552-
}
553529

554530
static bool xdpy_create_display_hook_default(ALLEGRO_DISPLAY *display,
555531
int w, int h)
@@ -559,7 +535,24 @@ static bool xdpy_create_display_hook_default(ALLEGRO_DISPLAY *display,
559535
(void)w;
560536
(void)h;
561537

562-
set_initial_icon(system->x11display, d->window);
538+
if (_al_xwin_initial_icon) {
539+
ALLEGRO_BITMAP *bitmaps[] = {_al_xwin_initial_icon};
540+
_al_xwin_set_icons(display, 1, bitmaps);
541+
} else {
542+
ALLEGRO_STATE state;
543+
al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
544+
ALLEGRO_BITMAP *bitmap = al_create_bitmap(ICON_WIDTH, ICON_HEIGHT);
545+
546+
ALLEGRO_LOCKED_REGION *lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_RGBA_8888, ALLEGRO_LOCK_WRITEONLY);
547+
for (int y = 0; y < ICON_HEIGHT; y++) {
548+
memcpy((char*)lr->data + lr->pitch * y, &icon_data[ICON_WIDTH * y], ICON_WIDTH * 4);
549+
}
550+
al_unlock_bitmap(bitmap);
551+
552+
ALLEGRO_BITMAP *bitmaps[] = {bitmap};
553+
_al_xwin_set_icons(display, 1, bitmaps);
554+
al_destroy_bitmap(bitmap);
555+
}
563556

564557
XLockDisplay(system->x11display);
565558

src/x/xicon.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#ifndef XICON_H
22
#define XICON_H
33

4-
extern char **x11_xpm;
4+
extern ALLEGRO_BITMAP *_al_xwin_initial_icon;
55

66
#endif // XICON_H

src/x/xsystem.c

Lines changed: 7 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -27,144 +27,22 @@ ALLEGRO_DEBUG_CHANNEL("system")
2727

2828
static ALLEGRO_SYSTEM_INTERFACE *xglx_vt;
2929

30-
char **x11_xpm = NULL;
30+
ALLEGRO_BITMAP *_al_xwin_initial_icon = NULL;
3131

3232
static bool xglx_inhibit_screensaver(bool inhibit);
3333

34-
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
35-
#include <stdio.h>
36-
#include "icon.xpm"
37-
38-
static bool x11_xpm_set;
39-
static int x11_xpm_rows;
40-
41-
static char **bitmap_to_xpm(ALLEGRO_BITMAP *bitmap, int *nrows_ret)
42-
{
43-
_AL_VECTOR v;
44-
int w, h, x, y;
45-
int ncolors, nrows;
46-
char **xpm;
47-
char buf[100];
48-
int i;
49-
50-
ALLEGRO_LOCKED_REGION *lr = al_lock_bitmap(bitmap, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_READONLY);
51-
if (lr == NULL)
52-
return NULL;
53-
54-
_al_vector_init(&v, sizeof(uint32_t));
55-
56-
w = al_get_bitmap_width(bitmap);
57-
h = al_get_bitmap_height(bitmap);
58-
59-
for (y = 0; y < h; y++) {
60-
for (x = 0; x < w; x++) {
61-
uint32_t c = *(uint32_t *)((((char *)lr->data) + lr->pitch * y + x * 4));
62-
int alpha = (c >> 24) & 0xff;
63-
if (alpha != 255) {
64-
c = 0;
65-
}
66-
int sz = _al_vector_size(&v);
67-
bool found = false;
68-
for (i = 0; i < sz; i++) {
69-
if (*((uint32_t *)_al_vector_ref(&v, i)) == c) {
70-
found = true;
71-
break;
72-
}
73-
}
74-
if (found == false) {
75-
uint32_t *p = _al_vector_alloc_back(&v);
76-
*p = c;
77-
}
78-
}
79-
}
80-
81-
ncolors = _al_vector_size(&v);
82-
nrows = 2 + ncolors + h;
83-
84-
xpm = malloc(nrows * sizeof(char *));
85-
if (xpm == NULL)
86-
return NULL;
87-
88-
snprintf(buf, 100, "%d %d %d 8", w, h, ncolors + 1);
89-
90-
xpm[0] = strdup(buf);
91-
92-
xpm[1] = strdup("00000000\tc None");
93-
94-
for (i = 0; i < ncolors; i++) {
95-
uint32_t c = *((uint32_t *)_al_vector_ref(&v, i));
96-
int r = c & 0xff;
97-
int g = (c >> 8) & 0xff;
98-
int b = (c >> 16) & 0xff;
99-
snprintf(buf, 100, "%08x\tc #%02x%02x%02x", i+1, r, g, b);
100-
xpm[i+2] = strdup(buf);
101-
}
102-
103-
for (y = 0; y < h; y++) {
104-
int row = y + 2 + ncolors;
105-
xpm[row] = malloc(8 * w + 1);
106-
xpm[row][8 * w] = 0;
107-
uint32_t *p = (uint32_t *)(((char *)lr->data) + lr->pitch * y);
108-
for (x = 0; x < w; x++) {
109-
uint32_t pixel = *p;
110-
int alpha = (pixel >> 24) & 0xff;
111-
if (alpha != 255) {
112-
snprintf(buf, 100, "%s", "00000000");
113-
}
114-
else {
115-
for (i = 0; i < (int)_al_vector_size(&v); i++) {
116-
uint32_t pixel2 = *((uint32_t *)_al_vector_ref(&v, i));
117-
if (pixel == pixel2)
118-
break;
119-
}
120-
snprintf(buf, 100, "%08x", i+1);
121-
}
122-
for (i = 0; i < 8; i++) {
123-
xpm[row][8*x+i] = buf[i];
124-
}
125-
p++;
126-
}
127-
}
128-
129-
_al_vector_free(&v);
130-
131-
*nrows_ret = nrows;
132-
133-
al_unlock_bitmap(bitmap);
134-
135-
// debug
136-
/*
137-
for (i = 0; i < nrows; i++) {
138-
printf("%s\n", xpm[i]);
139-
}
140-
*/
141-
142-
return xpm;
143-
}
144-
#endif
14534

14635
/* Function: al_x_set_initial_icon
14736
*/
14837
bool al_x_set_initial_icon(ALLEGRO_BITMAP *bitmap)
14938
{
150-
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
151-
if (x11_xpm_set) {
152-
int i;
153-
for (i = 0; i < x11_xpm_rows; i++) {
154-
free(x11_xpm[i]);
155-
}
156-
free(x11_xpm);
157-
x11_xpm_set = false;
158-
}
159-
x11_xpm = bitmap_to_xpm(bitmap, &x11_xpm_rows);
160-
if (x11_xpm == NULL)
161-
return false;
162-
x11_xpm_set = true;
39+
ALLEGRO_STATE state;
40+
al_store_state(&state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS);
41+
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
42+
al_destroy_bitmap(_al_xwin_initial_icon);
43+
_al_xwin_initial_icon = al_clone_bitmap(bitmap);
44+
al_restore_state(&state);
16345
return true;
164-
#else
165-
(void)bitmap;
166-
return false;
167-
#endif
16846
}
16947

17048
static ALLEGRO_SYSTEM *xglx_initialize(int flags)
@@ -246,10 +124,6 @@ static ALLEGRO_SYSTEM *xglx_initialize(int flags)
246124
}
247125
}
248126

249-
#ifdef ALLEGRO_XWINDOWS_WITH_XPM
250-
x11_xpm = icon_xpm;
251-
#endif
252-
253127
return &s->system;
254128
}
255129

0 commit comments

Comments
 (0)