summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Turney <jon.turney@dronecode.org.uk>2015-11-02 17:55:19 +0000
committerJon Turney <jon.turney@dronecode.org.uk>2016-04-07 10:30:48 +0100
commit6a64b9d7af70dc7ff2cac8b35a1f7b0797823733 (patch)
tree9b6e79cad6abcb916b2a40485c3833024f77c582
parent0a69c1e2fa0ea63b02fff98e68d9f56a369e882b (diff)
hw/xwin: xcbify code for converting X11 icon to Win32 icon
Convert the code for converting an X11 icon to Win32 icon from Xlib to xcb. v2: some warning fixes in winXIconToHICON() v3: declaration-after-statement warning fixes v4: printf format fixes v5: convert in place rather than in a library This also avoids the xlib/xserver namespace collision issues, so winmultiwindowicons.h can be included everywhere it should be, which fixes compilation with -Werror=implicit-function-declaration Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk> Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
-rw-r--r--configure.ac2
-rw-r--r--hw/xwin/winmultiwindowicons.c151
-rw-r--r--hw/xwin/winmultiwindowicons.h4
-rw-r--r--hw/xwin/winmultiwindowwindow.c2
-rw-r--r--hw/xwin/winmultiwindowwm.c4
-rw-r--r--hw/xwin/winprefs.c1
-rw-r--r--hw/xwin/winwin32rootless.c1
7 files changed, 99 insertions, 66 deletions
diff --git a/configure.ac b/configure.ac
index dff06efdc..1e78b7dfd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2150,7 +2150,7 @@ if test "x$XWIN" = xyes; then
AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
AC_CHECK_TOOL(WINDRES, windres)
- PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes])
+ PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-image xcb-icccm])
if test "x$WINDOWSWM" = xauto; then
PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
diff --git a/hw/xwin/winmultiwindowicons.c b/hw/xwin/winmultiwindowicons.c
index cc4538709..050795123 100644
--- a/hw/xwin/winmultiwindowicons.c
+++ b/hw/xwin/winmultiwindowicons.c
@@ -36,15 +36,21 @@
#define WINVER 0x0500
#endif
+#include <limits.h>
+#include <stdbool.h>
+
#include <X11/Xwindows.h>
#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_icccm.h>
+#include <xcb/xcb_image.h>
#include "winresource.h"
#include "winprefs.h"
#include "winmsg.h"
#include "winmultiwindowicons.h"
#include "winglobals.h"
+
/*
* global variables
*/
@@ -57,7 +63,7 @@ extern HINSTANCE g_hInstance;
static void
winScaleXImageToWindowsIcon(int iconSize,
int effBPP,
- int stride, XImage * pixmap, unsigned char *image)
+ int stride, xcb_image_t* pixmap, unsigned char *image)
{
int row, column, effXBPP, effXDepth;
unsigned char *outPtr;
@@ -69,15 +75,15 @@ winScaleXImageToWindowsIcon(int iconSize,
unsigned int zero;
unsigned int color;
- effXBPP = pixmap->bits_per_pixel;
- if (pixmap->bits_per_pixel == 15)
+ effXBPP = pixmap->bpp;
+ if (pixmap->bpp == 15)
effXBPP = 16;
effXDepth = pixmap->depth;
if (pixmap->depth == 15)
effXDepth = 16;
- xStride = pixmap->bytes_per_line;
+ xStride = pixmap->stride;
if (stride == 0 || xStride == 0) {
ErrorF("winScaleXBitmapToWindows - stride or xStride is zero. "
"Bailing.\n");
@@ -330,8 +336,8 @@ NetWMToWinIconThreshold(uint32_t * icon)
static HICON
NetWMToWinIcon(int bpp, uint32_t * icon)
{
- static Bool hasIconAlphaChannel = FALSE;
- static BOOL versionChecked = FALSE;
+ static bool hasIconAlphaChannel = FALSE;
+ static bool versionChecked = FALSE;
if (!versionChecked) {
OSVERSIONINFOEX osvi = { 0 };
@@ -366,8 +372,8 @@ NetWMToWinIcon(int bpp, uint32_t * icon)
*/
static
- HICON
-winXIconToHICON(Display * pDisplay, Window id, int iconSize)
+HICON
+winXIconToHICON(xcb_connection_t *conn, xcb_window_t id, int iconSize)
{
unsigned char *mask, *image = NULL, *imageMask;
unsigned char *dst, *src;
@@ -375,16 +381,13 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
unsigned int biggest_size = 0;
HDC hDC;
ICONINFO ii;
- XWMHints *hints;
+ xcb_icccm_wm_hints_t hints;
HICON hIcon = NULL;
uint32_t *biggest_icon = NULL;
- static Atom _XA_NET_WM_ICON;
+ static xcb_atom_t _XA_NET_WM_ICON;
static int generation;
uint32_t *icon, *icon_data = NULL;
unsigned long int size;
- Atom type;
- int format;
- unsigned long int left;
hDC = GetDC(GetDesktopWindow());
planes = GetDeviceCaps(hDC, PLANES);
@@ -393,17 +396,31 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
/* Always prefer _NET_WM_ICON icons */
if (generation != serverGeneration) {
+ xcb_intern_atom_reply_t *atom_reply;
+ xcb_intern_atom_cookie_t atom_cookie;
+ const char *atomName = "_NET_WM_ICON";
+
generation = serverGeneration;
- _XA_NET_WM_ICON = XInternAtom(pDisplay, "_NET_WM_ICON", FALSE);
+
+ _XA_NET_WM_ICON = XCB_NONE;
+
+ atom_cookie = xcb_intern_atom(conn, 0, strlen(atomName), atomName);
+ atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
+ if (atom_reply) {
+ _XA_NET_WM_ICON = atom_reply->atom;
+ free(atom_reply);
+ }
}
- if ((XGetWindowProperty(pDisplay, id, _XA_NET_WM_ICON,
- 0, MAXINT, FALSE,
- AnyPropertyType, &type, &format, &size, &left,
- (unsigned char **) &icon_data) == Success) &&
- (icon_data != NULL)) {
- for (icon = icon_data; icon < &icon_data[size] && *icon;
- icon = &icon[icon[0] * icon[1] + 2]) {
+ {
+ xcb_get_property_cookie_t cookie = xcb_get_property(conn, FALSE, id, _XA_NET_WM_ICON, XCB_ATOM_CARDINAL, 0L, INT_MAX);
+ xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, NULL);
+
+ if (reply &&
+ ((icon_data = xcb_get_property_value(reply)) != NULL)) {
+ size = xcb_get_property_value_length(reply)/sizeof(uint32_t);
+ for (icon = icon_data; icon < &icon_data[size] && *icon;
+ icon = &icon[icon[0] * icon[1] + 2]) {
winDebug("winXIconToHICON: %u x %u NetIcon\n", icon[0], icon[1]);
/* Icon data size will overflow an int and thus is bigger than the
@@ -441,40 +458,46 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
hIcon = NetWMToWinIcon(bpp, biggest_icon);
}
- XFree(icon_data);
+ free(reply);
+ }
}
if (!hIcon) {
+ xcb_get_property_cookie_t wm_hints_cookie;
+
winDebug("winXIconToHICON: no suitable NetIcon\n");
- hints = XGetWMHints(pDisplay, id);
- if (hints) {
+ wm_hints_cookie = xcb_icccm_get_wm_hints(conn, id);
+ if (xcb_icccm_get_wm_hints_reply(conn, wm_hints_cookie, &hints, NULL)) {
winDebug("winXIconToHICON: id 0x%x icon_pixmap hint 0x%x\n",
(unsigned int)id,
- (unsigned int)hints->icon_pixmap);
-
- if (hints->icon_pixmap) {
- Window root;
- int x, y;
- unsigned int width, height, border_width, depth;
- XImage *xImageIcon;
- XImage *xImageMask = NULL;
-
- XGetGeometry(pDisplay, hints->icon_pixmap, &root, &x, &y,
- &width, &height, &border_width, &depth);
-
- xImageIcon =
- XGetImage(pDisplay, hints->icon_pixmap, 0, 0, width, height,
- 0xFFFFFFFF, ZPixmap);
- winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%p\n",
- (unsigned int)id, xImageIcon);
-
- if (hints->icon_mask)
- xImageMask =
- XGetImage(pDisplay, hints->icon_mask, 0, 0, width,
- height, 0xFFFFFFFF, ZPixmap);
-
- if (xImageIcon) {
+ (unsigned int)hints.icon_pixmap);
+
+ if (hints.icon_pixmap) {
+ unsigned int width, height;
+ xcb_image_t *xImageIcon;
+ xcb_image_t *xImageMask = NULL;
+
+ xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(conn, hints.icon_pixmap);
+ xcb_get_geometry_reply_t *geom_reply = xcb_get_geometry_reply(conn, geom_cookie, NULL);
+
+ if (geom_reply) {
+ width = geom_reply->width;
+ height = geom_reply->height;
+
+ xImageIcon = xcb_image_get(conn, hints.icon_pixmap,
+ 0, 0, width, height,
+ 0xFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
+
+ winDebug("winXIconToHICON: id 0x%x icon Ximage 0x%p\n",
+ (unsigned int)id, xImageIcon);
+
+ if (hints.icon_mask)
+ xImageMask = xcb_image_get(conn, hints.icon_mask,
+ 0, 0, width, height,
+ 0xFFFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
+
+ if (xImageIcon) {
int effBPP, stride, maskStride;
/* 15 BPP is really 16BPP as far as we care */
@@ -543,12 +566,12 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
free(imageMask);
if (xImageMask)
- XDestroyImage(xImageMask);
+ xcb_image_destroy(xImageMask);
- XDestroyImage(xImageIcon);
+ xcb_image_destroy(xImageIcon);
+ }
}
}
- XFree(hints);
}
}
return hIcon;
@@ -560,20 +583,22 @@ winXIconToHICON(Display * pDisplay, Window id, int iconSize)
#ifdef XWIN_MULTIWINDOW
void
-winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew)
+winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew)
{
HICON hIcon, hIconSmall = NULL, hIconOld;
- /* Start with the icon from preferences, if any */
- hIcon = hIconNew;
- hIconSmall = hIconNew;
-
- /* If we still need an icon, try and get the icon from WM_HINTS */
- if (!hIcon)
- hIcon = winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXICON));
- if (!hIconSmall)
- hIconSmall =
- winXIconToHICON(pDisplay, id, GetSystemMetrics(SM_CXSMICON));
+ if (hIconNew)
+ {
+ /* Start with the icon from preferences, if any */
+ hIcon = hIconNew;
+ hIconSmall = hIconNew;
+ }
+ else
+ {
+ /* If we still need an icon, try and get the icon from WM_HINTS */
+ hIcon = winXIconToHICON(conn, id, GetSystemMetrics(SM_CXICON));
+ hIconSmall = winXIconToHICON(conn, id, GetSystemMetrics(SM_CXSMICON));
+ }
/* If we got the small, but not the large one swap them */
if (!hIcon && hIconSmall) {
diff --git a/hw/xwin/winmultiwindowicons.h b/hw/xwin/winmultiwindowicons.h
index bf7f6eda7..87ba8d1cf 100644
--- a/hw/xwin/winmultiwindowicons.h
+++ b/hw/xwin/winmultiwindowicons.h
@@ -27,8 +27,10 @@
#ifndef WINMULTIWINDOWICONS_H
#define WINMULTIWINDOWICONS_H
+#include <xcb/xcb.h>
+
void
- winUpdateIcon(HWND hWnd, Display * pDisplay, Window id, HICON hIconNew);
+ winUpdateIcon(HWND hWnd, xcb_connection_t *conn, Window id, HICON hIconNew);
void
winInitGlobalIcons(void);
diff --git a/hw/xwin/winmultiwindowwindow.c b/hw/xwin/winmultiwindowwindow.c
index 6db576a92..e82d91591 100644
--- a/hw/xwin/winmultiwindowwindow.c
+++ b/hw/xwin/winmultiwindowwindow.c
@@ -35,9 +35,11 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
#include "win.h"
#include "dixevents.h"
#include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
/*
* Prototypes for local functions
diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index c5404cfe3..e594794c1 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -48,6 +48,7 @@
#include <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
#include <X11/Xlocale.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
@@ -62,6 +63,7 @@
#include "windowstr.h"
#include "winglobals.h"
#include "windisplay.h"
+#include "winmultiwindowicons.h"
#ifdef XWIN_MULTIWINDOWEXTWM
#include <X11/extensions/windowswmstr.h>
@@ -628,7 +630,7 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
}
}
- winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
+ winUpdateIcon(hWnd, XGetXCBConnection(pWMInfo->pDisplay), iWindow, hIconNew);
}
/*
diff --git a/hw/xwin/winprefs.c b/hw/xwin/winprefs.c
index 505292714..a180a9e8f 100644
--- a/hw/xwin/winprefs.c
+++ b/hw/xwin/winprefs.c
@@ -46,6 +46,7 @@
#include "winprefs.h"
#include "windisplay.h"
#include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
/* Where will the custom menu commands start counting from? */
#define STARTMENUID WM_USER
diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c
index 95b845230..52806887f 100644
--- a/hw/xwin/winwin32rootless.c
+++ b/hw/xwin/winwin32rootless.c
@@ -40,6 +40,7 @@
#define _WINDOWSWM_SERVER_
#include <X11/extensions/windowswmstr.h>
#include "winmultiwindowclass.h"
+#include "winmultiwindowicons.h"
#include <X11/Xatom.h>
/*