1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 #include "gdkprivate-x11.h"
28 #include <pango/pangox.h>
33 #if defined (HAVE_IPC_H) && defined (HAVE_SHM_H) && defined (HAVE_XSHM_H)
38 #include <X11/extensions/XShm.h>
41 #include "gdkprivate-x11.h"
42 #include "gdkdrawable-x11.h"
43 #include "gdkpixmap-x11.h"
45 static void gdk_x11_draw_rectangle (GdkDrawable *drawable,
52 static void gdk_x11_draw_arc (GdkDrawable *drawable,
61 static void gdk_x11_draw_polygon (GdkDrawable *drawable,
66 static void gdk_x11_draw_text (GdkDrawable *drawable,
73 static void gdk_x11_draw_text_wc (GdkDrawable *drawable,
80 static void gdk_x11_draw_drawable (GdkDrawable *drawable,
89 static void gdk_x11_draw_points (GdkDrawable *drawable,
93 static void gdk_x11_draw_segments (GdkDrawable *drawable,
97 static void gdk_x11_draw_lines (GdkDrawable *drawable,
101 static void gdk_x11_draw_glyphs (GdkDrawable *drawable,
106 PangoGlyphString *glyphs);
107 static void gdk_x11_draw_image (GdkDrawable *drawable,
117 static void gdk_x11_set_colormap (GdkDrawable *drawable,
118 GdkColormap *colormap);
120 static GdkColormap* gdk_x11_get_colormap (GdkDrawable *drawable);
122 static gint gdk_x11_get_depth (GdkDrawable *drawable);
124 static void gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass);
126 static gpointer parent_class = NULL;
129 gdk_drawable_impl_x11_get_type (void)
131 static GType object_type = 0;
135 static const GTypeInfo object_info =
137 sizeof (GdkDrawableImplX11Class),
138 (GBaseInitFunc) NULL,
139 (GBaseFinalizeFunc) NULL,
140 (GClassInitFunc) gdk_drawable_impl_x11_class_init,
141 NULL, /* class_finalize */
142 NULL, /* class_data */
143 sizeof (GdkDrawableImplX11),
145 (GInstanceInitFunc) NULL,
148 object_type = g_type_register_static (GDK_TYPE_DRAWABLE,
149 "GdkDrawableImplX11",
157 gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
159 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
161 parent_class = g_type_class_peek_parent (klass);
163 drawable_class->create_gc = _gdk_x11_gc_new;
164 drawable_class->draw_rectangle = gdk_x11_draw_rectangle;
165 drawable_class->draw_arc = gdk_x11_draw_arc;
166 drawable_class->draw_polygon = gdk_x11_draw_polygon;
167 drawable_class->draw_text = gdk_x11_draw_text;
168 drawable_class->draw_text_wc = gdk_x11_draw_text_wc;
169 drawable_class->draw_drawable = gdk_x11_draw_drawable;
170 drawable_class->draw_points = gdk_x11_draw_points;
171 drawable_class->draw_segments = gdk_x11_draw_segments;
172 drawable_class->draw_lines = gdk_x11_draw_lines;
173 drawable_class->draw_glyphs = gdk_x11_draw_glyphs;
174 drawable_class->draw_image = gdk_x11_draw_image;
176 drawable_class->set_colormap = gdk_x11_set_colormap;
177 drawable_class->get_colormap = gdk_x11_get_colormap;
179 drawable_class->get_depth = gdk_x11_get_depth;
182 /*****************************************************
183 * X11 specific implementations of generic functions *
184 *****************************************************/
187 gdk_x11_get_colormap (GdkDrawable *drawable)
189 GdkDrawableImplX11 *impl;
191 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
193 return impl->colormap;
197 gdk_x11_set_colormap (GdkDrawable *drawable,
198 GdkColormap *colormap)
200 GdkDrawableImplX11 *impl;
202 g_return_if_fail (colormap != NULL);
204 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
206 if (impl->colormap == colormap)
210 gdk_colormap_unref (impl->colormap);
211 impl->colormap = colormap;
213 gdk_colormap_ref (impl->colormap);
220 gdk_x11_draw_rectangle (GdkDrawable *drawable,
228 GdkDrawableImplX11 *impl;
230 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
233 XFillRectangle (impl->xdisplay, impl->xid,
234 GDK_GC_GET_XGC (gc), x, y, width, height);
236 XDrawRectangle (impl->xdisplay, impl->xid,
237 GDK_GC_GET_XGC (gc), x, y, width, height);
241 gdk_x11_draw_arc (GdkDrawable *drawable,
251 GdkDrawableImplX11 *impl;
253 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
257 XFillArc (impl->xdisplay, impl->xid,
258 GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
260 XDrawArc (impl->xdisplay, impl->xid,
261 GDK_GC_GET_XGC (gc), x, y, width, height, angle1, angle2);
265 gdk_x11_draw_polygon (GdkDrawable *drawable,
273 GdkDrawableImplX11 *impl;
275 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
279 (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y))
281 tmp_npoints = npoints + 1;
282 tmp_points = g_new (XPoint, tmp_npoints);
283 tmp_points[npoints].x = points[0].x;
284 tmp_points[npoints].y = points[0].y;
288 tmp_npoints = npoints;
289 tmp_points = g_new (XPoint, tmp_npoints);
292 for (i=0; i<npoints; i++)
294 tmp_points[i].x = points[i].x;
295 tmp_points[i].y = points[i].y;
299 XFillPolygon (impl->xdisplay, impl->xid,
300 GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, Complex, CoordModeOrigin);
302 XDrawLines (impl->xdisplay, impl->xid,
303 GDK_GC_GET_XGC (gc), tmp_points, tmp_npoints, CoordModeOrigin);
310 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
312 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
315 gdk_x11_draw_text (GdkDrawable *drawable,
323 GdkDrawableImplX11 *impl;
325 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
327 if (font->type == GDK_FONT_FONT)
329 XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
330 XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
331 if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
333 XDrawString (impl->xdisplay, impl->xid,
334 GDK_GC_GET_XGC (gc), x, y, text, text_length);
338 XDrawString16 (impl->xdisplay, impl->xid,
339 GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
342 else if (font->type == GDK_FONT_FONTSET)
344 XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
345 XmbDrawString (impl->xdisplay, impl->xid,
346 fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
349 g_error("undefined font type\n");
353 gdk_x11_draw_text_wc (GdkDrawable *drawable,
358 const GdkWChar *text,
361 GdkDrawableImplX11 *impl;
363 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
365 if (font->type == GDK_FONT_FONT)
367 XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
370 XSetFont(impl->xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
371 text_8bit = g_new (gchar, text_length);
372 for (i=0; i<text_length; i++) text_8bit[i] = text[i];
373 XDrawString (impl->xdisplay, impl->xid,
374 GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length);
377 else if (font->type == GDK_FONT_FONTSET)
379 if (sizeof(GdkWChar) == sizeof(wchar_t))
381 XwcDrawString (impl->xdisplay, impl->xid,
382 (XFontSet) GDK_FONT_XFONT (font),
383 GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length);
389 text_wchar = g_new (wchar_t, text_length);
390 for (i=0; i<text_length; i++) text_wchar[i] = text[i];
391 XwcDrawString (impl->xdisplay, impl->xid,
392 (XFontSet) GDK_FONT_XFONT (font),
393 GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length);
398 g_error("undefined font type\n");
402 gdk_x11_draw_drawable (GdkDrawable *drawable,
412 int src_depth = gdk_drawable_get_depth (src);
413 int dest_depth = gdk_drawable_get_depth (drawable);
414 GdkDrawableImplX11 *impl;
416 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
420 XCopyArea (impl->xdisplay,
421 GDK_DRAWABLE_XID (src),
428 else if (dest_depth != 0 && src_depth == dest_depth)
430 XCopyArea (impl->xdisplay,
431 GDK_DRAWABLE_XID (src),
439 g_warning ("Attempt to copy between drawables of mismatched depths!\n");
443 gdk_x11_draw_points (GdkDrawable *drawable,
448 GdkDrawableImplX11 *impl;
450 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
453 /* We special-case npoints == 1, because X will merge multiple
454 * consecutive XDrawPoint requests into a PolyPoint request
458 XDrawPoint (impl->xdisplay,
461 points[0].x, points[0].y);
466 XPoint *tmp_points = g_new (XPoint, npoints);
468 for (i=0; i<npoints; i++)
470 tmp_points[i].x = points[i].x;
471 tmp_points[i].y = points[i].y;
474 XDrawPoints (impl->xdisplay,
486 gdk_x11_draw_segments (GdkDrawable *drawable,
491 GdkDrawableImplX11 *impl;
493 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
496 /* We special-case nsegs == 1, because X will merge multiple
497 * consecutive XDrawLine requests into a PolySegment request
501 XDrawLine (impl->xdisplay, impl->xid,
502 GDK_GC_GET_XGC (gc), segs[0].x1, segs[0].y1,
503 segs[0].x2, segs[0].y2);
508 XSegment *tmp_segs = g_new (XSegment, nsegs);
510 for (i=0; i<nsegs; i++)
512 tmp_segs[i].x1 = segs[i].x1;
513 tmp_segs[i].x2 = segs[i].x2;
514 tmp_segs[i].y1 = segs[i].y1;
515 tmp_segs[i].y2 = segs[i].y2;
518 XDrawSegments (impl->xdisplay,
528 gdk_x11_draw_lines (GdkDrawable *drawable,
534 XPoint *tmp_points = g_new (XPoint, npoints);
535 GdkDrawableImplX11 *impl;
537 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
540 for (i=0; i<npoints; i++)
542 tmp_points[i].x = points[i].x;
543 tmp_points[i].y = points[i].y;
546 XDrawLines (impl->xdisplay,
556 gdk_x11_draw_glyphs (GdkDrawable *drawable,
561 PangoGlyphString *glyphs)
563 GdkDrawableImplX11 *impl;
565 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
567 pango_x_render (impl->xdisplay,
574 gdk_x11_draw_image (GdkDrawable *drawable,
584 GdkDrawableImplX11 *impl;
586 impl = GDK_DRAWABLE_IMPL_X11 (drawable);
588 if (image->type == GDK_IMAGE_SHARED)
589 XShmPutImage (impl->xdisplay, impl->xid,
590 GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
591 xsrc, ysrc, xdest, ydest, width, height, False);
593 XPutImage (impl->xdisplay, impl->xid,
594 GDK_GC_GET_XGC (gc), GDK_IMAGE_XIMAGE (image),
595 xsrc, ysrc, xdest, ydest, width, height);
599 gdk_x11_get_depth (GdkDrawable *drawable)
601 /* This is a bit bogus but I'm not sure the other way is better */
603 return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper);