Я занимаюсь этим уже несколько дней, но я просто не могу понять, как создать 32-битное корневое окно, чтобы я мог использовать цвета RGBA в дочернем окне, а дочернее окно не может использовать 32-битный цвет. глубина (24-битная для RGB и 8-битная для альфа-канала), если родительский или в этом случае корневое окно не имеет 32-битной глубины цвета. Я использую следующий код, чтобы установить фон корневого окна для изображения RGB с глубиной цвета 24 бита, таким образом, когда я устанавливаю XCreatePixmap на глубину цвета 24 бита, это просто работает, но мне нужно это корневое окно иметь 32-битную глубину цвета для альфа-композиции:
/* displays an image or sets root background
* PUBLIC DOMAIN - CC0 http://creativecommons.org/publicdomain/zero/1.0/
* J.Mayo 2013
*
* gcc -Wall -W -g3 -o background background.c -lX11 -lImlib2
*
*/
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xcomposite.h>
#include <Imlib2.h>struct screenAttributes {
int height;
int width;
};
struct screenAttributes screenAttr;
void initializeScreenAttributes(Screen *screen) {
screenAttr.height=screen->height;
screenAttr.width=screen->width;
}int main(int argc, char **argv)
{
Imlib_Image img;
Display *dpy;
Pixmap pix;
Window root;
Screen *scn;
// Window topPanel;
int width, height;
const char *filename = "/sampleImage.png";img = imlib_load_image(filename);
if (!img) {
fprintf(stderr, "%s:Unable to load image\n", filename);
goto usage;
}
imlib_context_set_image(img);
width = imlib_image_get_width();
height = imlib_image_get_height();
dpy = XOpenDisplay(NULL);
if (!dpy) return 0;
scn = DefaultScreenOfDisplay(dpy);
root = DefaultRootWindow(dpy);
pix = XCreatePixmap(dpy, root, width, height,32); //when depth is set to 24 it just works, but when it is set to 32 it fails.//scale the image
initializeScreenAttributes(scn);
imlib_blend_image_onto_image(img,0,0,0,width,height,0,0,
screenAttr.width, screenAttr.height);imlib_context_set_display(dpy);
imlib_context_set_visual(DefaultVisualOfScreen(scn));
imlib_context_set_colormap(DefaultColormapOfScreen(scn));
imlib_context_set_drawable(pix);
imlib_render_image_on_drawable(0, 0);
XSetWindowBackgroundPixmap(dpy, root, pix);
XClearWindow(dpy, root);while (XPending(dpy)) {
XEvent ev;
XNextEvent(dpy, &ev);
}
XFreePixmap(dpy, pix);
imlib_free_image();
sleep(10);
//XFreePixmap(dpy, pix);
//imlib_free_image();
XCloseDisplay(dpy);
return 0;
usage:
fprintf(stderr, "usage: %s <image_file>\n", argv[0]);
return 1;
}
когда я устанавливаю XCreapePixmap на 32-битную глубину цвета, я получаю:
X Error of failed request: BadMatch (invalid parameter attributes)
Major opcode of failed request: 130 (MIT-SHM)
Minor Opcode of failed request: 3 (X_ShmPutImage)
Serial number of failed request : 28
Current serial number in output stream: 29 xinit: connection to X server lost
Итак, другими словами, я не совсем уверен в том, как установить глубину цвета корневого окна на 32-битное и установить 24-битное изображение RGB в качестве фона корневого окна.
Спасибо!
Постскриптум У меня нет установленных оконных менеджеров или какой-либо среды рабочего стола, поэтому об использовании любого из доступных инструментов в них не может быть и речи.
Нет, вам не нужно иметь корневое окно глубиной 32, чтобы иметь детей глубиной 32
тоже. Иначе как, черт возьми, окна могут иметь альфа-каналы в
компоновщик? Как вы думаете, это:
http://www.enlightenment.org/ss/e-5872c6ec3ddce1.54730231.png
возможно без 2 из этих окон, имеющих 32-битную глубину? (2 слева —
часы и полупрозрачный терминал). 🙂
Способ, которым работает полупрозрачность — это вмешательство композитора (в наши дни обычно ваш
оконный менеджер) и состоит из 32-битных окон сверху (также возможно сделок
с перерисовкой корневого окна тоже внизу — это может зависеть, хотя). так что сказать: «У меня нет композитора / оконного менеджера, так что об этом не может быть и речи», в сущности, сказать: «Я не хочу делать одну-единственную вещь, которую я НУЖНО СДЕЛАТЬ для того, чтобы получить прозрачность «, поэтому я предлагаю вам пересмотреть эту позицию.
Так что вам действительно нужен композитор и 32-битные окна. Либо использовать
композитный оконный менеджер, а затем создать 32-битные окна, или запустить отдельный
композитор и ваш существующий WM, или написать свой собственный композитор … (не собираюсь
очень весело, чтобы сделать это правильно и быстро) …
Теперь для создания окна ARGB вам понадобится помощь от XRender для визуализации. Как ниже, где Индик.точки твой Xlib дисплей а также родитель родитель Окно (например, root):
Window win;
XSetWindowAttributes attr;
XWindowAttributes att;
XVisualInfo *xvi;
XVisualInfo vi_in;
int nvi, i, scr = 0;
XRenderPictFormat *fmt;
Visual *vis;
vi_in.screen = scr;
vi_in.depth = 32;
vi_in.class = TrueColor;
xvi = XGetVisualInfo(disp,
VisualScreenMask |
VisualDepthMask |
VisualClassMask,
&vi_in,
&nvi);
if (!xvi) return 0;
vis = NULL;
for (i = 0; i < nvi; i++)
{
fmt = XRenderFindVisualFormat(disp, xvi[i].visual);
if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
{
vis = xvi[i].visual;
break;
}
}
XFree (xvi);
attr.backing_store = NotUseful;
attr.override_redirect = 0;
attr.colormap = XCreateColormap(disp, parent,
vis, AllocNone);
attr.border_pixel = 0;
attr.background_pixmap = None;
attr.bit_gravity = NorthWestGravity;
attr.win_gravity = NorthWestGravity;
attr.save_under = 0;
attr.do_not_propagate_mask = NoEventMask;
attr.event_mask = KeyPressMask |
KeyReleaseMask |
ButtonPressMask |
ButtonReleaseMask |
EnterWindowMask |
LeaveWindowMask |
PointerMotionMask |
ExposureMask |
VisibilityChangeMask |
StructureNotifyMask |
FocusChangeMask |
PropertyChangeMask |
ColormapChangeMask;
win = XCreateWindow(disp, parent,
x, y, w, h, 0,
32,
InputOutput,
vis,
CWBackingStore |
CWOverrideRedirect |
CWColormap |
CWBorderPixel |
CWBackPixmap |
CWSaveUnder |
CWDontPropagate |
CWEventMask |
CWBitGravity |
CWWinGravity,
&attr);
Код приходит отсюда: https://git.enlightenment.org/core/efl.git/tree/src/lib/ecore_x/ecore_x_window.c#n1644
Раньше у нас был XCB-сервер и весь этот код в XCB, но мы отказались от XCB примерно через десять лет. Если вы клонируете вышеизложенное и будете копаться в истории, вы будете в порядке в директории ecore_x, в которой были вложенные каталоги xlib и xcb, если вы действительно хотите это откопать.
Вот почему я написал xlib abstractor / detail filler, потому что написать гораздо меньше кода, если вы прячете обычное многословное использование Xlib за более простыми API.
Похоже, у вас точно такая же проблема, как я описал здесь: Как загрузить 32-битное изображение в растровое изображение на стороне сервера
Если вы создаете 32-битное окно и у вас есть 24-битный корень, вы не сможете использовать DefaultVisualOfScreen
/ DefaultColormapOfScreen
— они установят визуальную / цветовую карту, которая действительна для корня (и, таким образом, 24 бит).
imlib_context_set_visual(DefaultVisualOfScreen(scn));
imlib_context_set_colormap(DefaultColormapOfScreen(scn));
Я не очень знаком с imlib api, но, похоже, вы сможете создать цветовую карту для своего окна / растрового изображения вручную и передать ее в imlib
Самый простой способ создать окно глубиной 32 бита:
XVisualInfo vinfo;
XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo);
Window win = XCreateWindow(display, DefaultRootWindow(display),
0, 0, width, height, 0,
vinfo.depth, // <---------------!!!
InputOutput,
vinfo.visual, // <---------------!!!
mask, &attr);
Вы не можете иметь корневое окно, чтобы иметь желаемую глубину — оно уже существует и имеет глубину, которую оно имеет.