Thanks for your kind help. I have the source code of
the file. Please see the attachment.
The code provides some drawing methods. Can you give
more advice on it?
THanks!
Regards,
Ma Jun
--- Tristan Van Berkom <vantr touchtunes com>
µÄÕýÎÄ£º> I'm guessing that this is a new addition
to gtk or a piece of code floating on your desktop.
you can refer to the structure definition in the
header file to see what type of object it derives
from.
example:
struct _GtkMisc
{
GtkWidget widget;
gfloat xalign;
gfloat yalign;
guint16 xpad;
guint16 ypad;
};
struct _GtkMiscClass
{
GtkWidgetClass parent_class;
};
means that the GtkMisk derives from GtkWidget.
then you can refer to the docs to see what the
"parent" is capable of. (ofcourse you can refer
to the header file for the api).
Hope this helps,
-Tristan
_________________________________________________________
Do You Yahoo!?
ÑÅ»¢Í¨ÍøÂçKTV, ËæʱËæµØÃâ·Ñ¿¨ÀOK~~
http://rd.yahoo.com/mail_cn/tag/?http://cn.messenger.yahoo.com//chat/index.html
------------------------------------------------------------------------
X11
Subject: 272) How can I create a transparent widget?
[Last modified: Dec 98]
Answer: The simplest way is probably to use the SHAPE protocol extension. The
xeyes, xlogo, and oclock demo programs in X11R5 (and later) are good examples
of using SHAPE with widgets. You should be able to use the same techniques
with your Motif widget subclasses.
Ken Lee
Ken Sall (ksall cen com) adds: The official name for this extension is "X11
Nonrectangular Window Shape Extension". If you have X11R5 source, the Shape
extension document is $TOP/mit/hardcopy/extensions/shape.PS or
$TOP/mit/doc/extensions/shape.ms. In X11R6, see
$TOP/xc/doc/hardcopy/Xext/shape.PS or $TOP/xc/doc/specs/Xext/shape.ms. There
is also a terse man page: $TOP/mit/man/Xext/XShape.man (X11R5) and
$TOP/xc/doc/man/Xext/XShape.man (X11R6).
Ken Lee adds: Some graphics-oriented systems (e.g., SGI, HP) include hardware
overlay planes that support transparency directly. The APIs for accessing
these capabilities from Motif programs are non-standard. Read your system's
documentation or contact your vendor for more details.
I want to get a transparent window(linux) sth like solaris transparent overlay
window, through which we can see the motion under it or we move itself.
And one more thing is that it will be applied with XDraw* primitive.
How can i?
if i understand your question (which i'm not sure i do) you have 2
choices:
1) use the GnomeCanvas (or its repackaged version, GtkCanvas).
this provides a drawing canvas that supports alpha transparency
and lots of other cool things.
2) get familiar with gdk_window_shape_combine_mask (). start by
finding where its used in the testgtk.c source code that
comes with GTK+. this doesn't support transparency, just
the notion of non-rectangular windows.
i have a widget called GtkTransparency which provides the same drawing
primitives as gdk (draw_line, draw_polygon, draw_text, etc); the
widget is visible *only* where it has been drawn onto. it makes heavy
use of gtk_window_shape_combine_mask(). if you want to get a copy, ask
me. note, however, that its not *transparent* - where it *has* been
drawn onto, it is 100% opaque.
you need to keep in mind that standard X servers do not support an
alpha channel for transparency purposes, so you cannot do transparency
in general unless you, not the X server, are responsible for all the
rendering. obviously, you do not control the rendering of windows not
owned by your process, so there are clear limits to what you can
accomplish in this area.
--p Paul Davis <pbd op net>
//GdkPixmap *pixmap;
//GdkBitmap *mask;
//GdkGC *gc;
//...
///* The window has to exist before we create the pixmap */
///* Passing any drawable ought to be fine though(?) */
//gtk_widget_show(main_win);
//pixmap = gdk_pixmap_create_from_xpm(main_win->window,
// &mask,
// NULL,
// "/usr/X11/include/X11/pixmaps/mail.xpm");
//
//gc = gdk_gc_new(main_win->window);
//gdk_gc_set_clip_mask(gc, mask);
//gdk_gc_set_clip_origin(gc, 50, 50);
//
//gdk_draw_pixmap(main_win->window, gc, pixmap, 0, 0, 50, 50, -1, -1);
On Fri, 6 Mar 1998, Johannes Keukelaar wrote:
Hello all,
I tried to post this earlier, but suspect that it didn't get through. I seem to
get kicked off the mailing list every couple of days or so. *sigh* Anyway, if
it didn't get through:
I CC this directly to you just in case you get thrown off again.
I'm working on an application that will visualize certain expensive-to-draw
objects; these objects are nonrectangular, have a position and size and may
overlap. Even worse (I would think) is that the objects may even have holes in
them; just drawing a filled polygon and then filling in the holes again with
the background color would not always work for overlapping objects.
For this reason and to speed up rendering, I've been looking at using partially
transparent pixmaps. However, there doesn't seem to be a way to properly draw
these on the screen. Given, e.g. a pixmap and a bitmap mask, how would I go
about drawing those on the screen so that the transparency mask works? I've
been unable to figure out a better way than to do this in a loop with
GetPixel/PutPixel (or some such). Any hints?
The trick is to set the clip mask of the GC you use for drawing the
pixmap. The following snippet should do the trick.
GdkPixmap *pixmap;
GdkBitmap *mask;
GdkGC *gc;
...
/* The window has to exist before we create the pixmap */
/* Passing any drawable ought to be fine though(?) */
gtk_widget_show(main_win);
pixmap = gdk_pixmap_create_from_xpm(main_win->window,
&mask,
NULL,
"/usr/X11/include/X11/pixmaps/mail.xpm");
gc = gdk_gc_new(main_win->window);
gdk_gc_set_clip_mask(gc, mask);
gdk_gc_set_clip_origin(gc, 50, 50);
gdk_draw_pixmap(main_win->window, gc, pixmap, 0, 0, 50, 50, -1, -1);
...
Hope this helps.
-----------------------------------------------------------------------
Per Lewau (perle lysator liu se)Student of Computer Science at the
University of Linkoping,
Sweden.
"Why waste time learning, when ignorance is instantaneous?"
- Hobbes
Hello all,
I try to make a transparent window, what I did is:
1. create a window with default size 400X400 by calling
gtk_window_new(...) and gtk_window_set_default_size(...).
2. create background Pixmap and a mask by calling
gdk_pixmap_create_from_xpm(....).
3. set the Pixmap to be the background pixmap of the window by
modifying the GtkStyle of the window.
4. After I call gtk_window_shape_combine_mask(...), the window size
has been changed because half left area is transparent. However, I
still need to draw something
on that area in the future. I tryed call
gdk_window_resize(....), but it doesnot work.
So I wonder
1. How I can make a window transparent without change its size.
2. How to make a window absolutely transparent without any background
Pixmap and any background color, but still has the size 400*400.
Any help is appreciated!.
Thanks very much
Jiang
Code enclosed. Patches/Fixes/Improvements welcome.
-------- gtktransparency.c ---------------------------------
/* This file is intended to be part of GTK - The GIMP Toolkit
* Copyright (C) 1999 Paul Barton-Davis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_TRANSPARENCY_H__
#define __GTK_TRANSPARENCY_H__
#include <gdk/gdk.h>
#include <gtk/gtkwidget.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_TRANSPARENCY(obj) GTK_CHECK_CAST (obj, gtk_transparency_get_type (), GtkTransparency)
#define GTK_TRANSPARENCY_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_transparency_get_type (),
GtkTransparencyClass)
#define GTK_IS_TRANSPARENCY(obj) GTK_CHECK_TYPE (obj, gtk_transparency_get_type ())
typedef struct _GtkTransparency GtkTransparency;
typedef struct _GtkTransparencyClass GtkTransparencyClass;
struct _GtkTransparency
{
GtkWidget widget;
GdkPixmap *buffer;
GdkBitmap *mask;
GdkBitmap *clearmask;
GdkGC *bitmap_gc;
gpointer draw_data;
};
struct _GtkTransparencyClass
{
GtkWidgetClass parent_class;
};
guint gtk_transparency_get_type (void);
GtkWidget* gtk_transparency_new (void);
void gtk_transparency_size (GtkTransparency *darea,
gint width,
gint height);
GdkWindow* gtk_transparency_buffer (GtkTransparency*);
void gtk_transparency_project (GtkTransparency*);
void gtk_transparency_wipe (GtkTransparency*);
void gtk_transparency_set_mask_gc (GtkTransparency*,
GdkGCValues *values,
gint values_mask);
/* Drawing
*/
void gtk_transparency_draw_point (GtkTransparency *drawable,
GdkGC *gc,
gint x,
gint y);
void gtk_transparency_draw_line (GtkTransparency *drawable,
GdkGC *gc,
gint x1,
gint y1,
gint x2,
gint y2);
void gtk_transparency_draw_rectangle (GtkTransparency *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height);
void gtk_transparency_draw_arc (GtkTransparency *drawable,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height,
gint angle1,
gint angle2);
void gtk_transparency_draw_polygon (GtkTransparency *drawable,
GdkGC *gc,
gint filled,
GdkPoint *points,
gint npoints);
void gtk_transparency_draw_string (GtkTransparency *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *string);
void gtk_transparency_draw_text (GtkTransparency *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *text,
gint text_length);
void gtk_transparency_draw_text_wc (GtkTransparency *drawable,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const GdkWChar *text,
gint text_length);
void gtk_transparency_draw_pixmap (GtkTransparency *drawable,
GdkGC *gc,
GdkDrawable *src,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
void gtk_transparency_draw_image (GtkTransparency *drawable,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height);
void gtk_transparency_draw_points (GtkTransparency *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints);
void gtk_transparency_draw_segments (GtkTransparency *drawable,
GdkGC *gc,
GdkSegment *segs,
gint nsegs);
void gtk_transparency_draw_lines (GtkTransparency *drawable,
GdkGC *gc,
GdkPoint *points,
gint npoints);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_TRANSPARENCY_H__ */
------- gtktransparency.c ---------------------------------------
/* This file is intended to be part of GTK - The GIMP Toolkit
* Copyright (C) 1999 Paul Barton-Davis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gtkmmext/gtktransparency.h>
static void gtk_transparency_class_init (GtkTransparencyClass *klass);
static void gtk_transparency_init (GtkTransparency *tarea);
static void gtk_transparency_realize (GtkWidget *widget);
static void gtk_transparency_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_transparency_send_configure (GtkTransparency *tarea);
guint
gtk_transparency_get_type (void)
{
static guint drawing_area_type = 0;
if (!drawing_area_type)
{
static const GtkTypeInfo drawing_area_info =
{
"GtkTransparency",
sizeof (GtkTransparency),
sizeof (GtkTransparencyClass),
(GtkClassInitFunc) gtk_transparency_class_init,
(GtkObjectInitFunc) gtk_transparency_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
drawing_area_type = gtk_type_unique (gtk_widget_get_type (), &drawing_area_info);
}
return drawing_area_type;
}
static void
gtk_transparency_class_init (GtkTransparencyClass *class)
{
GtkWidgetClass *widget_class;
widget_class = (GtkWidgetClass*) class;
widget_class->realize = gtk_transparency_realize;
widget_class->size_allocate = gtk_transparency_size_allocate;
}
static void
gtk_transparency_init (GtkTransparency *tarea)
{
tarea->draw_data = NULL;
}
GtkWidget*
gtk_transparency_new (void)
{
return GTK_WIDGET (gtk_type_new (gtk_transparency_get_type ()));
}
void
gtk_transparency_size (GtkTransparency *tarea,
gint width,
gint height)
{
g_return_if_fail (tarea != NULL);
g_return_if_fail (GTK_IS_TRANSPARENCY (tarea));
GTK_WIDGET (tarea)->requisition.width = width;
GTK_WIDGET (tarea)->requisition.height = height;
}
static void
gtk_transparency_realize (GtkWidget *w)
{
GtkTransparency *tarea;
GdkWindowAttr attributes;
gchar *clear_data;
GdkColor zero;
GdkColor one;
gint attributes_mask;
g_return_if_fail (w != NULL);
g_return_if_fail (GTK_IS_TRANSPARENCY (w));
tarea = GTK_TRANSPARENCY (w);
GTK_WIDGET_SET_FLAGS (w, GTK_REALIZED);
attributes.window_type = GDK_WINDOW_CHILD;
attributes.x = w->allocation.x;
attributes.y = w->allocation.y;
attributes.width = w->allocation.width;
attributes.height = w->allocation.height;
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.visual = gtk_widget_get_visual (w);
attributes.colormap = gtk_widget_get_colormap (w);
attributes.event_mask = gtk_widget_get_events (w) | GDK_EXPOSURE_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
w->window = gdk_window_new (gtk_widget_get_parent_window (w),
&attributes, attributes_mask);
tarea->buffer = gdk_pixmap_new (w->window,
w->allocation.width,
w->allocation.height, -1);
tarea->mask = gdk_pixmap_new (w->window,
w->allocation.width,
w->allocation.height, 1);
/* create a GC for bitmap (depth=1) operations */
gdk_color_black (gdk_colormap_get_system (), &zero);
if (zero.pixel != 0) {
gdk_color_white (gdk_colormap_get_system(), &zero);
gdk_color_black (gdk_colormap_get_system(), &one);
} else {
gdk_color_white (gdk_colormap_get_system(), &one);
}
tarea->bitmap_gc = gdk_gc_new (tarea->mask);
gdk_gc_set_foreground (tarea->bitmap_gc, &one);
gdk_gc_set_background (tarea->bitmap_gc, &zero);
/* Create a clear bitmap */
clear_data = (gchar *) g_malloc (w->allocation.width * w->allocation.height);
memset (clear_data, 0, w->allocation.width * w->allocation.height);
tarea->clearmask = gdk_pixmap_create_from_data (w->window,
clear_data,
w->allocation.width,
w->allocation.height,
1,
&one,
&zero);
/* use it to clear the mask */
/* XXX use filled rectangle instead */
gdk_window_copy_area (tarea->mask,
tarea->bitmap_gc,
0, 0,
tarea->clearmask,
0, 0,
w->allocation.width,
w->allocation.height);
gdk_window_shape_combine_mask (w->window, tarea->mask, 0, 0);
g_free (clear_data);
gdk_window_set_user_data (w->window, tarea);
w->style = gtk_style_attach (w->style, w->window);
gtk_transparency_send_configure (GTK_TRANSPARENCY (w));
}
static void
gtk_transparency_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_TRANSPARENCY (widget));
g_return_if_fail (allocation != NULL);
widget->allocation = *allocation;
if (GTK_WIDGET_REALIZED (widget))
{
gdk_window_move_resize (widget->window,
allocation->x, allocation->y,
allocation->width, allocation->height);
gtk_transparency_send_configure (GTK_TRANSPARENCY (widget));
}
}
static void
gtk_transparency_send_configure (GtkTransparency *tarea)
{
GtkWidget *widget;
GdkEventConfigure event;
widget = GTK_WIDGET (tarea);
event.type = GDK_CONFIGURE;
event.window = widget->window;
event.x = widget->allocation.x;
event.y = widget->allocation.y;
event.width = widget->allocation.width;
event.height = widget->allocation.height;
gtk_widget_event (widget, (GdkEvent*) &event);
}
GdkWindow *
gtk_transparency_buffer (GtkTransparency *tarea)
{
return tarea->buffer;
}
void
gtk_transparency_project (GtkTransparency *tarea)
{
GtkWidget *w = GTK_WIDGET(tarea);
/* Reshape the window */
gdk_window_shape_combine_mask (w->window, tarea->mask, 0, 0);
/* flush the current pixmap into the window */
gdk_draw_pixmap (w->window, w->style->fg_gc[GTK_STATE_NORMAL],
tarea->buffer, 0, 0, 0, 0,
w->allocation.width, w->allocation.height);
}
void
gtk_transparency_wipe (GtkTransparency *tarea)
{
GtkWidget *w = GTK_WIDGET(tarea);
gdk_window_copy_area (tarea->mask,
tarea->bitmap_gc,
0, 0,
tarea->clearmask,
0, 0,
w->allocation.width,
w->allocation.height);
}
/* Drawing Functions */
#define CHECK_GC(t,gc) \
if (gc == NULL) { \
gc = GTK_WIDGET(t)->style->fg_gc[GTK_WIDGET_STATE(GTK_WIDGET(t))];\
}
void
gtk_transparency_draw_rectangle (GtkTransparency *tarea,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height)
{
CHECK_GC(tarea,gc);
gdk_draw_rectangle (tarea->mask, tarea->bitmap_gc,
filled, x, y, width, height);
gdk_draw_rectangle (tarea->buffer, gc, filled, x, y, width, height);
}
void gtk_transparency_draw_point (GtkTransparency *tarea,
GdkGC *gc,
gint x,
gint y)
{
CHECK_GC(tarea,gc);
gdk_draw_point (tarea->mask, tarea->bitmap_gc, x, y);
gdk_draw_point (tarea->buffer, gc, x, y);
}
void gtk_transparency_draw_line (GtkTransparency *tarea,
GdkGC *gc,
gint x1,
gint y1,
gint x2,
gint y2)
{
CHECK_GC(tarea,gc);
gdk_draw_line (tarea->mask, tarea->bitmap_gc, x1, y1, x2, y2);
gdk_draw_line (tarea->buffer, gc, x1, y1, x2, y2);
}
void gtk_transparency_draw_arc (GtkTransparency *tarea,
GdkGC *gc,
gint filled,
gint x,
gint y,
gint width,
gint height,
gint angle1,
gint angle2)
{
CHECK_GC(tarea,gc);
gdk_draw_arc (tarea->mask, tarea->bitmap_gc, filled, x, y,
width, height, angle1, angle2);
gdk_draw_arc (tarea->buffer, gc, filled, x, y,
width, height, angle1, angle2);
}
void gtk_transparency_draw_polygon (GtkTransparency *tarea,
GdkGC *gc,
gint filled,
GdkPoint *points,
gint npoints)
{
CHECK_GC(tarea,gc);
gdk_draw_polygon (tarea->mask, tarea->bitmap_gc, filled,
points, npoints);
gdk_draw_polygon (tarea->buffer, gc, filled,
points, npoints);
}
void gtk_transparency_draw_string (GtkTransparency *tarea,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *string)
{
CHECK_GC(tarea,gc);
gdk_draw_string (tarea->mask, font, tarea->bitmap_gc, x, y, string);
gdk_draw_string (tarea->buffer, font, gc, x, y, string);
}
void gtk_transparency_draw_text (GtkTransparency *tarea,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const gchar *text,
gint text_length)
{
CHECK_GC(tarea,gc);
gdk_draw_text (tarea->mask, font, tarea->bitmap_gc, x, y,
text, text_length);
gdk_draw_text (tarea->buffer, font, gc, x, y,
text, text_length);
}
void gtk_transparency_draw_text_wc (GtkTransparency *tarea,
GdkFont *font,
GdkGC *gc,
gint x,
gint y,
const GdkWChar *text,
gint text_length)
{
CHECK_GC(tarea,gc);
gdk_draw_text_wc (tarea->mask, font, tarea->bitmap_gc, x, y,
text, text_length);
gdk_draw_text_wc (tarea->buffer, font, gc, x, y,
text, text_length);
}
void gtk_transparency_draw_pixmap (GtkTransparency *tarea,
GdkGC *gc,
GdkDrawable *src,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
CHECK_GC(tarea,gc);
gdk_draw_pixmap (tarea->mask, tarea->bitmap_gc,
src, xsrc, ysrc, xdest, ydest,
width, height);
gdk_draw_pixmap (tarea->buffer, gc,
src, xsrc, ysrc, xdest, ydest,
width, height);
}
void gtk_transparency_draw_image (GtkTransparency *tarea,
GdkGC *gc,
GdkImage *image,
gint xsrc,
gint ysrc,
gint xdest,
gint ydest,
gint width,
gint height)
{
CHECK_GC(tarea,gc);
gdk_draw_image (tarea->mask, tarea->bitmap_gc,
image, xsrc, ysrc, xdest, ydest,
width, height);
gdk_draw_image (tarea->buffer, gc,
image, xsrc, ysrc, xdest, ydest,
width, height);
}
void gtk_transparency_draw_points (GtkTransparency *tarea,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
CHECK_GC(tarea,gc);
gdk_draw_points (tarea->mask, tarea->bitmap_gc, points, npoints);
gdk_draw_points (tarea->buffer, gc, points, npoints);
}
void gtk_transparency_draw_segments (GtkTransparency *tarea,
GdkGC *gc,
GdkSegment *segs,
gint nsegs)
{
CHECK_GC(tarea,gc);
gdk_draw_segments (tarea->mask, tarea->bitmap_gc, segs, nsegs);
gdk_draw_segments (tarea->buffer, gc, segs, nsegs);
}
void gtk_transparency_draw_lines (GtkTransparency *tarea,
GdkGC *gc,
GdkPoint *points,
gint npoints)
{
CHECK_GC(tarea,gc);
gdk_draw_lines (tarea->mask, tarea->bitmap_gc, points, npoints);
gdk_draw_lines (tarea->buffer, gc, points, npoints);
}
void
gtk_transparency_set_mask_gc (GtkTransparency *tarea,
GdkGCValues *values,
gint values_mask)
{
gdk_gc_change_values (tarea->bitmap_gc,
values,
values_mask);
}