From abd24dd7453958d22ed57f7358dd3a33530ab2a2 Mon Sep 17 00:00:00 2001 From: Stu Black Date: Sat, 18 Apr 2026 19:54:46 -0400 Subject: [PATCH 1/3] Use a sed script instead of a shell script to fix up autogenerated WINGs FFI bindings. --- WINGs/wings-rs/Makefile.am | 5 +++-- WINGs/wings-rs/patch_WINGsP.sed | 10 ++++++++++ WINGs/wings-rs/patch_WINGsP.sh | 22 ---------------------- 3 files changed, 13 insertions(+), 24 deletions(-) create mode 100755 WINGs/wings-rs/patch_WINGsP.sed delete mode 100755 WINGs/wings-rs/patch_WINGsP.sh diff --git a/WINGs/wings-rs/Makefile.am b/WINGs/wings-rs/Makefile.am index 14eda0fe..f3fd5fc2 100644 --- a/WINGs/wings-rs/Makefile.am +++ b/WINGs/wings-rs/Makefile.am @@ -18,7 +18,7 @@ RUST_EXTRA = \ Cargo.lock \ Cargo.toml -src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sh +src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sed $(BINDGEN) ../WINGs/WINGsP.h \ --no-recursive-allowlist \ --allowlist-type "^W_.+|^WM(View|Array|DragOperationType|Point|Data|OpenPanel|SavePanel|HashTable|DraggingInfo|SelectionProcs|Rect|EventProc|Widget|Size|Pixmap|FilePanel|List|ListItem)" \ @@ -55,7 +55,8 @@ src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs -o src/WINGsP.rs -- \ @PANGO_CFLAGS@ \ -I../../wrlib \ - -I.. && ./patch_WINGsP.sh src/WINGsP.rs + -I.. \ + && sed -i -r -f patch_WINGsP.sed src/WINGsP.rs Cargo.lock: $(CARGO) build diff --git a/WINGs/wings-rs/patch_WINGsP.sed b/WINGs/wings-rs/patch_WINGsP.sed new file mode 100755 index 00000000..56b8a149 --- /dev/null +++ b/WINGs/wings-rs/patch_WINGsP.sed @@ -0,0 +1,10 @@ +# This file provides ad-hoc fixups to the WINGsP provided by bindgen: +# - Import Xlib symbols so that everything compiles. +# - Import FFI symbols from Rust bindings and rewrites. +# - The opaque type names _XftDraw and _XftFont are replaced with void*. +# - Pango bindings aren't yet pulled into our Rust code, so PangoLayout is also demoted to void*. + +1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\n/ +s/_XftDraw/::std::ffi::c_void/g +s/_XftFont/::std::ffi::c_void/g +s/PangoLayout/::std::ffi::c_void/g diff --git a/WINGs/wings-rs/patch_WINGsP.sh b/WINGs/wings-rs/patch_WINGsP.sh deleted file mode 100755 index 966ed1ea..00000000 --- a/WINGs/wings-rs/patch_WINGsP.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -# This file provides ad-hoc fixups to the WINGsP provided by bindgen: -# - Import Xlib symbols so that everything compiles. -# - The opaque type names _XftDraw and _XftFont are replaced with void*. -# - Pango bindings aren't yet pulled into our Rust code, so PangoLayout is also demoted to void*. - -set -e - -if [ "x$1" = "x" ]; then - echo "Usage: $(basename $0) " - exit 1 -fi - -FILE="$1" - -exec sed -i -r \ - -e "1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\n/" \ - -e "s/_XftDraw/::std::ffi::c_void/g" \ - -e "s/_XftFont/::std::ffi::c_void/g" \ - -e "s/PangoLayout/::std::ffi::c_void/g" \ - "$1" -- 2.39.5 From 784e896fad649dab508033d55f28bcde333a2178 Mon Sep 17 00:00:00 2001 From: Stu Black Date: Sat, 18 Apr 2026 19:54:08 -0400 Subject: [PATCH 2/3] Generate a distinct FFI module for constants in WINGs C headers. --- .gitignore | 2 ++ WINGs/wings-rs/Makefile.am | 21 ++++++++++++++++----- WINGs/wings-rs/patch_WINGsP.sed | 2 +- WINGs/wings-rs/src/defines.h | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 WINGs/wings-rs/src/defines.h diff --git a/.gitignore b/.gitignore index 82592007..eb0d3d85 100644 --- a/.gitignore +++ b/.gitignore @@ -155,6 +155,8 @@ WPrefs.app/WPrefs.desktop WINGs/wings-rs-tests/Cargo.lock WINGs/wings-rs/Cargo.lock WINGs/wings-rs/src/WINGsP.rs +WINGs/wings-rs/src/WINGsP/constants.rs +WINGs/wings-rs/src/WINGsP/mod.rs wmaker-rs/Cargo.lock wrlib-rs/src/ffi.rs wrlib-rs/Cargo.lock diff --git a/WINGs/wings-rs/Makefile.am b/WINGs/wings-rs/Makefile.am index f3fd5fc2..0464597c 100644 --- a/WINGs/wings-rs/Makefile.am +++ b/WINGs/wings-rs/Makefile.am @@ -1,7 +1,8 @@ AUTOMAKE_OPTIONS = RUST_SRC = \ - src/WINGsP.rs \ + src/WINGsP/constants.rs \ + src/WINGsP/mod.rs \ src/button.rs \ src/color.rs \ src/configuration.rs \ @@ -18,8 +19,9 @@ RUST_EXTRA = \ Cargo.lock \ Cargo.toml -src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sed - $(BINDGEN) ../WINGs/WINGsP.h \ +src/WINGsP/mod.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sed + mkdir -p src/WINGsP \ + && $(BINDGEN) ../WINGs/WINGsP.h \ --no-recursive-allowlist \ --allowlist-type "^W_.+|^WM(View|Array|DragOperationType|Point|Data|OpenPanel|SavePanel|HashTable|DraggingInfo|SelectionProcs|Rect|EventProc|Widget|Size|Pixmap|FilePanel|List|ListItem)" \ --allowlist-type "^WM(FontPanel|Screen|Button)" \ @@ -52,11 +54,18 @@ src/WINGsP.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs --allowlist-item "^WMAlignment" \ --allowlist-item "^WMReliefType" \ --allowlist-function "^WM(Create|Release|Draw)Pixmap|^WMCreate(|Blended|ScaledBlended)PixmapFromFile|^WMCreate(|Blended)PixmapFromRImage" \ - -o src/WINGsP.rs -- \ + -o src/WINGsP/mod.rs -- \ @PANGO_CFLAGS@ \ -I../../wrlib \ -I.. \ - && sed -i -r -f patch_WINGsP.sed src/WINGsP.rs + && sed -i -r -f patch_WINGsP.sed src/WINGsP/mod.rs + +src/WINGsP/constants.rs: src/WINGsP src/defines.h ../WINGs/WINGs.h Makefile + $(BINDGEN) src/defines.h \ + --allowlist-type WSystemIcon \ + -o src/WINGsP/constants.rs -- \ + -I../../wrlib \ + -I.. Cargo.lock: $(CARGO) build @@ -70,5 +79,7 @@ check-local: clean-local: $(CARGO) clean rm -f src/WINGsP.rs + rm -f src/WINGsP/constants.rs + rm -f src/WINGsP/mod.rs all: target/debug/libwings_rs.so diff --git a/WINGs/wings-rs/patch_WINGsP.sed b/WINGs/wings-rs/patch_WINGsP.sed index 56b8a149..939d6a15 100755 --- a/WINGs/wings-rs/patch_WINGsP.sed +++ b/WINGs/wings-rs/patch_WINGsP.sed @@ -4,7 +4,7 @@ # - The opaque type names _XftDraw and _XftFont are replaced with void*. # - Pango bindings aren't yet pulled into our Rust code, so PangoLayout is also demoted to void*. -1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\n/ +1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\npub mod constants;\n\n/ s/_XftDraw/::std::ffi::c_void/g s/_XftFont/::std::ffi::c_void/g s/PangoLayout/::std::ffi::c_void/g diff --git a/WINGs/wings-rs/src/defines.h b/WINGs/wings-rs/src/defines.h new file mode 100644 index 00000000..b10728f2 --- /dev/null +++ b/WINGs/wings-rs/src/defines.h @@ -0,0 +1,16 @@ +#include "../../WINGs/WINGs.h" + +typedef enum { + ReturnArrow = WSIReturnArrow, + HighlightedReturnArrow = WSIHighlightedReturnArrow, + ScrollerDimple = WSIScrollerDimple, + ArrowLeft = WSIArrowLeft, + HighlightedArrowLeft = WSIHighlightedArrowLeft, + ArrowRight = WSIArrowRight, + HighlightedArrowRight = WSIHighlightedArrowRight, + ArrowUp = WSIArrowUp, + HighlightedArrowUp = WSIHighlightedArrowUp, + ArrowDown = WSIArrowDown, + HighlightedArrowDown = WSIHighlightedArrowDown, + CheckMark = WSICheckMark, +} WSystemIcon; -- 2.39.5 From 70639c74622dcb86eb380c1f7dc95431565840fc Mon Sep 17 00:00:00 2001 From: Stu Black Date: Sun, 8 Mar 2026 00:40:39 -0500 Subject: [PATCH 3/3] Port WMPixmap to Rust. --- WINGs/Makefile.am | 1 - WINGs/WINGs/WINGs.h | 27 +- WINGs/WINGs/WINGsP.h.in | 101 ++- WINGs/dragsource.c | 6 +- WINGs/wappresource.c | 24 +- WINGs/wbutton.c | 38 +- WINGs/wcolorpanel.c | 24 +- WINGs/wfilepanel.c | 2 +- ...mpixmap_tests__empty_pixmap_on_window.snap | 2 +- ...p_tests__from_file_blended_with_grey.snap} | 2 +- ...ests__from_file_blended_with_grey.snap.png | Bin 0 -> 36778 bytes ...tests__from_file_blended_with_red.snap.png | Bin 37279 -> 0 bytes ...__from_file_scaled_blended_with_grey.snap} | 2 +- ...rom_file_scaled_blended_with_grey.snap.png | Bin 0 -> 12284 bytes ...from_file_scaled_blended_with_red.snap.png | Bin 12388 -> 0 bytes WINGs/wings-rs-tests/tests/wmpixmap_tests.rs | 53 +- WINGs/wings-rs/Makefile.am | 8 +- WINGs/wings-rs/patch_WINGsP.sed | 2 +- WINGs/wings-rs/src/defines.h | 6 +- WINGs/wings-rs/src/ffi.rs | 3 + WINGs/wings-rs/src/lib.rs | 1 + WINGs/wings-rs/src/pixmap.rs | 602 ++++++++++++++++++ WINGs/wlabel.c | 2 +- WINGs/wmisc.c | 43 +- WINGs/wpanel.c | 16 +- WINGs/wpixmap.c | 260 -------- WINGs/wpopupbutton.c | 42 +- WINGs/wscroller.c | 43 +- WINGs/wsplitview.c | 16 +- WINGs/wtext.c | 25 +- WINGs/wview.c | 4 +- WPrefs.app/HotCornerShortcuts.c | 28 +- WPrefs.app/MouseSettings.c | 7 +- WPrefs.app/WPrefs.c | 17 +- src/dialog.c | 30 +- src/dockedapp.c | 7 +- wrlib-rs/Makefile.am | 1 + wutil-rs/src/array.rs | 2 + 38 files changed, 870 insertions(+), 577 deletions(-) rename WINGs/wings-rs-tests/tests/snapshots/{wmpixmap_tests__from_file_blended_with_red.snap => wmpixmap_tests__from_file_blended_with_grey.snap} (85%) create mode 100644 WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap.png delete mode 100644 WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap.png rename WINGs/wings-rs-tests/tests/snapshots/{wmpixmap_tests__from_file_scaled_blended_with_red.snap => wmpixmap_tests__from_file_scaled_blended_with_grey.snap} (85%) create mode 100644 WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap.png delete mode 100644 WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_red.snap.png mode change 100755 => 100644 WINGs/wings-rs/patch_WINGsP.sed create mode 100644 WINGs/wings-rs/src/pixmap.rs delete mode 100644 WINGs/wpixmap.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 08dd0050..453e36c9 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -45,7 +45,6 @@ libWINGs_la_SOURCES = \ wmenuitem.c \ wmisc.c \ wpanel.c \ - wpixmap.c \ wpopupbutton.c \ wprogressindicator.c \ wruler.c \ diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h index 49df41da..4a68fa8b 100644 --- a/WINGs/WINGs/WINGs.h +++ b/WINGs/WINGs/WINGs.h @@ -688,8 +688,7 @@ void WMSetApplicationIconPixmap(WMScreen *app, WMPixmap *icon); WMPixmap* WMGetApplicationIconPixmap(WMScreen *app); -/* If color==NULL it will use the default color for panels: ae/aa/ae */ -WMPixmap* WMCreateApplicationIconBlendedPixmap(WMScreen *scr, const RColor *color); +WMPixmap* WMCreateApplicationIconGreyedPixmap(WMScreen *scr); void WMSetApplicationIconWindow(WMScreen *scr, Window window); @@ -833,23 +832,31 @@ WMSize WMGetPixmapSize(WMPixmap *pixmap); WMPixmap* WMCreatePixmapFromFile(WMScreen *scrPtr, const char *fileName); -WMPixmap* WMCreateBlendedPixmapFromRImage(WMScreen *scrPtr, RImage *image, - const RColor *color); +WMPixmap* WMCreateGreyedPixmapFromRImage(WMScreen *scrPtr, RImage *image); -WMPixmap* WMCreateBlendedPixmapFromFile(WMScreen *scrPtr, const char *fileName, - const RColor *color); +WMPixmap* WMCreateGreyedPixmapFromFile(WMScreen *scrPtr, const char *fileName); -WMPixmap* WMCreateScaledBlendedPixmapFromFile(WMScreen *scrPtr, const char *fileName, - const RColor *color, - unsigned int width, - unsigned int height); +WMPixmap* WMCreateScaledPixmapFromFile(WMScreen *scrPtr, const char *fileName, + unsigned int width, + unsigned int height); + +WMPixmap* WMCreateScaledGreyedPixmapFromFile(WMScreen *scrPtr, const char *fileName, + unsigned int width, + unsigned int height); void WMDrawPixmap(WMPixmap *pixmap, Drawable d, int x, int y); Pixmap WMGetPixmapXID(WMPixmap *pixmap); +/* Note that this can be used to deliberately leak the current pixmap. */ +void WMSetPixmapXID(WMPixmap *pixmap, Pixmap value); + Pixmap WMGetPixmapMaskXID(WMPixmap *pixmap); +void WMSetPixmapMaskXID(WMPixmap *pixmap, Pixmap mask); + +int WMGetPixmapDepth(WMPixmap *pixmap); + WMPixmap* WMGetSystemPixmap(WMScreen *scr, int image); /* ---[ WINGs/wings-rs/src/color.rs ]------------------------------------- */ diff --git a/WINGs/WINGs/WINGsP.h.in b/WINGs/WINGs/WINGsP.h.in index a3d45dfa..000bcacf 100644 --- a/WINGs/WINGs/WINGsP.h.in +++ b/WINGs/WINGs/WINGsP.h.in @@ -71,7 +71,7 @@ typedef struct W_DraggingInfo { typedef struct W_Color W_Color; /* Pre-definition of internal structs */ -typedef struct W_Pixmap W_Pixmap; +typedef struct W_Pixmap WMPixmap; typedef struct W_View W_View; typedef struct W_FocusInfo { @@ -106,7 +106,7 @@ typedef struct W_Screen { W_FocusInfo *focusInfo; RImage *applicationIconImage; /* image (can have alpha channel) */ - W_Pixmap *applicationIconPixmap; /* pixmap - no alpha channel */ + WMPixmap *applicationIconPixmap; /* pixmap - no alpha channel */ Window applicationIconWindow; struct W_Window *windowList; /* list of windows in the app */ @@ -165,57 +165,57 @@ typedef struct W_Screen { struct W_Balloon *balloon; - W_Pixmap *checkButtonImageOn; - W_Pixmap *checkButtonImageOff; + WMPixmap *checkButtonImageOn; + WMPixmap *checkButtonImageOff; - W_Pixmap *radioButtonImageOn; - W_Pixmap *radioButtonImageOff; + WMPixmap *radioButtonImageOn; + WMPixmap *radioButtonImageOff; - W_Pixmap *buttonArrow; - W_Pixmap *pushedButtonArrow; + WMPixmap *buttonArrow; + WMPixmap *pushedButtonArrow; - W_Pixmap *scrollerDimple; + WMPixmap *scrollerDimple; - W_Pixmap *upArrow; - W_Pixmap *downArrow; - W_Pixmap *leftArrow; - W_Pixmap *rightArrow; + WMPixmap *upArrow; + WMPixmap *downArrow; + WMPixmap *leftArrow; + WMPixmap *rightArrow; - W_Pixmap *hiUpArrow; - W_Pixmap *hiDownArrow; - W_Pixmap *hiLeftArrow; - W_Pixmap *hiRightArrow; + WMPixmap *hiUpArrow; + WMPixmap *hiDownArrow; + WMPixmap *hiLeftArrow; + WMPixmap *hiRightArrow; - W_Pixmap *pullDownIndicator; - W_Pixmap *popUpIndicator; + WMPixmap *pullDownIndicator; + WMPixmap *popUpIndicator; - W_Pixmap *checkMark; + WMPixmap *checkMark; - W_Pixmap *homeIcon; - W_Pixmap *altHomeIcon; + WMPixmap *homeIcon; + WMPixmap *altHomeIcon; - W_Pixmap *trashcanIcon; - W_Pixmap *altTrashcanIcon; + WMPixmap *trashcanIcon; + WMPixmap *altTrashcanIcon; - W_Pixmap *createDirIcon; - W_Pixmap *altCreateDirIcon; + WMPixmap *createDirIcon; + WMPixmap *altCreateDirIcon; - W_Pixmap *disketteIcon; - W_Pixmap *altDisketteIcon; - W_Pixmap *unmountIcon; - W_Pixmap *altUnmountIcon; + WMPixmap *disketteIcon; + WMPixmap *altDisketteIcon; + WMPixmap *unmountIcon; + WMPixmap *altUnmountIcon; - W_Pixmap *magnifyIcon; - /*W_Pixmap *altMagnifyIcon;*/ - W_Pixmap *wheelIcon; - W_Pixmap *grayIcon; - W_Pixmap *rgbIcon; - W_Pixmap *cmykIcon; - W_Pixmap *hsbIcon; - W_Pixmap *customPaletteIcon; - W_Pixmap *colorListIcon; + WMPixmap *magnifyIcon; + /*WMPixmap *altMagnifyIcon;*/ + WMPixmap *wheelIcon; + WMPixmap *grayIcon; + WMPixmap *rgbIcon; + WMPixmap *cmykIcon; + WMPixmap *hsbIcon; + WMPixmap *customPaletteIcon; + WMPixmap *colorListIcon; - W_Pixmap *defaultObjectIcon; + WMPixmap *defaultObjectIcon; Cursor defaultCursor; @@ -272,9 +272,9 @@ typedef struct W_Screen { * Added at the end of the structure to avoid breaking binary compatibility * with previous versions of the toolkit */ - W_Pixmap *tristateButtonImageOn; - W_Pixmap *tristateButtonImageOff; - W_Pixmap *tristateButtonImageTri; + WMPixmap *tristateButtonImageOn; + WMPixmap *tristateButtonImageOff; + WMPixmap *tristateButtonImageTri; } W_Screen; @@ -476,7 +476,7 @@ void W_DrawReliefWithGC(W_Screen *scr, Drawable d, int x, int y, void W_PaintTextAndImage(W_View *view, int wrap, WMColor *textColor, WMFont *font, WMReliefType relief, const char *text, - WMAlignment alignment, W_Pixmap *image, + WMAlignment alignment, WMPixmap *image, WMImagePosition position, WMColor *backColor, int ofs); void W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y, @@ -486,19 +486,6 @@ void W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y, int W_GetTextHeight(WMFont *font, const char *text, int width, int wrap); -/* ---[ wpixmap.c ]------------------------------------------------------- */ - -struct W_Pixmap { - struct W_Screen *screen; - Pixmap pixmap; - Pixmap mask; - unsigned short width; - unsigned short height; - short depth; - short refCount; -}; - - /* ---[ wview.c ]--------------------------------------------------------- */ typedef struct W_ViewDelegate { diff --git a/WINGs/dragsource.c b/WINGs/dragsource.c index c6bb9466..a97136e3 100644 --- a/WINGs/dragsource.c +++ b/WINGs/dragsource.c @@ -195,7 +195,7 @@ static Window makeDragIcon(WMScreen * scr, WMPixmap * pixmap) flags = CWSaveUnder | CWBackPixmap | CWOverrideRedirect | CWColormap; attribs.save_under = True; - attribs.background_pixmap = pixmap->pixmap; + attribs.background_pixmap = WMGetPixmapXID(pixmap); attribs.override_redirect = True; attribs.colormap = scr->colormap; @@ -203,8 +203,8 @@ static Window makeDragIcon(WMScreen * scr, WMPixmap * pixmap) size.height, 0, scr->depth, InputOutput, scr->visual, flags, &attribs); #ifdef USE_XSHAPE - if (pixmap->mask) { - XShapeCombineMask(scr->display, window, ShapeBounding, 0, 0, pixmap->mask, ShapeSet); + if (WMGetPixmapMaskXID(pixmap)) { + XShapeCombineMask(scr->display, window, ShapeBounding, 0, 0, WMGetPixmapMaskXID(pixmap), ShapeSet); } #endif diff --git a/WINGs/wappresource.c b/WINGs/wappresource.c index 013049c0..c0f54b79 100644 --- a/WINGs/wappresource.c +++ b/WINGs/wappresource.c @@ -63,8 +63,8 @@ void WMSetApplicationIconPixmap(WMScreen * scr, WMPixmap * icon) hints = XGetWMHints(scr->display, scr->groupLeader); hints->flags |= IconPixmapHint | IconMaskHint; - hints->icon_pixmap = (icon != NULL ? icon->pixmap : None); - hints->icon_mask = (icon != NULL ? icon->mask : None); + hints->icon_pixmap = (icon != NULL ? WMGetPixmapXID(icon) : None); + hints->icon_mask = (icon != NULL ? WMGetPixmapMaskXID(icon) : None); XSetWMHints(scr->display, scr->groupLeader, hints); XFree(hints); @@ -76,22 +76,12 @@ WMPixmap *WMGetApplicationIconPixmap(WMScreen * scr) return scr->applicationIconPixmap; } -WMPixmap *WMCreateApplicationIconBlendedPixmap(WMScreen * scr, const RColor * color) +WMPixmap *WMCreateApplicationIconGreyedPixmap(WMScreen * scr) { WMPixmap *pix; if (scr->applicationIconImage) { - static const RColor gray = { - /* red */ 0xAE, - /* green */ 0xAA, - /* blue */ 0xAE, - /* alpha */ 0xFF - }; - - if (!color) - color = &gray; - - pix = WMCreateBlendedPixmapFromRImage(scr, scr->applicationIconImage, color); + pix = WMCreateGreyedPixmapFromRImage(scr, scr->applicationIconImage); } else { pix = NULL; } @@ -133,10 +123,10 @@ void W_InitApplication(WMScreen * scr) */ if (scr->applicationIconPixmap) { hints->flags |= IconPixmapHint; - hints->icon_pixmap = scr->applicationIconPixmap->pixmap; - if (scr->applicationIconPixmap->mask) { + hints->icon_pixmap = WMGetPixmapXID(scr->applicationIconPixmap); + if (WMGetPixmapMaskXID(scr->applicationIconPixmap)) { hints->flags |= IconMaskHint; - hints->icon_mask = scr->applicationIconPixmap->mask; + hints->icon_mask = WMGetPixmapMaskXID(scr->applicationIconPixmap); } } diff --git a/WINGs/wbutton.c b/WINGs/wbutton.c index f8c23cd3..7312f949 100644 --- a/WINGs/wbutton.c +++ b/WINGs/wbutton.c @@ -15,11 +15,11 @@ typedef struct W_Button { WMColor *altTextColor; WMColor *disTextColor; - W_Pixmap *image; - W_Pixmap *altImage; - W_Pixmap *tsImage; + WMPixmap *image; + WMPixmap *altImage; + WMPixmap *tsImage; - W_Pixmap *dimage; + WMPixmap *dimage; void *clientData; WMAction *action; @@ -232,32 +232,32 @@ static void updateDisabledMask(WMButton * bPtr) if (bPtr->image) { XGCValues gcv; - if (bPtr->dimage->mask) { - XFreePixmap(dpy, bPtr->dimage->mask); - bPtr->dimage->mask = None; + if (WMGetPixmapMaskXID(bPtr->dimage)) { + XFreePixmap(dpy, WMGetPixmapMaskXID(bPtr->dimage)); + WMSetPixmapMaskXID(bPtr->dimage, 0); } if (bPtr->flags.dimsWhenDisabled) { - bPtr->dimage->mask = XCreatePixmap(dpy, scr->stipple, - bPtr->dimage->width, bPtr->dimage->height, 1); + WMSize size = WMGetPixmapSize(bPtr->dimage); + WMSetPixmapMaskXID(bPtr->dimage, XCreatePixmap(dpy, scr->stipple, size.width, size.height, 1)); XSetForeground(dpy, scr->monoGC, 0); - XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0, - bPtr->dimage->width, bPtr->dimage->height); + XFillRectangle(dpy, WMGetPixmapMaskXID(bPtr->dimage), scr->monoGC, 0, 0, + size.width, size.height); gcv.foreground = 1; gcv.background = 0; gcv.stipple = scr->stipple; gcv.fill_style = FillStippled; - gcv.clip_mask = bPtr->image->mask; + gcv.clip_mask = WMGetPixmapMaskXID(bPtr->image); gcv.clip_x_origin = 0; gcv.clip_y_origin = 0; XChangeGC(dpy, scr->monoGC, GCForeground | GCBackground | GCStipple | GCFillStyle | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv); - XFillRectangle(dpy, bPtr->dimage->mask, scr->monoGC, 0, 0, - bPtr->dimage->width, bPtr->dimage->height); + XFillRectangle(dpy, WMGetPixmapMaskXID(bPtr->dimage), scr->monoGC, 0, 0, + size.width, size.height); gcv.fill_style = FillSolid; gcv.clip_mask = None; @@ -279,15 +279,17 @@ void WMSetButtonImage(WMButton * bPtr, WMPixmap * image) bPtr->image = WMRetainPixmap(image); if (bPtr->dimage) { - bPtr->dimage->pixmap = None; + WMSetPixmapXID(bPtr->dimage, None); WMReleasePixmap(bPtr->dimage); bPtr->dimage = NULL; } if (image) { + WMSize size = WMGetPixmapSize(image); bPtr->dimage = WMCreatePixmapFromXPixmaps(WMWidgetScreen(bPtr), - image->pixmap, None, - image->width, image->height, image->depth); + WMGetPixmapXID(image), None, + size.width, size.height, + WMGetPixmapDepth(image)); updateDisabledMask(bPtr); } @@ -771,7 +773,7 @@ static void destroyButton(Button * bPtr) if (bPtr->dimage) { /* yuck.. kluge */ - bPtr->dimage->pixmap = None; + WMSetPixmapXID(bPtr->dimage, None); WMReleasePixmap(bPtr->dimage); } diff --git a/WINGs/wcolorpanel.c b/WINGs/wcolorpanel.c index 5ae526f5..f58c6a75 100644 --- a/WINGs/wcolorpanel.c +++ b/WINGs/wcolorpanel.c @@ -560,7 +560,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap, + W_PaintText(W_VIEW(panel->grayBrightnessS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Brightness"), strlen(_("Brightness"))); else @@ -581,7 +581,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) graybuttoncolor = WMCreateRGBColor(scrPtr, (255 / 6) * i << 8, (255 / 6) * i << 8, (255 / 6) * i << 8, True); - WMPaintColorSwatch(graybuttoncolor, pixmap->pixmap, 0, 0, 15, 15); + WMPaintColorSwatch(graybuttoncolor, WMGetPixmapXID(pixmap), 0, 0, 15, 15); WMReleaseColor(graybuttoncolor); panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm); @@ -635,7 +635,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->rgbRedS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Red"), strlen(_("Red"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -666,7 +666,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->rgbGreenS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Green"), strlen(_("Green"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -697,7 +697,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->rgbBlueS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Blue"), strlen(_("Blue"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -772,7 +772,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->cmykCyanS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Cyan"), strlen(_("Cyan"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -803,7 +803,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->cmykMagentaS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Magenta"), strlen(_("Magenta"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -835,7 +835,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->cmykYellowS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Yellow"), strlen(_("Yellow"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -868,7 +868,7 @@ static WMColorPanel *makeColorPanel(WMScreen * scrPtr, const char *name) RReleaseImage(image); if (pixmap) - W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12, + W_PaintText(W_VIEW(panel->cmykBlackS), WMGetPixmapXID(pixmap), panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Black"), strlen(_("Black"))); else wwarning(_("Color Panel: Could not allocate memory")); @@ -2711,7 +2711,7 @@ static void hsbUpdateBrightnessGradient(W_ColorPanel * panel) RReleaseImage(sliderImg); if (sliderPxmp) - W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap, + W_PaintText(W_VIEW(panel->hsbBrightnessS), WMGetPixmapXID(sliderPxmp), panel->font12, 2, 0, 100, WALeft, scr->white, False, _("Brightness"), strlen(_("Brightness"))); else @@ -2744,7 +2744,7 @@ static void hsbUpdateSaturationGradient(W_ColorPanel * panel) RReleaseImage(sliderImg); if (sliderPxmp) - W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, + W_PaintText(W_VIEW(panel->hsbSaturationS), WMGetPixmapXID(sliderPxmp), panel->font12, 2, 0, 100, WALeft, from.hsv.value < 128 ? scr->white : scr->black, False, _("Saturation"), strlen(_("Saturation"))); @@ -2779,7 +2779,7 @@ static void hsbUpdateHueGradient(W_ColorPanel * panel) RReleaseImage(sliderImg); if (sliderPxmp) - W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, + W_PaintText(W_VIEW(panel->hsbHueS), WMGetPixmapXID(sliderPxmp), panel->font12, 2, 0, 100, WALeft, hsvcolor.value < 128 ? scr->white : scr->black, False, _("Hue"), strlen(_("Hue"))); else diff --git a/WINGs/wfilepanel.c b/WINGs/wfilepanel.c index cb01ca1a..d620fa63 100644 --- a/WINGs/wfilepanel.c +++ b/WINGs/wfilepanel.c @@ -180,7 +180,7 @@ static WMFilePanel *makeFilePanel(WMScreen * scrPtr, const char *name, const cha WMResizeWidget(fPtr->iconLabel, 64, 64); WMMoveWidget(fPtr->iconLabel, 0, 0); WMSetLabelImagePosition(fPtr->iconLabel, WIPImageOnly); - icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL); + icon = WMCreateApplicationIconGreyedPixmap(scrPtr); if (icon) { WMSetLabelImage(fPtr->iconLabel, icon); WMReleasePixmap(icon); diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__empty_pixmap_on_window.snap b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__empty_pixmap_on_window.snap index 13c6fb0e..61d1314b 100644 --- a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__empty_pixmap_on_window.snap +++ b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__empty_pixmap_on_window.snap @@ -1,6 +1,6 @@ --- source: tests/wmpixmap_tests.rs -assertion_line: 63 +assertion_line: 56 expression: app.xvfb.png_screenshot() extension: png snapshot_kind: binary diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap similarity index 85% rename from WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap rename to WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap index b1482c84..fab3a044 100644 --- a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap +++ b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap @@ -1,6 +1,6 @@ --- source: tests/wmpixmap_tests.rs -assertion_line: 175 +assertion_line: 162 expression: app.xvfb.png_screenshot() extension: png snapshot_kind: binary diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap.png b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_grey.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..10189505b1df2bd5e9c015a35a934b7e276cde5b GIT binary patch literal 36778 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 B7J>i( literal 0 HcmV?d00001 diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap.png b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_blended_with_red.snap.png deleted file mode 100644 index c29171696d3e83a373d19f2566c9b5117ebf972c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37279 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 diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_red.snap b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap similarity index 85% rename from WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_red.snap rename to WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap index b4eb991a..1b86eafd 100644 --- a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_red.snap +++ b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap @@ -1,6 +1,6 @@ --- source: tests/wmpixmap_tests.rs -assertion_line: 239 +assertion_line: 220 expression: app.xvfb.png_screenshot() extension: png snapshot_kind: binary diff --git a/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap.png b/WINGs/wings-rs-tests/tests/snapshots/wmpixmap_tests__from_file_scaled_blended_with_grey.snap.png new file mode 100644 index 0000000000000000000000000000000000000000..d4b2ffe9aa8ae7b7d10afe57c2581b057082d442 GIT binary patch literal 12284 zcmeI2|3B0F|NkeIUP8n^-haa9ayh>~E|=%?^0+*{+;7*%{dRkP-_}Cz zAn+gn0Fbk?yloEv?0E_RNR1rWzdNGW`+Xb$&~CQ6ebeCyTgVNl2#av!EmGE5QCM^< zhzFYv0s@cb+`f7Lz2`oepI+WSe?-7I<6BnvQ&Q<6?eva12h}UbHLTTCvp@W9egyZj z^)|u&Ct3AF=WgGuMP|>%h$8Ypc@gX=7$GdE`dUlj5(;h7HF_AvM%(?i>P^^*m0V3N zJPH6D`T5G3_g_s!MHAXm0MpA>X-gIdUf3xC0B3&La|W|ms( z3mzxm&+KJFY|SIFUtlKd`o?*sPsiocH9GD7U-}Z+%1Pn&GIKOCrmr zI}pzzd}HL^6PX=4lC+MEAFhn$=jUD29o;(ps#1d*wOv^KZD1X27yo38fcYtQ0sy#e zzVE&!IQvgMQ&nJJc44n)2K-HjE(`}8*7Xb+veASIx=(EDcS~${0(8F%;LduKf!82TAGPmko{oIkU*RN}hhMZ8 z_Xq5|ANPj)8{%@+krH2hiJj1cFbxZbEcE+d)R03&Dk`H8;Wjhg0hDbzV z7Zd78;g9d7q@?(iIX1}zb61!-nnk4EBX0s!7e+>!h*XZSozE{hv|l>diZkOpW6-6-&bL z>%5ixeD!7PcN?OH_e13;12+$kQuRC~#q*34e-2iF*4Xs>)oIyrK4qqt zBzD$QkViS$AK$xunHzofHs#xD*n?AU?oU*&^fO6khWh^Yzj+n2N^K}(QW~r06-+ad zvgj}^zNb^9B+oD+D;96dvd|s2RY9lBEP$uIn2$7ZzwI5LmHLZs8{!3IcLB3wLyMe zX@X%)b5uS^Reqs@k_;TrQNXgGJ99aA`o1dFRVo4@i=C^#LsSDP(e*D0AlI2NLRq#m z+1C*2550z2^qCV|LkRYViEjOPVuNbnm>&b5?7<8vz%&Ip>334*edfk-Ur$L(15BUn zH64@Pu*XVG#Ty}M8FxyA&PbUH9K|O6Rvf=-i)vAa;iJ%4N&05MBhCZk6G^!Fy|&qS zvF?G4NQHnpW^04WBz-OcQK&w~jcf{y!K$!qr<>R<0@ zICl+ei$1yZz|KU~M(&A0IdAExw!TG=LCLsN9U6JnCPNff7@!&z71e8k1OPs%0D$tI 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 diff --git a/WINGs/wings-rs-tests/tests/wmpixmap_tests.rs b/WINGs/wings-rs-tests/tests/wmpixmap_tests.rs index 85d8fb65..753e4791 100644 --- a/WINGs/wings-rs-tests/tests/wmpixmap_tests.rs +++ b/WINGs/wings-rs-tests/tests/wmpixmap_tests.rs @@ -3,13 +3,9 @@ use std::{ ptr::{self, NonNull}, time::Instant, }; -use wings_rs::WINGsP::{ - WMCreateBlendedPixmapFromFile, WMCreateBlendedPixmapFromRImage, WMCreatePixmap, - WMCreatePixmapFromFile, WMCreatePixmapFromRImage, WMCreateScaledBlendedPixmapFromFile, - WMDrawPixmap, WMReleasePixmap, -}; +use wings_rs::pixmap::ffi::*; use wings_rs_tests::HeadlessApplication; -use wrlib_rs::ffi::{RColor, RLoadImage, RReleaseImage}; +use wrlib_rs::ffi::{RLoadImage, RReleaseImage}; #[test] fn draw_blank_pixmap() { @@ -34,9 +30,9 @@ fn draw_blank_pixmap() { while app.pump_event_queue(Instant::now()) {} assert_png_snapshot!("empty_window", app.xvfb.png_screenshot()); - let gc = x11::xlib::XCreateGC(display, (*pixmap.as_ptr()).pixmap, 0, ptr::null_mut()); + let gc = x11::xlib::XCreateGC(display, (*pixmap.as_ptr()).pixmap(), 0, ptr::null_mut()); x11::xlib::XSetForeground(display, gc, 0); - x11::xlib::XFillRectangle(display, (*pixmap.as_ptr()).pixmap, gc, 0, 0, 128, 196); + x11::xlib::XFillRectangle(display, (*pixmap.as_ptr()).pixmap(), gc, 0, 0, 128, 196); WMDrawPixmap(pixmap.as_ptr(), win, 64, 96); while app.pump_event_queue(Instant::now()) {} assert_png_snapshot!("empty_pixmap_on_window", app.xvfb.png_screenshot()); @@ -209,17 +205,8 @@ fn draw_blended_pixmap_from_r_image() { c"tests/image_128x120.png".as_ptr(), 0, ); - let pixmap = NonNull::new(WMCreateBlendedPixmapFromRImage( - app.screen.as_ptr(), - rimage, - &RColor { - red: 255, - green: 0, - blue: 0, - alpha: 255, - } as *const _, - )) - .unwrap(); + let pixmap = + NonNull::new(WMCreateGreyedPixmapFromRImage(app.screen.as_ptr(), rimage)).unwrap(); WMDrawPixmap(pixmap.as_ptr(), win, 70, 74); while app.pump_event_queue(Instant::now()) {} @@ -276,21 +263,15 @@ fn draw_blended_pixmap_from_file() { app.xvfb.png_screenshot() ); - let pixmap = NonNull::new(WMCreateBlendedPixmapFromFile( + let pixmap = NonNull::new(WMCreateGreyedPixmapFromFile( app.screen.as_ptr(), c"tests/image_with_transparent_dot_128x120.png".as_ptr(), - &RColor { - red: 255, - green: 0, - blue: 0, - alpha: 255, - } as *const _, )) .unwrap(); WMDrawPixmap(pixmap.as_ptr(), win, 64, 96); while app.pump_event_queue(Instant::now()) {} - assert_png_snapshot!("from_file_blended_with_red", app.xvfb.png_screenshot()); + assert_png_snapshot!("from_file_blended_with_grey", app.xvfb.png_screenshot()); WMReleasePixmap(pixmap.as_ptr()); } } @@ -346,15 +327,9 @@ fn draw_scaled_blended_pixmap_from_file() { app.xvfb.png_screenshot() ); - let pixmap = NonNull::new(WMCreateScaledBlendedPixmapFromFile( + let pixmap = NonNull::new(WMCreateScaledGreyedPixmapFromFile( app.screen.as_ptr(), c"tests/image_with_transparent_dot_128x120.png".as_ptr(), - &RColor { - red: 255, - green: 0, - blue: 0, - alpha: 255, - } as *const _, 60, 64, )) @@ -363,7 +338,7 @@ fn draw_scaled_blended_pixmap_from_file() { while app.pump_event_queue(Instant::now()) {} assert_png_snapshot!( - "from_file_scaled_blended_with_red", + "from_file_scaled_blended_with_grey", app.xvfb.png_screenshot() ); WMReleasePixmap(pixmap.as_ptr()); @@ -421,16 +396,10 @@ fn draw_scaled_blended_pixmap_from_file_non_integral_scaling() { app.xvfb.png_screenshot() ); - let pixmap = NonNull::new(WMCreateScaledBlendedPixmapFromFile( + let pixmap = NonNull::new(WMCreateScaledGreyedPixmapFromFile( app.screen.as_ptr(), // No alpha channel on this image, so no color blending happens. c"tests/image_128x120.png".as_ptr(), - &RColor { - red: 255, - green: 0, - blue: 0, - alpha: 255, - } as *const _, // Shrink by only a little bit, such that simple integer division // might be thrown off. This test ensures that rescaling will // actually happen. diff --git a/WINGs/wings-rs/Makefile.am b/WINGs/wings-rs/Makefile.am index 0464597c..26d4f663 100644 --- a/WINGs/wings-rs/Makefile.am +++ b/WINGs/wings-rs/Makefile.am @@ -12,6 +12,7 @@ RUST_SRC = \ src/lib.rs \ src/list.rs \ src/pango_extras.rs \ + src/pixmap.rs \ src/screen.rs \ src/widget.rs @@ -19,12 +20,14 @@ RUST_EXTRA = \ Cargo.lock \ Cargo.toml -src/WINGsP/mod.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sed + src/WINGsP/mod.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../WINGs/WUtil.h Makefile patch_WINGsP.sed mkdir -p src/WINGsP \ && $(BINDGEN) ../WINGs/WINGsP.h \ --no-recursive-allowlist \ - --allowlist-type "^W_.+|^WM(View|Array|DragOperationType|Point|Data|OpenPanel|SavePanel|HashTable|DraggingInfo|SelectionProcs|Rect|EventProc|Widget|Size|Pixmap|FilePanel|List|ListItem)" \ + --allowlist-type "^W_.+|^WM(View|DragOperationType|Point|Data|OpenPanel|SavePanel|HashTable|DraggingInfo|SelectionProcs|Rect|EventProc|Widget|Size|FilePanel|List|ListItem)" \ --allowlist-type "^WM(FontPanel|Screen|Button)" \ + --allowlist-type "^W_(Screen|View|DragSourceProcs|ViewDelegate|DragDestinationProcs|Data|HashTable|Button|FilePanel|DraggingInfo|IMContext|Window|FocusInfo|SelectionHandlers|FontPanel|DragSourceInfo|DragDestinationInfo|ColorPanel|Balloon|DndState)" \ + --allowlist-type "^WM(View|DragOperationType|Point|Data|OpenPanel|SavePanel|HashTable|DraggingInfo|SelectionProcs|Rect|EventProc|Widget|Size|FilePanel|FontPanel|Screen|Button)|_WINGsConfiguration" \ --allowlist-function "^WMCreateScreen|^WM(Get|Show)FontPanel|^WMCreateCommandButton|^WM(Initialize|Release)Application|^WMScreenMainLoop|^WMHandleEvent" \ --allowlist-function "^WMWidgetScreen|^WM(Initialize|Release)Application|^WM(ScreenMainLoop|HandleEvent)|^WM(((Get|Set)TextFieldFont)|GetTextFieldText|SetTextFieldText|SelectTextFieldRange)" \ --allowlist-type "WMList" \ @@ -53,7 +56,6 @@ src/WINGsP/mod.rs: ../WINGs/WINGsP.h ../../wrlib/wraster.h ../WINGs/WINGs.h ../W --allowlist-type "_WINGsConfiguration" \ --allowlist-item "^WMAlignment" \ --allowlist-item "^WMReliefType" \ - --allowlist-function "^WM(Create|Release|Draw)Pixmap|^WMCreate(|Blended|ScaledBlended)PixmapFromFile|^WMCreate(|Blended)PixmapFromRImage" \ -o src/WINGsP/mod.rs -- \ @PANGO_CFLAGS@ \ -I../../wrlib \ diff --git a/WINGs/wings-rs/patch_WINGsP.sed b/WINGs/wings-rs/patch_WINGsP.sed old mode 100755 new mode 100644 index 939d6a15..21f58ca1 --- a/WINGs/wings-rs/patch_WINGsP.sed +++ b/WINGs/wings-rs/patch_WINGsP.sed @@ -4,7 +4,7 @@ # - The opaque type names _XftDraw and _XftFont are replaced with void*. # - Pango bindings aren't yet pulled into our Rust code, so PangoLayout is also demoted to void*. -1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\npub mod constants;\n\n/ +1s/^/use wrlib_rs::ffi::*;\nuse wutil_rs::array::ffi::*;\nuse wutil_rs::range::ffi::*;\nuse x11::xlib::*;\nuse crate::ffi::*;\n\npub mod constants;\n\n/ s/_XftDraw/::std::ffi::c_void/g s/_XftFont/::std::ffi::c_void/g s/PangoLayout/::std::ffi::c_void/g diff --git a/WINGs/wings-rs/src/defines.h b/WINGs/wings-rs/src/defines.h index b10728f2..dad7bdce 100644 --- a/WINGs/wings-rs/src/defines.h +++ b/WINGs/wings-rs/src/defines.h @@ -1,6 +1,8 @@ +// Exposes preprocessor symbol constants as an enum so that bindgen can see them. + #include "../../WINGs/WINGs.h" -typedef enum { +enum WSystemIcon { ReturnArrow = WSIReturnArrow, HighlightedReturnArrow = WSIHighlightedReturnArrow, ScrollerDimple = WSIScrollerDimple, @@ -13,4 +15,4 @@ typedef enum { ArrowDown = WSIArrowDown, HighlightedArrowDown = WSIHighlightedArrowDown, CheckMark = WSICheckMark, -} WSystemIcon; +}; diff --git a/WINGs/wings-rs/src/ffi.rs b/WINGs/wings-rs/src/ffi.rs index 3ef6248c..b0727f16 100644 --- a/WINGs/wings-rs/src/ffi.rs +++ b/WINGs/wings-rs/src/ffi.rs @@ -1,2 +1,5 @@ +//! Provides reexports of all public FFI symbols, for convenience. + pub use crate::color::ffi::*; pub use crate::font::ffi::*; +pub use crate::pixmap::ffi::*; diff --git a/WINGs/wings-rs/src/lib.rs b/WINGs/wings-rs/src/lib.rs index 4364ee1b..6afff5f5 100644 --- a/WINGs/wings-rs/src/lib.rs +++ b/WINGs/wings-rs/src/lib.rs @@ -11,5 +11,6 @@ pub mod font; pub mod font_panel; pub mod list; pub(crate) mod pango_extras; +pub mod pixmap; pub mod screen; pub mod widget; diff --git a/WINGs/wings-rs/src/pixmap.rs b/WINGs/wings-rs/src/pixmap.rs new file mode 100644 index 00000000..c10a4aae --- /dev/null +++ b/WINGs/wings-rs/src/pixmap.rs @@ -0,0 +1,602 @@ +use crate::WINGsP; +use std::{ + cell::RefCell, + ffi::CStr, + ptr::NonNull, +}; + +pub struct Pixmap { + display: NonNull, + clip_gc: x11::xlib::GC, + pixmap: RefCell, + mask: RefCell, + width: u16, + height: u16, + depth: u16, +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum Masked { + Yes, + No, +} + +impl Pixmap { + pub fn new(screen: NonNull, width: u16, height: u16, depth: u16, masked: Masked) -> Self { + let display = NonNull::new(unsafe { (*screen.as_ptr()).display }).unwrap(); + let drawable = unsafe { (*(*screen.as_ptr()).rcontext).drawable }; + let clip_gc = unsafe { (*screen.as_ptr()).clipGC }; + let pixmap = unsafe { x11::xlib::XCreatePixmap(display.as_ptr(), drawable, width.into(), height.into(), depth.into()) }; + let mask = match masked { + Masked::Yes => RefCell::new(unsafe { x11::xlib::XCreatePixmap(display.as_ptr(), drawable, width.into(), height.into(), 1) }), + Masked::No => RefCell::new(0), + }; + Pixmap { + display, + clip_gc, + pixmap: RefCell::new(pixmap), + mask, + width, + height, + depth, + } + } + + pub fn new_from_x_pixmaps( + screen: NonNull, + pixmap: x11::xlib::Pixmap, + mask: x11::xlib::Pixmap, + width: u16, + height: u16, + depth: u16, + ) -> Self { + let display = NonNull::new(unsafe { (*screen.as_ptr()).display }).unwrap(); + let clip_gc = unsafe { (*screen.as_ptr()).clipGC }; + Pixmap { + display, + clip_gc, + pixmap: RefCell::new(pixmap), + mask: RefCell::new(mask), + width, + height, + depth, + } + } + + pub fn new_from_file( + screen: NonNull, + file_name: &CStr, + ) -> Option { + let rcontext = NonNull::new(unsafe { (*screen.as_ptr()).rcontext }).unwrap(); + let Some(image) = NonNull::new(unsafe { wrlib_rs::ffi::RLoadImage(rcontext.as_ptr(), file_name.as_ptr(), 0) }) else { + return None; + }; + let result = Self::new_from_r_image(screen, image, 127); + unsafe { wrlib_rs::ffi::RReleaseImage(image.as_ptr()) }; + result + } + + pub fn new_from_r_image( + screen: NonNull, + image: NonNull, + threshold: u16, + ) -> Option { + let display = NonNull::new(unsafe { (*screen.as_ptr()).display }).unwrap(); + let clip_gc = unsafe { (*screen.as_ptr()).clipGC }; + let depth: u16 = unsafe { (*screen.as_ptr()).depth.try_into().expect("invalid depth") }; + let rcontext = NonNull::new(unsafe { (*screen.as_ptr()).rcontext }).unwrap(); + let mut pixmap: x11::xlib::Pixmap = 0; + let mut mask: x11::xlib::Pixmap = 0; + if unsafe { wrlib_rs::ffi::RConvertImageMask(rcontext.as_ptr(), image.as_ptr(), &mut pixmap, &mut mask, threshold.into()) } == 0 { + return None; + } + + let (width, height) = unsafe { + ((*image.as_ptr()).width.try_into().expect("invalid width"), + (*image.as_ptr()).height.try_into().expect("invalid height")) + }; + Some(Pixmap { + display, + clip_gc, + pixmap: RefCell::new(pixmap), + mask: RefCell::new(mask), + width, + height, + depth, + }) + } + + pub fn draw(&self, drawable: x11::xlib::Drawable, x: i32, y: i32) { + unsafe { + x11::xlib::XSetClipMask(self.display.as_ptr(), self.clip_gc, *self.mask.borrow()); + x11::xlib::XSetClipOrigin(self.display.as_ptr(), self.clip_gc, x, y); + x11::xlib::XCopyArea( + self.display.as_ptr(), + *self.pixmap.borrow(), + drawable, + self.clip_gc, + 0, + 0, + self.width.into(), + self.height.into(), + x, + y, + ); + } + } + + pub fn pixmap(&self) -> x11::xlib::Pixmap { + *self.pixmap.borrow() + } + + pub fn mask(&self) -> x11::xlib::Pixmap { + *self.mask.borrow() + } +} + +/// Attempts to load an `RImage` from `file_name` and returns the value of invoking `f` on it. +/// +/// If image loading fails, `f` is invoked on a `None` value. +/// +/// For example: +/// +/// ```ignore +/// # use std::ffi::CString; +/// # use wings_rs::pixmap::with_r_image_from_file; +/// # fn main() { +/// # let rcontext = unsafe { wrlib_rs::RCreateContext(display, 0, ptr::null_mut()) }; +/// let (width, height) = with_r_image_from_file( +/// rcontext, +/// &CString::new("test_image_32x48.png").unwrap(), +/// |image| { +/// let image = image.expect("image loading failed"); +/// ((*image.as_ptr()).width, (*image.as_ptr()).height) +/// } +/// ); +/// assert_eq!(width, 32); +/// assert_eq!(height, 48); +/// # unsafe { wrlib_rs::RDestroyContext(rcontext); } +/// # } +/// ``` +pub fn with_r_image_from_file( + rcontext: NonNull, + file_name: &CStr, + f: impl FnOnce(Option>) -> R, +) -> R { + let image = NonNull::new(unsafe { + wrlib_rs::ffi::RLoadImage(rcontext.as_ptr(), file_name.as_ptr(), 0) + }); + let result = f(image); + if let Some(image) = image { + unsafe { wrlib_rs::ffi::RReleaseImage(image.as_ptr()); } + } + result +} + +#[derive(Clone, Copy, Eq, PartialEq, Debug)] +pub enum Transform { + Downscale { width: u32, height: u32 }, + Greymask, +} + +impl Transform { + pub fn with_transformed( + mut image: NonNull, + transforms: &[Transform], + f: impl FnOnce(NonNull) -> R, + ) -> R { + let mut transforms_i = transforms.iter(); + if let Some(t) = transforms_i.next() { + image = t.apply(image); + } + for t in transforms_i { + let next_image = t.apply(image); + unsafe { wrlib_rs::ffi::RReleaseImage(image.as_ptr()); } + image = next_image; + } + let result = f(image); + if !transforms.is_empty() { + unsafe { wrlib_rs::ffi::RReleaseImage(image.as_ptr()); } + } + result + } + + fn apply( + &self, + image: NonNull, + ) -> NonNull { + match self { + Transform::Downscale { width, height } => { + let Ok(current_width): Result = (unsafe { (*image.as_ptr()).width.try_into() }) else { + return image; + }; + let Ok(current_height): Result = (unsafe { (*image.as_ptr()).height.try_into() }) else { + return image; + }; + if current_width <= *width && current_height <= *height { + return image; + } + + let mut new_width = current_width; + let mut new_height = current_height; + if new_width > *width { + new_width = *width; + new_height = *width * current_height / current_width; + } + if new_height > *height { + new_width = *height * current_width / current_height; + new_height = *height; + } + let image = unsafe { wrlib_rs::ffi::RScaleImage(image.as_ptr(), new_width, new_height) }; + NonNull::new(image).expect("RScaleImage failed") + } + Transform::Greymask => { + const GREY: wrlib_rs::ffi::RColor = wrlib_rs::ffi::RColor { + red: 0xAE, + green: 0xAA, + blue: 0xAE, + alpha: 0xFF, + }; + unsafe { + let result = NonNull::new(wrlib_rs::ffi::RCloneImage(image.as_ptr())) + .expect("RCloneImage failed"); + wrlib_rs::ffi::RCombineImageWithColor(result.as_ptr(), &GREY as *const _); + result + } + } + } + } +} + +impl Drop for Pixmap { + fn drop(&mut self) { + unsafe { + if *self.pixmap.borrow() != 0 { + x11::xlib::XFreePixmap(self.display.as_ptr(), *self.pixmap.borrow()); + } + if *self.mask.borrow() != 0 { + x11::xlib::XFreePixmap(self.display.as_ptr(), *self.mask.borrow()); + } + } + } +} + +pub mod ffi { + use super::*; + use std::{ + ffi::{c_char, c_int, c_uint, c_ushort}, + ptr, + rc::Rc, + }; + + pub type WMPixmap = Rc; + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMRetainPixmap(pixmap: *mut WMPixmap) -> *mut WMPixmap { + if pixmap.is_null() { + return ptr::null_mut(); + } + Box::leak(Box::new(unsafe { (*pixmap).clone() })) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMReleasePixmap(pixmap: *mut WMPixmap) { + let _ = unsafe { Box::from_raw(pixmap) }; + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreatePixmap( + screen: *mut WINGsP::WMScreen, + width: c_ushort, + height: c_ushort, + depth: c_ushort, + masked: c_int, + ) -> *mut WMPixmap { + let pixmap = Pixmap::new( + NonNull::new(screen).expect("pixmap screen cannot be null"), + width, + height, + depth, + if masked == 0 { + Masked::No + } else { + Masked::Yes + }, + ); + Box::leak(Box::new(Rc::new(pixmap))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreatePixmapFromXPixmaps( + screen: *mut WINGsP::WMScreen, + pixmap: x11::xlib::Pixmap, + mask: x11::xlib::Pixmap, + width: c_ushort, + height: c_ushort, + depth: c_ushort, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + let pixmap = Pixmap::new_from_x_pixmaps( + screen, + pixmap, + mask, + width, + height, + depth, + ); + Box::leak(Box::new(Rc::new(pixmap))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreatePixmapFromFile( + screen: *mut WINGsP::WMScreen, + file_name: *const c_char, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + if file_name.is_null() { + return ptr::null_mut(); + } + let file_name = unsafe { CStr::from_ptr(file_name) }; + let Some(pixmap) = Pixmap::new_from_file(screen, file_name) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(pixmap))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreatePixmapFromRImage( + screen: *mut WINGsP::WMScreen, + image: *mut wrlib_rs::ffi::RImage, + threshold: c_ushort, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + let Some(image) = NonNull::new(image) else { + return ptr::null_mut(); + }; + let Some(pixmap) = Pixmap::new_from_r_image( + screen, + image, + threshold, + ) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(pixmap))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreateGreyedPixmapFromRImage( + screen: *mut WINGsP::WMScreen, + image: *mut wrlib_rs::ffi::RImage, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + let image = NonNull::new(image).expect("image cannot be null"); + let Some(result) = Transform::with_transformed( + image, + &[Transform::Greymask], + |image| Pixmap::new_from_r_image(screen, image, 0)) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(result))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreateScaledPixmapFromFile( + screen: *mut WINGsP::WMScreen, + file_name: *const c_char, + width: c_uint, + height: c_uint, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + if file_name.is_null() { + return ptr::null_mut(); + } + let file_name = unsafe { CStr::from_ptr(file_name) }; + let Some(rcontext) = NonNull::new(unsafe { (*screen.as_ptr()).rcontext }) else { + return ptr::null_mut(); + }; + let Some(result) = + with_r_image_from_file( + rcontext, + file_name, + |image| { + let Some(image) = image else { + return None; + }; + Transform::with_transformed( + image, + &[Transform::Downscale { width, height }], + |image| Pixmap::new_from_r_image(screen, image, 0), + ) + } + ) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(result))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreateGreyedPixmapFromFile( + screen: *mut WINGsP::WMScreen, + file_name: *const c_char, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + if file_name.is_null() { + return ptr::null_mut(); + } + let file_name = unsafe { CStr::from_ptr(file_name) }; + let Some(rcontext) = NonNull::new(unsafe { (*screen.as_ptr()).rcontext }) else { + return ptr::null_mut(); + }; + let Some(result) = + with_r_image_from_file( + rcontext, + file_name, + |image| { + let Some(image) = image else { + return None; + }; + Transform::with_transformed( + image, + &[Transform::Greymask], + |image| Pixmap::new_from_r_image(screen, image, 0), + ) + } + ) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(result))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreateScaledGreyedPixmapFromFile( + screen: *mut WINGsP::WMScreen, + file_name: *const c_char, + width: c_uint, + height: c_uint, + ) -> *mut WMPixmap { + let Some(screen) = NonNull::new(screen) else { + return ptr::null_mut(); + }; + if file_name.is_null() { + return ptr::null_mut(); + } + let file_name = unsafe { CStr::from_ptr(file_name) }; + let Some(rcontext) = NonNull::new(unsafe { (*screen.as_ptr()).rcontext }) else { + return ptr::null_mut(); + }; + let Some(result) = with_r_image_from_file( + rcontext, + file_name, + |image| { + let Some(image) = image else { + return None; + }; + Transform::with_transformed( + image, + &[Transform::Downscale { width, height }, + Transform::Greymask], + |image| Pixmap::new_from_r_image(screen, image, 0), + ) + }, + ) else { + return ptr::null_mut(); + }; + Box::leak(Box::new(Rc::new(result))) as *mut _ + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMCreatePixmapFromXPMData( + screen: *mut WINGsP::WMScreen, + data: *mut *mut c_char, + ) -> *mut WMPixmap { + todo!() + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMGetPixmapXID(pixmap: *mut WMPixmap) -> x11::xlib::Pixmap { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + unsafe { *(&(*pixmap.as_ptr())).pixmap.borrow() } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMSetPixmapXID(pixmap: *mut WMPixmap, value: x11::xlib::Pixmap) { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + unsafe { *(&mut (*pixmap.as_ptr())).pixmap.borrow_mut() = value; } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMGetPixmapMaskXID(pixmap: *mut WMPixmap) -> x11::xlib::Pixmap { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + unsafe { *(&(*pixmap.as_ptr())).mask.borrow() } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMSetPixmapMaskXID(pixmap: *mut WMPixmap, mask: x11::xlib::Pixmap) { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + unsafe { *(&mut (*pixmap.as_ptr())).mask.borrow_mut() = mask; } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMGetPixmapSize(pixmap: *mut WMPixmap) -> WINGsP::WMSize { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + let (width, height) = unsafe { + ((&(*pixmap.as_ptr())).width, (&(*pixmap.as_ptr())).height) + }; + WINGsP::WMSize { + width: width.into(), + height: height.into(), + } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMGetPixmapDepth(pixmap: *mut WMPixmap) -> c_int { + let pixmap = NonNull::new(pixmap).expect("pixmap cannot be null"); + + unsafe { (&(*pixmap.as_ptr())).depth.into() } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMGetSystemPixmap(screen: *mut WINGsP::WMScreen, image: c_uint) -> *mut WMPixmap { + unsafe { + let screen = &*screen; + match image { + WINGsP::constants::WSystemIcon_ReturnArrow => WMRetainPixmap(screen.buttonArrow), + WINGsP::constants::WSystemIcon_HighlightedReturnArrow => WMRetainPixmap(screen.pushedButtonArrow), + WINGsP::constants::WSystemIcon_ScrollerDimple => WMRetainPixmap(screen.scrollerDimple), + WINGsP::constants::WSystemIcon_ArrowLeft => WMRetainPixmap(screen.leftArrow), + WINGsP::constants::WSystemIcon_HighlightedArrowLeft => WMRetainPixmap(screen.hiLeftArrow), + WINGsP::constants::WSystemIcon_ArrowRight => WMRetainPixmap(screen.rightArrow), + WINGsP::constants::WSystemIcon_HighlightedArrowRight => WMRetainPixmap(screen.hiRightArrow), + WINGsP::constants::WSystemIcon_ArrowUp => WMRetainPixmap(screen.upArrow), + WINGsP::constants::WSystemIcon_HighlightedArrowUp => WMRetainPixmap(screen.hiUpArrow), + WINGsP::constants::WSystemIcon_ArrowDown => WMRetainPixmap(screen.downArrow), + WINGsP::constants::WSystemIcon_HighlightedArrowDown => WMRetainPixmap(screen.hiDownArrow), + WINGsP::constants::WSystemIcon_CheckMark => WMRetainPixmap(screen.checkMark), + _ => ptr::null_mut(), + } + } + } + + #[unsafe(no_mangle)] + pub unsafe extern "C" fn WMDrawPixmap( + pixmap: *mut WMPixmap, + drawable: x11::xlib::Drawable, + x: c_int, + y: c_int, + ) { + unsafe { + let pixmap = &*pixmap; + x11::xlib::XSetClipMask(pixmap.display.as_ptr(), pixmap.clip_gc, *pixmap.mask.borrow()); + x11::xlib::XSetClipOrigin(pixmap.display.as_ptr(), pixmap.clip_gc, x, y); + x11::xlib::XCopyArea( + pixmap.display.as_ptr(), + *pixmap.pixmap.borrow(), + drawable, + pixmap.clip_gc, + 0, + 0, + pixmap.width.into(), + pixmap.height.into(), + x, + y, + ); + } + } +} diff --git a/WINGs/wlabel.c b/WINGs/wlabel.c index 9726cb15..9445a4ee 100644 --- a/WINGs/wlabel.c +++ b/WINGs/wlabel.c @@ -10,7 +10,7 @@ typedef struct W_Label { WMColor *textColor; WMFont *font; /* if NULL, use default */ - W_Pixmap *image; + WMPixmap *image; struct { WMReliefType relief:3; diff --git a/WINGs/wmisc.c b/WINGs/wmisc.c index 68b98e2b..4623e4ba 100644 --- a/WINGs/wmisc.c +++ b/WINGs/wmisc.c @@ -203,7 +203,7 @@ W_PaintText(W_View * view, Drawable d, WMFont * font, int x, int y, void W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, WMFont * font, WMReliefType relief, const char *text, - WMAlignment alignment, W_Pixmap * image, + WMAlignment alignment, WMPixmap * image, WMImagePosition position, WMColor * backColor, int ofs) { W_Screen *screen = view->screen; @@ -250,11 +250,12 @@ W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, WMFont * font, /* calc. image alignment */ if (position != WIPNoImage && image != NULL) { + WMSize size = WMGetPixmapSize(image); switch (position) { case WIPOverlaps: case WIPImageOnly: - ix = (view->size.width - image->width) / 2; - iy = (view->size.height - image->height) / 2; + ix = (view->size.width - size.width) / 2; + iy = (view->size.height - size.height) / 2; /* x = 2; y = 0; @@ -263,31 +264,31 @@ W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, WMFont * font, case WIPLeft: ix = x; - iy = y + (h - image->height) / 2; - x = x + image->width + 5; + iy = y + (h - size.height) / 2; + x = x + size.width + 5; y = 0; - w -= image->width + 5; + w -= size.width + 5; break; case WIPRight: - ix = view->size.width - image->width - x; - iy = y + (h - image->height) / 2; - w -= image->width + 5; + ix = view->size.width - size.width - x; + iy = y + (h - size.height) / 2; + w -= size.width + 5; break; case WIPBelow: - ix = (view->size.width - image->width) / 2; - iy = h - image->height; + ix = (view->size.width - size.width) / 2; + iy = h - size.height; y = 0; - h -= image->height; + h -= size.height; break; default: case WIPAbove: - ix = (view->size.width - image->width) / 2; + ix = (view->size.width - size.width) / 2; iy = y; - y = image->height; - h -= image->height; + y = size.height; + h -= size.height; break; } @@ -295,14 +296,14 @@ W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, WMFont * font, iy += ofs; XSetClipOrigin(screen->display, screen->clipGC, ix, iy); - XSetClipMask(screen->display, screen->clipGC, image->mask); + XSetClipMask(screen->display, screen->clipGC, WMGetPixmapMaskXID(image)); - if (image->depth == 1) - XCopyPlane(screen->display, image->pixmap, d, screen->clipGC, - 0, 0, image->width, image->height, ix, iy, 1); + if (WMGetPixmapDepth(image) == 1) + XCopyPlane(screen->display, WMGetPixmapXID(image), d, screen->clipGC, + 0, 0, size.width, size.height, ix, iy, 1); else - XCopyArea(screen->display, image->pixmap, d, screen->clipGC, - 0, 0, image->width, image->height, ix, iy); + XCopyArea(screen->display, WMGetPixmapXID(image), d, screen->clipGC, + 0, 0, size.width, size.height, ix, iy); } /* draw text */ diff --git a/WINGs/wpanel.c b/WINGs/wpanel.c index a0220487..3d8be03a 100644 --- a/WINGs/wpanel.c +++ b/WINGs/wpanel.c @@ -124,7 +124,7 @@ WMAlertPanel *WMCreateAlertPanel(WMScreen * scrPtr, WMWindow * owner, WMSetLabelImagePosition(panel->iLbl, WIPImageOnly); WMMapWidget(panel->iLbl); WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10); - icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL); + icon = WMCreateApplicationIconGreyedPixmap(scrPtr); if (icon) { WMSetLabelImage(panel->iLbl, icon); WMReleasePixmap(icon); @@ -181,7 +181,7 @@ WMAlertPanel *WMCreateAlertPanel(WMScreen * scrPtr, WMWindow * owner, if (defaultButton) dw = WMWidthOfString(defaultFont, defaultButton, strlen(defaultButton)); - dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0); + dw = dw + (scrPtr->buttonArrow ? WMGetPixmapSize(scrPtr->buttonArrow).width : 0); aw += 30; ow += 30; @@ -291,7 +291,7 @@ WMAlertPanel *WMCreateScaledAlertPanel(WMScreen * scrPtr, WMWindow * owner, WMSetLabelImagePosition(panel->iLbl, WIPImageOnly); WMMapWidget(panel->iLbl); WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10); - icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL); + icon = WMCreateApplicationIconGreyedPixmap(scrPtr); if (icon) { WMSetLabelImage(panel->iLbl, icon); WMReleasePixmap(icon); @@ -347,7 +347,7 @@ WMAlertPanel *WMCreateScaledAlertPanel(WMScreen * scrPtr, WMWindow * owner, if (defaultButton) dw = WMWidthOfString(scrPtr->normalFont, defaultButton, strlen(defaultButton)); - dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0); + dw = dw + (scrPtr->buttonArrow ? WMGetPixmapSize(scrPtr->buttonArrow).width : 0); aw += WMScaleX(30); ow += WMScaleX(30); @@ -563,7 +563,7 @@ WMInputPanel *WMCreateInputPanel(WMScreen * scrPtr, WMWindow * owner, const char if (okButton) dw = WMWidthOfString(defaultFont, okButton, strlen(okButton)); - w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0); + w = dw + (scrPtr->buttonArrow ? WMGetPixmapSize(scrPtr->buttonArrow).width : 0); if (aw > w) w = aw; @@ -662,7 +662,7 @@ WMInputPanel *WMCreateScaledInputPanel(WMScreen * scrPtr, WMWindow * owner, cons if (okButton) dw = WMWidthOfString(scrPtr->normalFont, okButton, strlen(okButton)); - w = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0); + w = dw + (scrPtr->buttonArrow ? WMGetPixmapSize(scrPtr->buttonArrow).width : 0); if (aw > w) w = aw; @@ -767,7 +767,7 @@ WMGenericPanel *WMCreateGenericPanel(WMScreen * scrPtr, WMWindow * owner, WMSetLabelImagePosition(panel->iLbl, WIPImageOnly); WMMapWidget(panel->iLbl); WMAddBoxSubview(hbox, WMWidgetView(panel->iLbl), False, True, 64, 0, 10); - icon = WMCreateApplicationIconBlendedPixmap(scrPtr, (RColor *) NULL); + icon = WMCreateApplicationIconGreyedPixmap(scrPtr); if (icon) { WMSetLabelImage(panel->iLbl, icon); WMReleasePixmap(icon); @@ -815,7 +815,7 @@ WMGenericPanel *WMCreateGenericPanel(WMScreen * scrPtr, WMWindow * owner, if (alternateButton) aw = WMWidthOfString(defaultFont, alternateButton, strlen(alternateButton)); - dw = dw + (scrPtr->buttonArrow ? scrPtr->buttonArrow->width : 0); + dw = dw + (scrPtr->buttonArrow ? WMGetPixmapSize(scrPtr->buttonArrow).width : 0); aw += 30; dw += 30; diff --git a/WINGs/wpixmap.c b/WINGs/wpixmap.c deleted file mode 100644 index 5ad311cb..00000000 --- a/WINGs/wpixmap.c +++ /dev/null @@ -1,260 +0,0 @@ - -#include "WINGsP.h" - -#include - -WMPixmap *WMRetainPixmap(WMPixmap * pixmap) -{ - if (pixmap) - pixmap->refCount++; - - return pixmap; -} - -void WMReleasePixmap(WMPixmap * pixmap) -{ - wassertr(pixmap != NULL); - - pixmap->refCount--; - - if (pixmap->refCount < 1) { - if (pixmap->pixmap) - XFreePixmap(pixmap->screen->display, pixmap->pixmap); - if (pixmap->mask) - XFreePixmap(pixmap->screen->display, pixmap->mask); - wfree(pixmap); - } -} - -WMPixmap *WMCreatePixmap(WMScreen * scrPtr, int width, int height, int depth, Bool masked) -{ - WMPixmap *pixPtr; - - pixPtr = wmalloc(sizeof(WMPixmap)); - pixPtr->screen = scrPtr; - pixPtr->width = width; - pixPtr->height = height; - pixPtr->depth = depth; - pixPtr->refCount = 1; - - pixPtr->pixmap = XCreatePixmap(scrPtr->display, W_DRAWABLE(scrPtr), width, height, depth); - if (masked) { - pixPtr->mask = XCreatePixmap(scrPtr->display, W_DRAWABLE(scrPtr), width, height, 1); - } else { - pixPtr->mask = None; - } - - return pixPtr; -} - -WMPixmap *WMCreatePixmapFromXPixmaps(WMScreen * scrPtr, Pixmap pixmap, Pixmap mask, - int width, int height, int depth) -{ - WMPixmap *pixPtr; - - pixPtr = wmalloc(sizeof(WMPixmap)); - pixPtr->screen = scrPtr; - pixPtr->pixmap = pixmap; - pixPtr->mask = mask; - pixPtr->width = width; - pixPtr->height = height; - pixPtr->depth = depth; - pixPtr->refCount = 1; - - return pixPtr; -} - -WMPixmap *WMCreatePixmapFromFile(WMScreen * scrPtr, const char *fileName) -{ - WMPixmap *pixPtr; - RImage *image; - - image = RLoadImage(scrPtr->rcontext, fileName, 0); - if (!image) - return NULL; - - pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127); - - RReleaseImage(image); - - return pixPtr; -} - -WMPixmap *WMCreatePixmapFromRImage(WMScreen * scrPtr, RImage * image, int threshold) -{ - WMPixmap *pixPtr; - Pixmap pixmap, mask; - - if (image == NULL) - return NULL; - - if (!RConvertImageMask(scrPtr->rcontext, image, &pixmap, &mask, threshold)) { - return NULL; - } - - pixPtr = wmalloc(sizeof(WMPixmap)); - pixPtr->screen = scrPtr; - pixPtr->pixmap = pixmap; - pixPtr->mask = mask; - pixPtr->width = image->width; - pixPtr->height = image->height; - pixPtr->depth = scrPtr->depth; - pixPtr->refCount = 1; - - return pixPtr; -} - -WMPixmap *WMCreateBlendedPixmapFromRImage(WMScreen * scrPtr, RImage * image, const RColor * color) -{ - WMPixmap *pixPtr; - RImage *copy; - - copy = RCloneImage(image); - if (!copy) - return NULL; - - RCombineImageWithColor(copy, color); - pixPtr = WMCreatePixmapFromRImage(scrPtr, copy, 0); - RReleaseImage(copy); - - return pixPtr; -} - -WMPixmap *WMCreateBlendedPixmapFromFile(WMScreen * scrPtr, const char *fileName, const RColor * color) -{ - return WMCreateScaledBlendedPixmapFromFile(scrPtr, fileName, color, 0, 0); -} - -WMPixmap *WMCreateScaledBlendedPixmapFromFile(WMScreen *scrPtr, const char *fileName, const RColor *color, - unsigned int width, unsigned int height) -{ - WMPixmap *pixPtr; - RImage *image; - - image = RLoadImage(scrPtr->rcontext, fileName, 0); - if (!image) - return NULL; - - /* scale it if needed to fit in the specified box */ - if ((width > 0) && (height > 0) && ((image->width > width) || (image->height > height))) { - int new_width, new_height; - RImage *new_image; - - new_width = image->width; - new_height = image->height; - if (new_width > width) { - new_width = width; - new_height = width * image->height / image->width; - } - if (new_height > height) { - new_width = height * image->width / image->height; - new_height = height; - } - - new_image = RScaleImage(image, new_width, new_height); - RReleaseImage(image); - image = new_image; - } - - RCombineImageWithColor(image, color); - pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 0); - RReleaseImage(image); - - return pixPtr; -} - -WMPixmap *WMCreatePixmapFromXPMData(WMScreen * scrPtr, char **data) -{ - WMPixmap *pixPtr; - RImage *image; - - image = RGetImageFromXPMData(scrPtr->rcontext, data); - if (!image) - return NULL; - - pixPtr = WMCreatePixmapFromRImage(scrPtr, image, 127); - - RReleaseImage(image); - - return pixPtr; -} - -Pixmap WMGetPixmapXID(WMPixmap * pixmap) -{ - wassertrv(pixmap != NULL, None); - - return pixmap->pixmap; -} - -Pixmap WMGetPixmapMaskXID(WMPixmap * pixmap) -{ - wassertrv(pixmap != NULL, None); - - return pixmap->mask; -} - -WMSize WMGetPixmapSize(WMPixmap * pixmap) -{ - WMSize size = { 0, 0 }; - - wassertrv(pixmap != NULL, size); - - size.width = pixmap->width; - size.height = pixmap->height; - - return size; -} - -WMPixmap *WMGetSystemPixmap(WMScreen * scr, int image) -{ - switch (image) { - case WSIReturnArrow: - return WMRetainPixmap(scr->buttonArrow); - - case WSIHighlightedReturnArrow: - return WMRetainPixmap(scr->pushedButtonArrow); - - case WSIScrollerDimple: - return WMRetainPixmap(scr->scrollerDimple); - - case WSIArrowLeft: - return WMRetainPixmap(scr->leftArrow); - - case WSIHighlightedArrowLeft: - return WMRetainPixmap(scr->hiLeftArrow); - - case WSIArrowRight: - return WMRetainPixmap(scr->rightArrow); - - case WSIHighlightedArrowRight: - return WMRetainPixmap(scr->hiRightArrow); - - case WSIArrowUp: - return WMRetainPixmap(scr->upArrow); - - case WSIHighlightedArrowUp: - return WMRetainPixmap(scr->hiUpArrow); - - case WSIArrowDown: - return WMRetainPixmap(scr->downArrow); - - case WSIHighlightedArrowDown: - return WMRetainPixmap(scr->hiDownArrow); - - case WSICheckMark: - return WMRetainPixmap(scr->checkMark); - - default: - return NULL; - } -} - -void WMDrawPixmap(WMPixmap * pixmap, Drawable d, int x, int y) -{ - WMScreen *scr = pixmap->screen; - - XSetClipMask(scr->display, scr->clipGC, pixmap->mask); - XSetClipOrigin(scr->display, scr->clipGC, x, y); - - XCopyArea(scr->display, pixmap->pixmap, d, scr->clipGC, 0, 0, pixmap->width, pixmap->height, x, y); -} diff --git a/WINGs/wpopupbutton.c b/WINGs/wpopupbutton.c index 1a8156b4..256d534f 100644 --- a/WINGs/wpopupbutton.c +++ b/WINGs/wpopupbutton.c @@ -284,21 +284,23 @@ static void paintPopUpButton(PopUpButton * bPtr) } if (bPtr->flags.pullsDown) { - XCopyArea(scr->display, scr->pullDownIndicator->pixmap, - pixmap, scr->copyGC, 0, 0, scr->pullDownIndicator->width, - scr->pullDownIndicator->height, - bPtr->view->size.width - scr->pullDownIndicator->width - 4, - (bPtr->view->size.height - scr->pullDownIndicator->height) / 2); + WMSize size = WMGetPixmapSize(scr->pullDownIndicator); + XCopyArea(scr->display, WMGetPixmapXID(scr->pullDownIndicator), + pixmap, scr->copyGC, 0, 0, size.width, + size.height, + bPtr->view->size.width - size.width - 4, + (bPtr->view->size.height - size.height) / 2); } else { int x, y; + WMSize size = WMGetPixmapSize(scr->popUpIndicator); - x = bPtr->view->size.width - scr->popUpIndicator->width - 4; - y = (bPtr->view->size.height - scr->popUpIndicator->height) / 2; + x = bPtr->view->size.width - size.width - 4; + y = (bPtr->view->size.height - size.height) / 2; XSetClipOrigin(scr->display, scr->clipGC, x, y); - XSetClipMask(scr->display, scr->clipGC, scr->popUpIndicator->mask); - XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap, - scr->clipGC, 0, 0, scr->popUpIndicator->width, scr->popUpIndicator->height, x, y); + XSetClipMask(scr->display, scr->clipGC, WMGetPixmapMaskXID(scr->popUpIndicator)); + XCopyArea(scr->display, WMGetPixmapXID(scr->popUpIndicator), pixmap, + scr->clipGC, 0, 0, size.width, size.height, x, y); } XCopyArea(scr->display, pixmap, bPtr->view->window, scr->copyGC, 0, 0, @@ -357,11 +359,12 @@ static void paintMenuEntry(PopUpButton * bPtr, int index, int highlight) index * itemHeight + yo, width, WALeft, scr->black, False, title, strlen(title)); if (!bPtr->flags.pullsDown && index == bPtr->selectedItemIndex) { - XCopyArea(scr->display, scr->popUpIndicator->pixmap, + WMSize size = WMGetPixmapSize(scr->popUpIndicator); + XCopyArea(scr->display, WMGetPixmapXID(scr->popUpIndicator), bPtr->menuView->window, scr->copyGC, 0, 0, - scr->popUpIndicator->width, scr->popUpIndicator->height, - width - scr->popUpIndicator->width - 4, - index * itemHeight + (itemHeight - scr->popUpIndicator->height) / 2); + size.width, size.height, + width - size.width - 4, + index * itemHeight + (itemHeight - size.height) / 2); } } @@ -401,11 +404,12 @@ static Pixmap makeMenuPixmap(PopUpButton * bPtr) i * itemHeight + yo, width, WALeft, color, False, text, strlen(text)); if (!bPtr->flags.pullsDown && i == bPtr->selectedItemIndex) { - XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap, - scr->copyGC, 0, 0, scr->popUpIndicator->width, - scr->popUpIndicator->height, - width - scr->popUpIndicator->width - 4, - i * itemHeight + (itemHeight - scr->popUpIndicator->height) / 2); + WMSize size = WMGetPixmapSize(scr->popUpIndicator); + XCopyArea(scr->display, WMGetPixmapXID(scr->popUpIndicator), pixmap, + scr->copyGC, 0, 0, size.width, + size.height, + width - size.width - 4, + i * itemHeight + (itemHeight - size.height) / 2); } i++; diff --git a/WINGs/wscroller.c b/WINGs/wscroller.c index 1533da93..5dbc4024 100644 --- a/WINGs/wscroller.c +++ b/WINGs/wscroller.c @@ -225,7 +225,7 @@ static void paintArrow(WMScroller * sPtr, Drawable d, int part) WMView *view = sPtr->view; WMScreen *scr = view->screen; int ofs; - W_Pixmap *arrow; + WMPixmap *arrow; #ifndef DOUBLE_BUFFER GC gc = scr->lightGC; @@ -290,6 +290,7 @@ static void paintArrow(WMScroller * sPtr, Drawable d, int part) if (sPtr->flags.horizontal) { /* paint button */ + WMSize size = WMGetPixmapSize(arrow); #ifndef DOUBLE_BUFFER XFillRectangle(scr->display, d, gc, ofs + 1, 2 + 1, BUTTON_SIZE + 1 - 3, BUTTON_SIZE - 3); #else @@ -300,16 +301,16 @@ static void paintArrow(WMScroller * sPtr, Drawable d, int part) W_DrawRelief(scr, d, ofs, 2, BUTTON_SIZE, BUTTON_SIZE, WRRaised); /* paint arrow */ - XSetClipMask(scr->display, scr->clipGC, arrow->mask); + XSetClipMask(scr->display, scr->clipGC, WMGetPixmapMaskXID(arrow)); XSetClipOrigin(scr->display, scr->clipGC, - ofs + (BUTTON_SIZE - arrow->width) / 2, 2 + (BUTTON_SIZE - arrow->height) / 2); + ofs + (BUTTON_SIZE - size.width) / 2, 2 + (BUTTON_SIZE - size.height) / 2); - XCopyArea(scr->display, arrow->pixmap, d, scr->clipGC, - 0, 0, arrow->width, arrow->height, - ofs + (BUTTON_SIZE - arrow->width) / 2, 2 + (BUTTON_SIZE - arrow->height) / 2); + XCopyArea(scr->display, WMGetPixmapXID(arrow), d, scr->clipGC, + 0, 0, size.width, size.height, + ofs + (BUTTON_SIZE - size.width) / 2, 2 + (BUTTON_SIZE - size.height) / 2); } else { /* vertical */ - + WMSize size = WMGetPixmapSize(arrow); /* paint button */ #ifndef DOUBLE_BUFFER XFillRectangle(scr->display, d, gc, 2 + 1, ofs + 1, BUTTON_SIZE - 3, BUTTON_SIZE + 1 - 3); @@ -322,12 +323,12 @@ static void paintArrow(WMScroller * sPtr, Drawable d, int part) /* paint arrow */ - XSetClipMask(scr->display, scr->clipGC, arrow->mask); + XSetClipMask(scr->display, scr->clipGC, WMGetPixmapMaskXID(arrow)); XSetClipOrigin(scr->display, scr->clipGC, - 2 + (BUTTON_SIZE - arrow->width) / 2, ofs + (BUTTON_SIZE - arrow->height) / 2); - XCopyArea(scr->display, arrow->pixmap, d, scr->clipGC, - 0, 0, arrow->width, arrow->height, - 2 + (BUTTON_SIZE - arrow->width) / 2, ofs + (BUTTON_SIZE - arrow->height) / 2); + 2 + (BUTTON_SIZE - size.width) / 2, ofs + (BUTTON_SIZE - size.height) / 2); + XCopyArea(scr->display, WMGetPixmapXID(arrow), d, scr->clipGC, + 0, 0, size.width, size.height, + 2 + (BUTTON_SIZE - size.width) / 2, ofs + (BUTTON_SIZE - size.height) / 2); } } @@ -395,6 +396,7 @@ static void paintScroller(Scroller * sPtr) knobP = sPtr->floatValue * ((float)length - knobL); if (sPtr->flags.horizontal) { + WMSize size = WMGetPixmapSize(scr->scrollerDimple); /* before */ XFillRectangle(scr->display, d, scr->stippleGC, ofs, 2, (int)knobP, view->size.height - 4); @@ -405,11 +407,11 @@ static void paintScroller(Scroller * sPtr) #endif W_DrawRelief(scr, d, ofs + (int)knobP, 2, (int)knobL, view->size.height - 4, WRRaised); - XCopyArea(scr->display, scr->scrollerDimple->pixmap, d, + XCopyArea(scr->display, WMGetPixmapXID(scr->scrollerDimple), d, scr->copyGC, 0, 0, - scr->scrollerDimple->width, scr->scrollerDimple->height, - ofs + (int)knobP + ((int)knobL - scr->scrollerDimple->width - 1) / 2, - (view->size.height - scr->scrollerDimple->height - 1) / 2); + size.width, size.height, + ofs + (int)knobP + ((int)knobL - size.width - 1) / 2, + (view->size.height - size.height - 1) / 2); /* after */ if ((int)(knobP + knobL) < length) @@ -418,6 +420,7 @@ static void paintScroller(Scroller * sPtr) length - (int)(knobP + knobL), view->size.height - 4); } else { /* before */ + WMSize size = WMGetPixmapSize(scr->scrollerDimple); if (knobP > 0.0F) XFillRectangle(scr->display, d, scr->stippleGC, 2, ofs, view->size.width - 4, (int)knobP); @@ -427,11 +430,11 @@ static void paintScroller(Scroller * sPtr) XFillRectangle(scr->display, d, scr->lightGC, 2 + 2, ofs + (int)knobP + 2, view->size.width - 4 - 4, (int)knobL - 4); #endif - XCopyArea(scr->display, scr->scrollerDimple->pixmap, d, + XCopyArea(scr->display, WMGetPixmapXID(scr->scrollerDimple), d, scr->copyGC, 0, 0, - scr->scrollerDimple->width, scr->scrollerDimple->height, - (view->size.width - scr->scrollerDimple->width - 1) / 2, - ofs + (int)knobP + ((int)knobL - scr->scrollerDimple->height - 1) / 2); + size.width, size.height, + (view->size.width - size.width - 1) / 2, + ofs + (int)knobP + ((int)knobL - size.height - 1) / 2); W_DrawRelief(scr, d, 2, ofs + (int)knobP, view->size.width - 4, (int)knobL, WRRaised); diff --git a/WINGs/wsplitview.c b/WINGs/wsplitview.c index 3d8072db..55bab0e5 100644 --- a/WINGs/wsplitview.c +++ b/WINGs/wsplitview.c @@ -400,16 +400,18 @@ static void paintSplitView(WMSplitView * sPtr) sPtr->flags.adjustOnPaint = 0; } - XSetClipMask(scr->display, scr->clipGC, dimple->mask); + XSetClipMask(scr->display, scr->clipGC, WMGetPixmapMaskXID(dimple)); + WMSize size = WMGetPixmapSize(dimple); if (sPtr->flags.vertical) { - x = ((DIVIDER_THICKNESS - dimple->width) / 2); - y = (sPtr->view->size.height - dimple->height) / 2; + x = ((DIVIDER_THICKNESS - size.width) / 2); + y = (sPtr->view->size.height - size.height) / 2; } else { - x = (sPtr->view->size.width - dimple->width) / 2; - y = ((DIVIDER_THICKNESS - dimple->height) / 2); + x = (sPtr->view->size.width - size.width) / 2; + y = ((DIVIDER_THICKNESS - size.height) / 2); } + WMSize dimpleSize = WMGetPixmapSize(dimple); for (i = 0; i < count - 1; i++) { p = _GetPSubviewStructAt(i); @@ -419,8 +421,8 @@ static void paintSplitView(WMSplitView * sPtr) y += p->size; XSetClipOrigin(scr->display, scr->clipGC, x, y); - XCopyArea(scr->display, dimple->pixmap, sPtr->view->window, - scr->clipGC, 0, 0, dimple->width, dimple->height, x, y); + XCopyArea(scr->display, WMGetPixmapXID(dimple), sPtr->view->window, + scr->clipGC, 0, 0, dimpleSize.width, dimpleSize.height, x, y); if (sPtr->flags.vertical) x += DIVIDER_THICKNESS; diff --git a/WINGs/wtext.c b/WINGs/wtext.c index 2a9c3660..dc175bcf 100644 --- a/WINGs/wtext.c +++ b/WINGs/wtext.c @@ -627,9 +627,10 @@ static void paintText(Text * tPtr) XFillRectangle(dpy, tPtr->db, WMColorGC(tPtr->bgColor), 0, 0, tPtr->visible.w, tPtr->visible.h); if (tPtr->bgPixmap) { + WMSize bgSize = WMGetPixmapSize(tPtr->bgPixmap); WMDrawPixmap(tPtr->bgPixmap, tPtr->db, - (tPtr->visible.w - tPtr->visible.x - tPtr->bgPixmap->width) / 2, - (tPtr->visible.h - tPtr->visible.y - tPtr->bgPixmap->height) / 2); + (tPtr->visible.w - tPtr->visible.x - bgSize.width) / 2, + (tPtr->visible.h - tPtr->visible.y - bgSize.height) / 2); } if (!(tb = tPtr->currentTextBlock)) { @@ -766,7 +767,7 @@ static void paintText(Text * tPtr) WMDrawPixmap(tb->d.pixmap, tPtr->db, tb->sections[0].x - tPtr->hpos, tb->sections[0].y - tPtr->vpos); - h = tb->d.pixmap->height + 1; + h = WMGetPixmapSize(tb->d.pixmap).height + 1; } @@ -848,7 +849,7 @@ static void mouseOverObject(Text * tPtr, int x, int y) if (tb->sections[0].x <= x && tb->sections[0].y <= y && tb->sections[0].x + tb->sections[0].w >= x - && tb->sections[0].y + tb->d.pixmap->height >= y) { + && tb->sections[0].y + WMGetPixmapSize(tb->d.pixmap).height >= y) { tPtr->flags.isOverGraphic = 3; result = True; break; @@ -1059,7 +1060,7 @@ static void cursorToTextPosition(Text * tPtr, int x, int y) if (tb->object) _w = WMWidgetWidth(tb->d.widget) - 5; else - _w = tb->d.pixmap->width - 5; + _w = WMGetPixmapSize(tb->d.pixmap).width - 5; if (tb->sections[0].x + _w >= x) break; @@ -1096,7 +1097,7 @@ static void cursorToTextPosition(Text * tPtr, int x, int y) if (tb->object) tPtr->cursor.x += WMWidgetWidth(tb->d.widget); else - tPtr->cursor.x += tb->d.pixmap->width; + tPtr->cursor.x += WMGetPixmapSize(tb->d.pixmap).width; } else if (pos > tb->sections[s].begin) { tPtr->cursor.x += WMWidthOfString(tb->d.font, @@ -1121,7 +1122,7 @@ static void cursorToTextPosition(Text * tPtr, int x, int y) /* we have said TextBlock, now where within it? */ if (tb) { if (tb->graphic) { - int gw = (tb->object ? WMWidgetWidth(tb->d.widget) : tb->d.pixmap->width); + int gw = (tb->object ? WMWidgetWidth(tb->d.widget) : WMGetPixmapSize(tb->d.pixmap).width); tPtr->cursor.x = tb->sections[0].x; @@ -1370,9 +1371,9 @@ static int layOutLine(Text * tPtr, myLineItems * items, int nitems, int x, int y if (tPtr->flags.alignment != WALeft) lw += WMWidgetWidth(wdt); } else { - line_height = WMAX(line_height, tb->d.pixmap->height + max_d); + line_height = WMAX(line_height, WMGetPixmapSize(tb->d.pixmap).height + max_d); if (tPtr->flags.alignment != WALeft) - lw += tb->d.pixmap->width; + lw += WMGetPixmapSize(tb->d.pixmap).width; } } @@ -1420,8 +1421,8 @@ static int layOutLine(Text * tPtr, myLineItems * items, int nitems, int x, int y tb->sections[n].y = max_d + y + line_height - WMWidgetHeight(wdt); tb->sections[n].w = WMWidgetWidth(wdt); } else { - tb->sections[n].y = y + line_height + max_d - tb->d.pixmap->height; - tb->sections[n].w = tb->d.pixmap->width; + tb->sections[n].y = y + line_height + max_d - WMGetPixmapSize(tb->d.pixmap).height; + tb->sections[n].w = WMGetPixmapSize(tb->d.pixmap).width; } x += tb->sections[n].w; } @@ -1530,7 +1531,7 @@ static void layOutDocument(Text * tPtr) if (tb->object) width = WMWidgetWidth(tb->d.widget); else - width = tb->d.pixmap->width; + width = WMGetPixmapSize(tb->d.pixmap).width; if (width > tPtr->docWidth) tPtr->docWidth = width; diff --git a/WINGs/wview.c b/WINGs/wview.c index 9a927fae..0701f442 100644 --- a/WINGs/wview.c +++ b/WINGs/wview.c @@ -506,9 +506,9 @@ void W_SetViewBackgroundPixmap(W_View *view, WMPixmap *pix) view->attribFlags |= CWBackPixmap; view->attribFlags &= ~CWBackPixel; - view->attribs.background_pixmap = pix->pixmap; + view->attribs.background_pixmap = WMGetPixmapXID(pix); if (view->flags.realized) { - XSetWindowBackgroundPixmap(view->screen->display, view->window, pix->pixmap); + XSetWindowBackgroundPixmap(view->screen->display, view->window, WMGetPixmapXID(pix)); XClearWindow(view->screen->display, view->window); } } diff --git a/WPrefs.app/HotCornerShortcuts.c b/WPrefs.app/HotCornerShortcuts.c index 73595cdc..8d6f33ee 100644 --- a/WPrefs.app/HotCornerShortcuts.c +++ b/WPrefs.app/HotCornerShortcuts.c @@ -350,12 +350,13 @@ static void createPanel(Panel * p) CreateImages(scr, rc, xis, ICON_FILE, &panel->icon, NULL); if (panel->icon) { + WMSize size = WMGetPixmapSize(panel->icon); WMPixmap *nicon; - panel->quarter[0] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); - XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[0], gc, 0, 0, panel->icon->width/2, panel->icon->height/2, 0, 0); + panel->quarter[0] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), size.width/2, size.height/2, WMScreenDepth(scr)); + XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[0], gc, 0, 0, size.width/2, size.height/2, 0, 0); nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[0], WMGetPixmapMaskXID(panel->icon), - panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); + size.width/2, size.height/2, WMScreenDepth(scr)); WMSetLabelImage(panel->icornerL, nicon); WMReleasePixmap(nicon); } @@ -370,12 +371,13 @@ static void createPanel(Panel * p) WMSetLabelImagePosition(panel->icornerL, WIPImageOnly); if (panel->icon) { + WMSize size = WMGetPixmapSize(panel->icon); WMPixmap *nicon; - panel->quarter[1] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); - XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[1], gc, panel->icon->width/2, 0, panel->icon->width/2, panel->icon->height/2, 0, 0); + panel->quarter[1] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), size.width/2, size.height/2, WMScreenDepth(scr)); + XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[1], gc, size.width/2, 0, size.width/2, size.height/2, 0, 0); nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[1], WMGetPixmapMaskXID(panel->icon), - panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); + size.width/2, size.height/2, WMScreenDepth(scr)); WMSetLabelImage(panel->icornerL, nicon); WMReleasePixmap(nicon); } @@ -390,12 +392,13 @@ static void createPanel(Panel * p) WMSetLabelImagePosition(panel->icornerL, WIPImageOnly); if (panel->icon) { + WMSize size = WMGetPixmapSize(panel->icon); WMPixmap *nicon; - panel->quarter[2] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); - XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[2], gc, 0, panel->icon->height/2, panel->icon->width/2, panel->icon->height/2, 0, 0); + panel->quarter[2] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), size.width/2, size.height/2, WMScreenDepth(scr)); + XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[2], gc, 0, size.height/2, size.width/2, size.height/2, 0, 0); nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[2], WMGetPixmapMaskXID(panel->icon), - panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); + size.width/2, size.height/2, WMScreenDepth(scr)); WMSetLabelImage(panel->icornerL, nicon); WMReleasePixmap(nicon); } @@ -409,12 +412,13 @@ static void createPanel(Panel * p) WMSetLabelImagePosition(panel->icornerL, WIPImageOnly); if (panel->icon) { + WMSize size = WMGetPixmapSize(panel->icon); WMPixmap *nicon; - panel->quarter[3] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); - XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[3], gc, panel->icon->width/2, panel->icon->height/2, panel->icon->width/2, panel->icon->height/2, 0, 0); + panel->quarter[3] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), size.width/2, size.height/2, WMScreenDepth(scr)); + XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[3], gc, size.width/2, size.height/2, size.width/2, size.height/2, 0, 0); nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[3], WMGetPixmapMaskXID(panel->icon), - panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr)); + size.width/2, size.height/2, WMScreenDepth(scr)); WMSetLabelImage(panel->icornerL, nicon); WMReleasePixmap(nicon); } diff --git a/WPrefs.app/MouseSettings.c b/WPrefs.app/MouseSettings.c index d15d7a45..7d3236c9 100644 --- a/WPrefs.app/MouseSettings.c +++ b/WPrefs.app/MouseSettings.c @@ -438,13 +438,8 @@ static void createPanel(Panel * p) WMPixmap *icon; char *buf1, *buf2; int i; - RColor color; char *path; - color.red = 0xae; - color.green = 0xaa; - color.blue = 0xae; - panel->box = WMCreateBox(panel->parent); WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2); @@ -460,7 +455,7 @@ static void createPanel(Panel * p) WMSetLabelImagePosition(panel->speedL, WIPImageOnly); path = LocateImage(SPEED_ICON_FILE); if (path) { - icon = WMCreateBlendedPixmapFromFile(scr, path, &color); + icon = WMCreateGreyedPixmapFromFile(scr, path); if (icon) { WMSetLabelImage(panel->speedL, icon); WMReleasePixmap(icon); diff --git a/WPrefs.app/WPrefs.c b/WPrefs.app/WPrefs.c index c95f8a17..4de0efde 100644 --- a/WPrefs.app/WPrefs.c +++ b/WPrefs.app/WPrefs.c @@ -444,17 +444,12 @@ void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file, void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file) { WMPixmap *icon; - RColor color; char *iconPath; iconPath = LocateImage(file); - color.red = 0xae; - color.green = 0xaa; - color.blue = 0xae; - color.alpha = 0; if (iconPath) { - icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color); + icon = WMCreateGreyedPixmapFromFile(scr, iconPath); if (!icon) wwarning(_("could not load icon file %s"), iconPath); } else { @@ -463,12 +458,12 @@ void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file) WMSetButtonImage(bPtr, icon); - color.red = 0xff; - color.green = 0xff; - color.blue = 0xff; - color.alpha = 0; + /* color.red = 0xff; */ + /* color.green = 0xff; */ + /* color.blue = 0xff; */ + /* color.alpha = 0; */ if (iconPath) { - icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color); + icon = WMCreateGreyedPixmapFromFile(scr, iconPath); if (!icon) wwarning(_("could not load icon file %s"), iconPath); } else { diff --git a/src/dialog.c b/src/dialog.c index 7b0298f5..787fd6e0 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -631,16 +631,11 @@ static void listPixmaps(WScreen *scr, WMList *lPtr, const char *path) static void setViewedImage(IconPanel *panel, const char *file) { WMPixmap *pixmap; - RColor color; int iwidth, iheight; - color.red = 0xae; - color.green = 0xaa; - color.blue = 0xae; - color.alpha = 0; iwidth = WMWidgetWidth(panel->iconView); iheight = WMWidgetHeight(panel->iconView); - pixmap = WMCreateScaledBlendedPixmapFromFile(WMWidgetScreen(panel->win), file, &color, iwidth, iheight); + pixmap = WMCreateScaledGreyedPixmapFromFile(WMWidgetScreen(panel->win), file, iwidth, iheight); if (!pixmap) { WMSetButtonEnabled(panel->okButton, False); @@ -737,7 +732,6 @@ static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int s WMColor *back; WMSize size; WMScreen *wmscr = WMWidgetScreen(panel->win); - RColor color; int x, y, width, height, len; /* Parameter not used, but tell the compiler that it is ok */ @@ -759,12 +753,11 @@ static void drawIconProc(WMList * lPtr, int index, Drawable d, char *text, int s snprintf(file, len, "%s/%s", dirfile, text); wfree(dirfile); - color.red = WMRedComponentOfColor(back) >> 8; - color.green = WMGreenComponentOfColor(back) >> 8; - color.blue = WMBlueComponentOfColor(back) >> 8; - color.alpha = WMGetColorAlpha(back) >> 8; - - pixmap = WMCreateScaledBlendedPixmapFromFile(wmscr, file, &color, width - 2, height - 2); + if (state & WLDSSelected) { + pixmap = WMCreateScaledPixmapFromFile(wmscr, file, width - 2, height - 2); + } else { + pixmap = WMCreateScaledGreyedPixmapFromFile(wmscr, file, width - 2, height - 2); + } wfree(file); if (!pixmap) { @@ -1279,7 +1272,7 @@ void wShowInfoPanel(WScreen *scr) pheight = WMScaleY(270); WMResizeWidget(panel->win, pwidth, pheight); - logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL); + logo = WMCreateApplicationIconGreyedPixmap(scr->wmscreen); if (!logo) { logo = WMRetainPixmap(WMGetApplicationIconPixmap(scr->wmscreen)); } @@ -1652,14 +1645,7 @@ static WMPixmap *getWindowMakerIconImage(WMScreen *scr) path = get_icon_filename("Logo", "WMPanel", NULL, False); if (path) { - RColor gray; - - gray.red = 0xae; - gray.green = 0xaa; - gray.blue = 0xae; - gray.alpha = 0; - - pix = WMCreateBlendedPixmapFromFile(scr, path, &gray); + pix = WMCreateGreyedPixmapFromFile(scr, path); wfree(path); } diff --git a/src/dockedapp.c b/src/dockedapp.c index 26f0a610..157bfb4e 100644 --- a/src/dockedapp.c +++ b/src/dockedapp.c @@ -68,14 +68,9 @@ static void updateSettingsPanelIcon(AppSettingsPanel * panel) return; } else { WMPixmap *pixmap; - RColor color; - color.red = 0xae; - color.green = 0xaa; - color.blue = 0xae; - color.alpha = 0; size = wPreferences.icon_size; - pixmap = WMCreateScaledBlendedPixmapFromFile(WMWidgetScreen(panel->win), path, &color, size, size); + pixmap = WMCreateScaledGreyedPixmapFromFile(WMWidgetScreen(panel->win), path, size, size); if (!pixmap) { WMSetLabelImage(panel->iconLabel, NULL); } else { diff --git a/wrlib-rs/Makefile.am b/wrlib-rs/Makefile.am index 228aaa4f..8d86dfb6 100644 --- a/wrlib-rs/Makefile.am +++ b/wrlib-rs/Makefile.am @@ -13,6 +13,7 @@ src/ffi.rs: ../wrlib/wraster.h patch_ffi.sed Makefile --allowlist-type "R(Context|ContextAttributes|Image|RenderingMode|ScalingFilter|StdColormapMode|ImageFormat|Color)" \ --allowlist-function "RGetClosestXColor" \ --allowlist-function "RLoadImage|RReleaseImage" \ + --allowlist-function "R(Load|Release|Clone|Scale)Image|RConvertImageMask|RCombineImageWithColor" \ -o src/ffi.rs \ -- \ -I../../wrlib \ diff --git a/wutil-rs/src/array.rs b/wutil-rs/src/array.rs index a0d94684..d12f2160 100644 --- a/wutil-rs/src/array.rs +++ b/wutil-rs/src/array.rs @@ -15,6 +15,8 @@ pub mod ffi { pub const NOT_FOUND: c_int = -1; + pub type WMArray = Array; + #[unsafe(no_mangle)] pub unsafe extern "C" fn WMCreateArray(initial_size: c_int) -> *mut Array { let cap = if initial_size < 0 { -- 2.39.5