properly support shaped windows with xrender engine... :)

SVN revision: 17125
This commit is contained in:
Carsten Haitzler 2005-10-03 06:45:45 +00:00
parent 63d04c65d5
commit d022e996e6
6 changed files with 359 additions and 46 deletions

View File

@ -576,6 +576,48 @@ else
fi
fi
want_ecore_evas_xrender="yes";
have_ecore_evas_xrender="no";
AC_MSG_CHECKING(whether ecore_evas xrender support is to be built)
AC_ARG_ENABLE(ecore-evas-xrender,
[ --disable-ecore-evas-xrender disable xrender in the ecore_evas module],
[
if [ test "$enableval" = "yes" ]; then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
want_ecore_evas_xrender="no"
fi
], [
AC_MSG_RESULT(yes)
]
)
dnl Xrender support requires X support, so we should
dnl handle the case where our user is on crack
dnl i.e. user disables X but enables Xrender
PCFLAGS=$CFLAGS
CFLAGS="$EVAS_CFLAGS $CFLAGS"
if test "x$want_ecore_evas_xrender" = "xyes" -a "x$have_ecore_x" = "xyes"; then
AC_CHECK_HEADER(Evas_Engine_XRender_X11.h,
[
AM_CONDITIONAL(BUILD_ECORE_EVAS_XRENDER, true)
AC_DEFINE(BUILD_ECORE_EVAS_XRENDER, 1, [Support for XRender Engine in Ecore_Evas])
have_ecore_evas_xrender="yes";
], [
AM_CONDITIONAL(BUILD_ECORE_EVAS_XRENDER, false)
], [
#include <Evas.h>
]
)
else
AM_CONDITIONAL(BUILD_ECORE_EVAS_XRENDER, false)
if test "x$want_ecore_evas_xrender" = "xyes"; then
AC_MSG_WARN(Silly monkey: ecore_evas_xrender requires ecore_x ... disabling ecore_evas_xrender)
fi
fi
want_ecore_evas_fb="yes";
have_ecore_evas_fb="no";
@ -1052,20 +1094,21 @@ echo "$PACKAGE $VERSION"
echo
echo "Optional Modules:"
echo
echo " Ecore_Job...............: $have_ecore_job"
echo " Ecore_Con...............: $have_ecore_con (OpenSSL: $use_openssl)"
echo " Ecore_Txt...............: $have_ecore_txt"
echo " Ecore_X.................: $have_ecore_x (Xcursor: $use_Xcursor) (Xprint: $use_Xprint) (Xinerama: $use_Xinerama) (Xrandr: $use_Xrandr)"
echo " Ecore_FB................: $have_ecore_fb"
echo " Ecore_Evas..............: $have_ecore_evas"
echo " Ecore_Evas GL Support...: $have_ecore_evas_gl"
echo " Ecore_Evas FB Support...: $have_ecore_evas_fb"
echo " Ecore_Buffer............: $have_ecore_evas_buffer"
echo " Ecore_Ipc...............: $have_ecore_ipc (OpenSSL: $use_openssl)"
echo " Ecore_Config............: $have_ecore_config"
echo " Ecore_DBUS..............: $have_ecore_dbus"
#echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (FAM: $use_fam) (Poll: $use_poll)"
echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (Poll: $use_poll) (CURL: $use_curl)"
echo " Ecore_Job....................: $have_ecore_job"
echo " Ecore_Con....................: $have_ecore_con (OpenSSL: $use_openssl)"
echo " Ecore_Txt....................: $have_ecore_txt"
echo " Ecore_X......................: $have_ecore_x (Xcursor: $use_Xcursor) (Xprint: $use_Xprint) (Xinerama: $use_Xinerama) (Xrandr: $use_Xrandr)"
echo " Ecore_FB.....................: $have_ecore_fb"
echo " Ecore_Evas...................: $have_ecore_evas"
echo " Ecore_Evas GL Support........: $have_ecore_evas_gl"
echo " Ecore_Evas XRender Support...: $have_ecore_evas_xrender"
echo " Ecore_Evas FB Support........: $have_ecore_evas_fb"
echo " Ecore_Buffer.................: $have_ecore_evas_buffer"
echo " Ecore_Ipc....................: $have_ecore_ipc (OpenSSL: $use_openssl)"
echo " Ecore_Config.................: $have_ecore_config"
echo " Ecore_DBUS...................: $have_ecore_dbus"
#echo " Ecore_File...................: $have_ecore_file (Inotify: $use_inotify) (FAM: $use_fam) (Poll: $use_poll)"
echo " Ecore_File...................: $have_ecore_file (Inotify: $use_inotify) (Poll: $use_poll) (CURL: $use_curl)"
echo
echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE."
echo

View File

@ -72,6 +72,11 @@ app_start(int argc, const char **argv)
ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, 240, 320);
evas = ecore_evas_get(ee);
}
else if ((argc > 1) && (!strcmp(argv[1], "-xr")))
{
ee = ecore_evas_xrender_x11_new(NULL, 0, 0, 0, 240, 320);
evas = ecore_evas_get(ee);
}
#if HAVE_ECORE_EVAS_GL
else if ((argc > 1) && (!strcmp(argv[1], "-gl")))
{

View File

@ -53,7 +53,8 @@ typedef enum
ECORE_EVAS_ENGINE_SOFTWARE_X11,
ECORE_EVAS_ENGINE_SOFTWARE_FB,
ECORE_EVAS_ENGINE_GL_X11,
ECORE_EVAS_ENGINE_SOFTWARE_BUFFER
ECORE_EVAS_ENGINE_SOFTWARE_BUFFER,
ECORE_EVAS_ENGINE_XRENDER_X11
} Ecore_Evas_Engine_Type;
#ifndef _ECORE_X_H
@ -88,6 +89,13 @@ EAPI void ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on)
EAPI int ecore_evas_gl_x11_direct_resize_get(Ecore_Evas *ee);
EAPI void ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
EAPI Ecore_Evas *ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h);
EAPI Ecore_X_Window ecore_evas_xrender_x11_window_get(Ecore_Evas *ee);
EAPI Ecore_X_Window ecore_evas_xrender_x11_subwindow_get(Ecore_Evas *ee);
EAPI void ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on);
EAPI int ecore_evas_xrender_x11_direct_resize_get(Ecore_Evas *ee);
EAPI void ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win);
EAPI Ecore_Evas *ecore_evas_fb_new(char *disp_name, int rotation, int w, int h);
EAPI Ecore_Evas *ecore_evas_buffer_new(int w, int h);

View File

@ -40,6 +40,13 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
return 1;
#else
return 0;
#endif
break;
case ECORE_EVAS_ENGINE_XRENDER_X11:
#ifdef BUILD_ECORE_EVAS_XRENDER
return 1;
#else
return 0;
#endif
break;
case ECORE_EVAS_ENGINE_SOFTWARE_BUFFER:

View File

@ -26,6 +26,9 @@
#ifdef BUILD_ECORE_EVAS_GL
#include <Evas_Engine_GL_X11.h>
#endif
#ifdef BUILD_ECORE_EVAS_XRENDER
#include <Evas_Engine_XRender_X11.h>
#endif
#endif
#ifdef BUILD_ECORE_EVAS_FB
#include <Evas_Engine_FB.h>

View File

@ -1048,41 +1048,78 @@ _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation)
static void
_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
{
Evas_Engine_Info_Software_X11 *einfo;
if (((ee->shaped) && (shaped)) ||
((!ee->shaped) && (!shaped)))
if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
return;
if (!strcmp(ee->driver, "gl_x11")) return;
ee->shaped = shaped;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (einfo)
if (!strcmp(ee->driver, "software_x11"))
{
if (ee->shaped)
Evas_Engine_Info_Software_X11 *einfo;
ee->shaped = shaped;
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
if (einfo)
{
GC gc;
XGCValues gcv;
ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1);
gcv.foreground = 0;
gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask,
GCForeground,
&gcv);
XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc,
0, 0, ee->w, ee->h);
XFreeGC(ecore_x_display_get(), gc);
einfo->info.mask = ee->engine.x.mask;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
if (ee->shaped)
{
GC gc;
XGCValues gcv;
ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1);
gcv.foreground = 0;
gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask,
GCForeground,
&gcv);
XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc,
0, 0, ee->w, ee->h);
XFreeGC(ecore_x_display_get(), gc);
einfo->info.mask = ee->engine.x.mask;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
}
else
{
if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
ee->engine.x.mask = 0;
einfo->info.mask = 0;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
ecore_x_window_shape_mask_set(ee->engine.x.win, 0);
ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0);
}
}
else
}
else if (!strcmp(ee->driver, "xrender_x11"))
{
Evas_Engine_Info_XRender_X11 *einfo;
ee->shaped = shaped;
einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
if (einfo)
{
if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
ee->engine.x.mask = 0;
einfo->info.mask = 0;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
ecore_x_window_shape_mask_set(ee->engine.x.win, 0);
ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0);
if (ee->shaped)
{
GC gc;
XGCValues gcv;
ee->engine.x.mask = ecore_x_pixmap_new(ee->engine.x.win, ee->w, ee->h, 1);
gcv.foreground = 0;
gc = XCreateGC(ecore_x_display_get(), ee->engine.x.mask,
GCForeground,
&gcv);
XFillRectangle(ecore_x_display_get(), ee->engine.x.mask, gc,
0, 0, ee->w, ee->h);
XFreeGC(ecore_x_display_get(), gc);
einfo->info.mask = ee->engine.x.mask;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
}
else
{
if (ee->engine.x.mask) ecore_x_pixmap_del(ee->engine.x.mask);
ee->engine.x.mask = 0;
einfo->info.mask = 0;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
ecore_x_window_shape_mask_set(ee->engine.x.win, 0);
ecore_x_window_shape_mask_set(ee->engine.x.win_container, 0);
}
}
}
}
@ -1932,7 +1969,7 @@ ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
Ecore_X_Window
ecore_evas_gl_x11_window_get(Ecore_Evas *ee)
{
#ifdef BUILD_ECORE_EVAS_GL
#ifdef BUILD_ECORE_X
return ee->engine.x.win_container;
#else
return 0;
@ -1995,3 +2032,213 @@ ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
ecore_evas_software_x11_extra_event_window_add(ee, win);
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
Ecore_Evas *
ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent,
int x, int y, int w, int h)
{
#ifdef BUILD_ECORE_EVAS_XRENDER
Evas_Engine_Info_XRender_X11 *einfo;
Ecore_Evas *ee;
int rmethod;
rmethod = evas_render_method_lookup("xrender_x11");
if (!rmethod) return NULL;
if (!ecore_x_init(disp_name)) return NULL;
ee = calloc(1, sizeof(Ecore_Evas));
if (!ee) return NULL;
ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
_ecore_evas_x_init();
ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
ee->driver = strdup("xrender_x11");
if (disp_name) ee->name = strdup(disp_name);
if (w < 1) w = 1;
if (h < 1) h = 1;
ee->x = x;
ee->y = y;
ee->w = w;
ee->h = h;
ee->prop.max.w = 32767;
ee->prop.max.h = 32767;
ee->prop.layer = 4;
ee->prop.request_pos = 0;
/* init evas here */
ee->evas = evas_new();
evas_output_method_set(ee->evas, rmethod);
evas_output_size_set(ee->evas, w, h);
evas_output_viewport_set(ee->evas, 0, 0, w, h);
ee->engine.x.win_root = parent;
ee->engine.x.win_container = ecore_x_window_new(parent, x, y, w, h);
if (getenv("DESKTOP_STARTUP_ID"))
{
ecore_x_netwm_startup_id_set(ee->engine.x.win_container,
getenv("DESKTOP_STARTUP_ID"));
putenv("DESKTOP_STARTUP_ID");
}
einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
if (einfo)
{
XSetWindowAttributes attr;
int screen;
/* FIXME: this is inefficient as its a round trip */
screen = DefaultScreen(ecore_x_display_get());
if (ScreenCount(ecore_x_display_get()) > 1)
{
Ecore_X_Window *roots;
int num, i;
num = 0;
roots = ecore_x_window_root_list(&num);
if (roots)
{
XWindowAttributes at;
if (XGetWindowAttributes(ecore_x_display_get(),
parent, &at))
{
for (i = 0; i < num; i++)
{
if (at.root == roots[i])
{
screen = i;
break;
}
}
}
free(roots);
}
}
attr.backing_store = NotUseful;
attr.override_redirect = True;
attr.colormap = DefaultColormap(ecore_x_display_get(), screen);
attr.border_pixel = 0;
attr.background_pixmap = None;
attr.event_mask =
KeyPressMask | KeyReleaseMask |
ExposureMask | ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask | StructureNotifyMask | VisibilityChangeMask |
FocusChangeMask | PropertyChangeMask | ColormapChangeMask;
attr.bit_gravity = ForgetGravity;
ee->engine.x.win =
XCreateWindow(ecore_x_display_get(),
ee->engine.x.win_container,
0, 0,
w, h, 0,
DefaultDepth(ecore_x_display_get(), screen),
InputOutput,
DefaultVisual(ecore_x_display_get(), screen),
CWBackingStore | CWColormap |
CWBackPixmap | CWBorderPixel |
CWBitGravity | CWEventMask |
CWOverrideRedirect,
&attr);
einfo->info.display = ecore_x_display_get();
einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
einfo->info.drawable = ee->engine.x.win;
evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
}
evas_key_modifier_add(ee->evas, "Shift");
evas_key_modifier_add(ee->evas, "Control");
evas_key_modifier_add(ee->evas, "Alt");
evas_key_modifier_add(ee->evas, "Meta");
evas_key_modifier_add(ee->evas, "Hyper");
evas_key_modifier_add(ee->evas, "Super");
evas_key_lock_add(ee->evas, "Caps_Lock");
evas_key_lock_add(ee->evas, "Num_Lock");
evas_key_lock_add(ee->evas, "Scroll_Lock");
ecore_evases = _ecore_list2_prepend(ecore_evases, ee);
ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win), ee);
ecore_evases_hash = evas_hash_add(ecore_evases_hash, _ecore_evas_x_winid_str_get(ee->engine.x.win_container), ee);
return ee;
#else
return NULL;
#endif
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
Ecore_X_Window
ecore_evas_xrender_x11_window_get(Ecore_Evas *ee)
{
#ifdef BUILD_ECORE_X
return ee->engine.x.win_container;
#else
return 0;
#endif
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
Ecore_X_Window
ecore_evas_xrender_x11_subwindow_get(Ecore_Evas *ee)
{
#ifdef BUILD_ECORE_X
return ee->engine.x.win;
#else
return 0;
#endif
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
void
ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on)
{
#ifdef BUILD_ECORE_X
ee->engine.x.direct_resize = on;
#else
return;
#endif
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
int
ecore_evas_xrender_x11_direct_resize_get(Ecore_Evas *ee)
{
#ifdef BUILD_ECORE_X
return ee->engine.x.direct_resize;
#else
return 0;
#endif
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
void
ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
{
ecore_evas_software_x11_extra_event_window_add(ee, win);
}