internal doubleBuffer with re-copy ==> OK
This commit is contained in:
parent
3dad4f219b
commit
d3efb637ab
@ -127,7 +127,7 @@ cairo_font_face_t * Display::GetFont(bool bold, bool italic)
|
||||
#undef __class__
|
||||
#define __class__ "DrawerManager"
|
||||
|
||||
#define megaplop mlkjmlk
|
||||
//#define megaplop mlkjmlk
|
||||
/**
|
||||
* @brief DrawerManager constructor : generate a memoryDC where we can draw everything...
|
||||
*
|
||||
@ -151,42 +151,25 @@ DrawerManager::DrawerManager(GtkWidget * widget, int32_t x, int32_t y)
|
||||
m_windows = widget->window;
|
||||
# endif
|
||||
|
||||
#ifdef megaplop
|
||||
m_cairoWindows = gdk_cairo_create(m_windows);
|
||||
|
||||
// create internal surface :
|
||||
m_imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, x, y);
|
||||
m_cairo = cairo_create(m_imageSurface);
|
||||
|
||||
// copy current windows :
|
||||
cairo_surface_t * drawable_surface = cairo_get_target(m_cairoWindows);
|
||||
cairo_set_source_surface(m_cairo, drawable_surface, 0, 0);
|
||||
cairo_paint(m_cairo);
|
||||
|
||||
|
||||
// for Test only : this remove slowly the old line that is not rewritten
|
||||
cairo_set_source_rgb(m_cairo, 0, 0, 0);
|
||||
cairo_set_source_rgba(m_cairo, 1, 1, 1, 0.3);
|
||||
cairo_paint(m_cairo);
|
||||
|
||||
cairo_set_font_size(m_cairo, POLICE_SIZE);
|
||||
m_dataToDisplay[0] = '\0';
|
||||
// Double buffer with previous copy management :
|
||||
{
|
||||
// Create the Cairo context from the current windows
|
||||
cairo_t * cairoWindows = gdk_cairo_create(m_windows);
|
||||
// inform that we nee a double buffer
|
||||
GdkRectangle myRect = {0, 0, x, y};
|
||||
gdk_window_begin_paint_rect(m_windows, &myRect);
|
||||
// Create the Cairo context from the double Buffer just created
|
||||
m_cairo = gdk_cairo_create(m_windows);
|
||||
// Copy the previous display data from the current display to the double buffer area:
|
||||
cairo_surface_t * drawableSurface = cairo_get_target(cairoWindows);
|
||||
cairo_set_source_surface(m_cairo, drawableSurface, 0, 0);
|
||||
cairo_paint(m_cairo);
|
||||
//cairo_surface_destroy(drawableSurface);
|
||||
cairo_destroy(cairoWindows);
|
||||
}
|
||||
|
||||
cairo_scale(m_cairo, 1.0, 1.0);
|
||||
cairo_scale(m_cairoWindows, 1.0, 1.0);
|
||||
|
||||
#else
|
||||
|
||||
// start painting : we not use the automatic double buffered for internal optimisation, then we nee to work with this :
|
||||
|
||||
/*
|
||||
GdkRectangle myRect = {0, 0, 300, 300};
|
||||
gdk_window_begin_paint_rect(m_windows, &myRect);
|
||||
*/
|
||||
|
||||
// Create the Cairo Element
|
||||
m_cairo = gdk_cairo_create(m_windows);
|
||||
//cairo_translate(m_cairo, 0, 7);
|
||||
// for Test only : this remove slowly the old line that is not rewritten
|
||||
cairo_set_source_rgb(m_cairo, 0, 0, 0);
|
||||
cairo_set_source_rgba(m_cairo, 1, 1, 1, 0.3);
|
||||
@ -195,14 +178,8 @@ DrawerManager::DrawerManager(GtkWidget * widget, int32_t x, int32_t y)
|
||||
cairo_set_font_size(m_cairo, POLICE_SIZE);
|
||||
m_dataToDisplay[0] = '\0';
|
||||
|
||||
cairo_scale(m_cairo, 1.0, 1.0);
|
||||
|
||||
#endif
|
||||
|
||||
m_nbElement = 0;
|
||||
|
||||
|
||||
|
||||
// http://cairographics.org/FAQ/#clear_a_surface
|
||||
// http://gtk.developpez.com/faq/?page=gtkwidget#GTK_WIDGET_transparent
|
||||
//cairo_set_source_rgba(m_cairo, 1, 1, 1, 0);
|
||||
@ -225,16 +202,10 @@ DrawerManager::DrawerManager(GtkWidget * widget, int32_t x, int32_t y)
|
||||
*/
|
||||
DrawerManager::~DrawerManager()
|
||||
{
|
||||
#ifdef megaplop
|
||||
cairo_set_source_surface(m_cairoWindows, m_imageSurface, 0, 0);
|
||||
cairo_paint(m_cairoWindows);
|
||||
// call the painting of the double buffer in the displayed current buffer
|
||||
gdk_window_end_paint(m_windows);
|
||||
// Destroy cairo context
|
||||
cairo_destroy(m_cairo);
|
||||
cairo_destroy(m_cairoWindows);
|
||||
#else
|
||||
// fill the diplayed buffer ...
|
||||
//gdk_window_end_paint(m_windows);
|
||||
cairo_destroy(m_cairo);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,8 +86,6 @@ class DrawerManager {
|
||||
position_ts m_size; //!< Total size
|
||||
cairo_t * m_cairo; //!< Cairo Layout pointer
|
||||
GdkWindow * m_windows; //!< remember the current widget ==> for some internal problems
|
||||
cairo_t * m_cairoWindows; //!< Cairo context
|
||||
cairo_surface_t *m_imageSurface;
|
||||
};
|
||||
|
||||
|
||||
|
@ -36,6 +36,9 @@ int main(int argc, char **argv)
|
||||
|
||||
gtk_widget_set_app_paintable(window, TRUE);
|
||||
|
||||
// Remove double-buffering ==> in the current case we can not get the previous display...
|
||||
gtk_widget_set_double_buffered(window, FALSE);
|
||||
|
||||
# if USE_GTK_VERSION_3_0
|
||||
g_signal_connect(G_OBJECT(window), "draw", G_CALLBACK(expose), NULL);
|
||||
# elif USE_GTK_VERSION_2_0
|
||||
@ -60,17 +63,17 @@ int main(int argc, char **argv)
|
||||
&color);
|
||||
*/
|
||||
#endif
|
||||
gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
|
||||
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
|
||||
g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);
|
||||
//gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
|
||||
//gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
|
||||
/* //g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(clicked), NULL);
|
||||
|
||||
GtkWidget* fixed_container = gtk_fixed_new();
|
||||
gtk_container_add(GTK_CONTAINER(window), fixed_container);
|
||||
GtkWidget* button = gtk_button_new_with_label("button1");
|
||||
gtk_widget_set_size_request(button, 100, 100);
|
||||
gtk_container_add(GTK_CONTAINER(fixed_container), button);
|
||||
|
||||
screen_changed(window, NULL, NULL);
|
||||
*/
|
||||
//screen_changed(window, NULL, NULL);
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
gtk_main();
|
||||
@ -114,20 +117,36 @@ static void screen_changed(GtkWidget *widget, GdkScreen *old_screen, gpointer us
|
||||
|
||||
static gboolean expose(GtkWidget *widget, GdkEventExpose *event, gpointer userdata)
|
||||
{
|
||||
return FALSE;
|
||||
# if USE_GTK_VERSION_3_0
|
||||
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
|
||||
# elif USE_GTK_VERSION_2_0
|
||||
cairo_t *cr = gdk_cairo_create(widget->window);
|
||||
# endif
|
||||
if (TRUE == supports_alpha)
|
||||
cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.3); /* transparent */
|
||||
else
|
||||
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); /* opaque white */
|
||||
|
||||
/* draw the background */
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
//return FALSE;
|
||||
GdkWindow * m_windows = NULL;
|
||||
# if USE_GTK_VERSION_3_0
|
||||
m_windows = gtk_widget_get_window(widget);
|
||||
# elif USE_GTK_VERSION_2_0
|
||||
m_windows = widget->window;
|
||||
# endif
|
||||
gtk_widget_shape_combine_mask(widget, NULL, 0, 0);
|
||||
cairo_t *cr = gdk_cairo_create(m_windows);
|
||||
|
||||
|
||||
|
||||
//if (TRUE == supports_alpha) {
|
||||
cairo_set_source_rgba (cr, 0.0, 0.0, 1.0, 0.2); // transparent
|
||||
/*} else {
|
||||
cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); // opaque white
|
||||
}*/
|
||||
/* draw the background */
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (cr);
|
||||
|
||||
/* draw a circle */
|
||||
int width, height;
|
||||
gtk_window_get_size(GTK_WINDOW(widget), &width, &height);
|
||||
|
||||
cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
|
||||
cairo_arc(cr, width / 2, height / 2, (width < height ? width : height) / 2 - 8 , 0, 2 * 3.14);
|
||||
cairo_fill(cr);
|
||||
cairo_stroke(cr);
|
||||
|
||||
cairo_destroy(cr);
|
||||
|
||||
|
292
test_transparence2.c
Normal file
292
test_transparence2.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*******************************************************************************
|
||||
**3456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
||||
** 10 20 30 40 50 60 70 80
|
||||
**
|
||||
** program:
|
||||
** input_shape_test
|
||||
**
|
||||
** created:
|
||||
** 19.2.2006
|
||||
**
|
||||
** last change:
|
||||
** 20.2.2006
|
||||
**
|
||||
** author:
|
||||
** Mirco "MacSlow" Mueller <macslow@bangang.de>
|
||||
**
|
||||
** license:
|
||||
** GPL
|
||||
**
|
||||
** notes:
|
||||
** - this is a test I did to figure out how to use input-shapes (XShape 1.1)
|
||||
** - opens a decoration-less and transparent gtk+-window and draws a red
|
||||
** cross with a circle around it
|
||||
** - only the parts drawn will be "draggable"
|
||||
** - window can be dragged around with LMB-drag
|
||||
** - window can be resized with MMB-drag (the input-shape also resizes!)
|
||||
** - window can be exited with ESC or q
|
||||
** - needs a compositing manager to run in order to look as intended
|
||||
** - tested with xcompmgr and compiz
|
||||
** - tested with gtk+-2.8.11 and gtk+-2.9.0 (CVS-head)
|
||||
**
|
||||
** bugs:
|
||||
** - there are no size-checks done for the input-shape, so I don't know what
|
||||
** will happen, if you make the window super large
|
||||
**
|
||||
** todo:
|
||||
** - nothing
|
||||
**
|
||||
** compile with:
|
||||
** gcc `pkg-config --cflags --libs gtk+-2.0` input_shape_test.c -o input_shape_test
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
#if !GTK_CHECK_VERSION(2,9,0)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#endif
|
||||
|
||||
#define WIN_WIDTH 300
|
||||
#define WIN_HEIGHT 300
|
||||
|
||||
gint g_iCurrentWidth = WIN_WIDTH;
|
||||
gint g_iCurrentHeight = WIN_HEIGHT;
|
||||
|
||||
void update_input_shape (GtkWidget* pWindow, int iWidth, int iHeight);
|
||||
void on_alpha_screen_changed (GtkWidget* pWidget, GdkScreen* pOldScreen, GtkWidget* pLabel);
|
||||
void render (cairo_t* pCairoContext, gint iWidth, gint iHeight);
|
||||
gboolean on_expose (GtkWidget* pWidget, GdkEventExpose* pExpose);
|
||||
gboolean on_key_press (GtkWidget* pWidget, GdkEventKey* pKey, gpointer userData);
|
||||
gboolean on_button_press (GtkWidget* pWidget, GdkEventButton* pButton, GdkWindowEdge edge);
|
||||
gboolean on_configure (GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer data);
|
||||
#if !GTK_CHECK_VERSION(2,9,0)
|
||||
void do_shape_combine_mask (GdkWindow* window, GdkBitmap* mask, gint x, gint y);
|
||||
#endif
|
||||
void update_input_shape (GtkWidget* pWindow, int iWidth, int iHeight);
|
||||
|
||||
void on_alpha_screen_changed (GtkWidget* pWidget,
|
||||
GdkScreen* pOldScreen,
|
||||
GtkWidget* pLabel)
|
||||
{
|
||||
GdkScreen* pScreen = gtk_widget_get_screen (pWidget);
|
||||
GdkColormap* pColormap = gdk_screen_get_rgba_colormap (pScreen);
|
||||
|
||||
if (!pColormap)
|
||||
pColormap = gdk_screen_get_rgb_colormap (pScreen);
|
||||
|
||||
gtk_widget_set_colormap (pWidget, pColormap);
|
||||
}
|
||||
|
||||
void render (cairo_t* pCairoContext, gint iWidth, gint iHeight)
|
||||
{
|
||||
cairo_scale (pCairoContext, (double) iWidth, (double) iHeight);
|
||||
cairo_set_source_rgba (pCairoContext, 1.0f, 1.0f, 1.0f, 0.0f);
|
||||
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_paint (pCairoContext);
|
||||
cairo_set_source_rgba (pCairoContext, 1.0f, 0.0f, 0.0f, 0.75f);
|
||||
cairo_set_line_width (pCairoContext, 0.1f);
|
||||
cairo_move_to (pCairoContext, 0.15f, 0.15f);
|
||||
cairo_line_to (pCairoContext, 0.85f, 0.85f);
|
||||
cairo_move_to (pCairoContext, 0.85f, 0.15f);
|
||||
cairo_line_to (pCairoContext, 0.15f, 0.85f);
|
||||
cairo_stroke (pCairoContext);
|
||||
cairo_arc (pCairoContext, 0.5f, 0.5f, 0.45f, 0.0f, M_PI/180.0f * 360.0f);
|
||||
cairo_stroke (pCairoContext);
|
||||
}
|
||||
|
||||
gboolean on_expose (GtkWidget* pWidget,
|
||||
GdkEventExpose* pExpose)
|
||||
{
|
||||
gint iWidth;
|
||||
gint iHeight;
|
||||
cairo_t* pCairoContext = NULL;
|
||||
|
||||
pCairoContext = gdk_cairo_create (pWidget->window);
|
||||
if (!pCairoContext)
|
||||
return FALSE;
|
||||
|
||||
gtk_window_get_size (GTK_WINDOW (pWidget), &iWidth, &iHeight);
|
||||
render (pCairoContext, iWidth, iHeight);
|
||||
cairo_destroy (pCairoContext);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean on_configure (GtkWidget* pWidget,
|
||||
GdkEventConfigure* pEvent,
|
||||
gpointer userData)
|
||||
{
|
||||
gint iNewWidth = pEvent->width;
|
||||
gint iNewHeight = pEvent->height;
|
||||
|
||||
if (iNewWidth != g_iCurrentWidth || iNewHeight != g_iCurrentHeight)
|
||||
{
|
||||
update_input_shape (pWidget, iNewWidth, iNewHeight);
|
||||
g_iCurrentWidth = iNewWidth;
|
||||
g_iCurrentHeight = iNewHeight;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean on_key_press (GtkWidget* pWidget,
|
||||
GdkEventKey* pKey,
|
||||
gpointer userData)
|
||||
{
|
||||
gint iWidth;
|
||||
gint iHeight;
|
||||
|
||||
if (pKey->type == GDK_KEY_PRESS)
|
||||
{
|
||||
switch (pKey->keyval)
|
||||
{
|
||||
case GDK_Escape :
|
||||
case GDK_q :
|
||||
gtk_main_quit ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean on_button_press (GtkWidget* pWidget,
|
||||
GdkEventButton* pButton,
|
||||
GdkWindowEdge edge)
|
||||
{
|
||||
if (pButton->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
if (pButton->button == 1)
|
||||
gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
|
||||
pButton->button,
|
||||
pButton->x_root,
|
||||
pButton->y_root,
|
||||
pButton->time);
|
||||
if (pButton->button == 2)
|
||||
gtk_window_begin_resize_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
|
||||
edge,
|
||||
pButton->button,
|
||||
pButton->x_root,
|
||||
pButton->y_root,
|
||||
pButton->time);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if !GTK_CHECK_VERSION(2,9,0)
|
||||
/* this is piece by piece taken from gtk+ 2.9.0 (CVS-head with a patch applied
|
||||
regarding XShape's input-masks) so people without gtk+ >= 2.9.0 can compile and
|
||||
run input_shape_test.c */
|
||||
void do_shape_combine_mask (GdkWindow* window,
|
||||
GdkBitmap* mask,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
Pixmap pixmap;
|
||||
int ignore;
|
||||
int maj;
|
||||
int min;
|
||||
|
||||
if (!XShapeQueryExtension (GDK_WINDOW_XDISPLAY (window), &ignore, &ignore))
|
||||
return;
|
||||
|
||||
if (!XShapeQueryVersion (GDK_WINDOW_XDISPLAY (window), &maj, &min))
|
||||
return;
|
||||
|
||||
/* for shaped input we need at least XShape 1.1 */
|
||||
if (maj != 1 && min < 1)
|
||||
return;
|
||||
|
||||
if (mask)
|
||||
pixmap = GDK_DRAWABLE_XID (mask);
|
||||
else
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
pixmap = None;
|
||||
}
|
||||
|
||||
XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_DRAWABLE_XID (window),
|
||||
ShapeInput,
|
||||
x,
|
||||
y,
|
||||
pixmap,
|
||||
ShapeSet);
|
||||
}
|
||||
#endif
|
||||
|
||||
void update_input_shape (GtkWidget* pWindow, int iWidth, int iHeight)
|
||||
{
|
||||
static GdkBitmap* pShapeBitmap = NULL;
|
||||
static cairo_t* pCairoContext = NULL;
|
||||
|
||||
pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL, iWidth, iHeight, 1);
|
||||
if (pShapeBitmap)
|
||||
{
|
||||
pCairoContext = gdk_cairo_create (pShapeBitmap);
|
||||
if (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
render (pCairoContext, iWidth, iHeight);
|
||||
cairo_destroy (pCairoContext);
|
||||
#if !GTK_CHECK_VERSION(2,9,0)
|
||||
do_shape_combine_mask (pWindow->window, NULL, 0, 0);
|
||||
do_shape_combine_mask (pWindow->window, pShapeBitmap, 0, 0);
|
||||
#else
|
||||
gtk_widget_input_shape_combine_mask (pWindow, NULL, 0, 0);
|
||||
gtk_widget_input_shape_combine_mask (pWindow, pShapeBitmap, 0, 0);
|
||||
#endif
|
||||
}
|
||||
g_object_unref ((gpointer) pShapeBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
GtkWidget* pWindow = NULL;
|
||||
GdkBitmap* pShapeMaskBitmap = NULL;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
on_alpha_screen_changed (pWindow, NULL, NULL);
|
||||
gtk_widget_set_app_paintable (pWindow, TRUE);
|
||||
gtk_window_set_decorated (GTK_WINDOW (pWindow), FALSE);
|
||||
gtk_window_set_resizable (GTK_WINDOW (pWindow), TRUE);
|
||||
gtk_window_set_title (GTK_WINDOW (pWindow), "gtk+/XShape 1.1 test");
|
||||
gtk_widget_set_size_request (pWindow, g_iCurrentWidth, g_iCurrentHeight);
|
||||
gtk_widget_add_events (pWindow, GDK_BUTTON_PRESS_MASK);
|
||||
gtk_widget_show (pWindow);
|
||||
|
||||
g_signal_connect (G_OBJECT (pWindow),
|
||||
"destroy",
|
||||
G_CALLBACK (gtk_main_quit),
|
||||
NULL);
|
||||
g_signal_connect (G_OBJECT (pWindow),
|
||||
"expose-event",
|
||||
G_CALLBACK (on_expose),
|
||||
NULL);
|
||||
g_signal_connect (G_OBJECT (pWindow),
|
||||
"configure-event",
|
||||
G_CALLBACK (on_configure),
|
||||
NULL);
|
||||
g_signal_connect (G_OBJECT (pWindow),
|
||||
"key-press-event",
|
||||
G_CALLBACK (on_key_press),
|
||||
NULL);
|
||||
g_signal_connect (G_OBJECT (pWindow),
|
||||
"button-press-event",
|
||||
G_CALLBACK (on_button_press),
|
||||
NULL);
|
||||
|
||||
update_input_shape (pWindow, g_iCurrentWidth, g_iCurrentHeight);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user