]> Pileus Git - ~andy/gtk/blob - gdk/win32/gdkdraw.c
Change GDK_WINDOWING_WIN32 usage to #ifdef also here.
[~andy/gtk] / gdk / win32 / gdkdraw.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library 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.
8  *
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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-1999.  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/. 
25  */
26
27 #include "config.h"
28
29 #include <math.h>
30
31 #include "gdkdrawable.h"
32 #include "gdkprivate.h"
33
34 #ifndef G_PI
35 #define G_PI 3.14159265358979323846
36 #endif
37
38 void
39 gdk_draw_point (GdkDrawable *drawable,
40                 GdkGC       *gc,
41                 gint         x,
42                 gint         y)
43 {
44   GdkWindowPrivate *drawable_private;
45   GdkGCPrivate *gc_private;
46   HDC hdc;
47
48   g_return_if_fail (drawable != NULL);
49   g_return_if_fail (gc != NULL);
50
51   drawable_private = (GdkWindowPrivate*) drawable;
52   if (drawable_private->destroyed)
53     return;
54   gc_private = (GdkGCPrivate*) gc;
55
56   hdc = gdk_gc_predraw (drawable_private, gc_private);
57
58   /* We use LineTo because SetPixel wants the COLORREF directly,
59    * and doesn't use the current pen, which is what we want.
60    */
61   if (!MoveToEx (hdc, x, y, NULL))
62     g_warning ("gdk_draw_point: MoveToEx failed");
63   if (!LineTo (hdc, x + 1, y))
64     g_warning ("gdk_draw_point: LineTo failed");
65   
66   gdk_gc_postdraw (drawable_private, gc_private);
67 }
68
69 void
70 gdk_draw_line (GdkDrawable *drawable,
71                GdkGC       *gc,
72                gint         x1,
73                gint         y1,
74                gint         x2,
75                gint         y2)
76 {
77   GdkWindowPrivate *drawable_private;
78   GdkGCPrivate *gc_private;
79   HDC hdc;
80
81   g_return_if_fail (drawable != NULL);
82   g_return_if_fail (gc != NULL);
83
84   drawable_private = (GdkWindowPrivate*) drawable;
85   if (drawable_private->destroyed)
86     return;
87   gc_private = (GdkGCPrivate*) gc;
88
89   hdc = gdk_gc_predraw (drawable_private, gc_private);
90     
91   GDK_NOTE (MISC, g_print ("gdk_draw_line: %#x (%d) +%d+%d..+%d+%d\n",
92                            drawable_private->xwindow, gc_private,
93                            x1, y1, x2, y2));
94   
95   MoveToEx (hdc, x1, y1, NULL);
96   if (!LineTo (hdc, x2, y2))
97     g_warning ("gdk_draw_line: LineTo #1 failed");
98   /* LineTo doesn't draw the last point, so if we have a pen width of 1,
99    * we draw the end pixel separately... With wider pens we don't care.
100    * //HB: But the NT developers don't read their API documentation ...
101    */
102   if (gc_private->pen_width == 1
103       && GetVersion () > 0x80000000)
104     if (!LineTo (hdc, x2 + 1, y2))
105       g_warning ("gdk_draw_line: LineTo #2 failed");
106   gdk_gc_postdraw (drawable_private, gc_private);
107 }
108
109 void
110 gdk_draw_rectangle (GdkDrawable *drawable,
111                     GdkGC       *gc,
112                     gint         filled,
113                     gint         x,
114                     gint         y,
115                     gint         width,
116                     gint         height)
117 {
118   GdkWindowPrivate *drawable_private;
119   GdkGCPrivate *gc_private;
120   HDC hdc;
121   HGDIOBJ oldpen, oldbrush;
122
123   g_return_if_fail (drawable != NULL);
124   g_return_if_fail (gc != NULL);
125
126   drawable_private = (GdkWindowPrivate*) drawable;
127   if (drawable_private->destroyed)
128     return;
129   gc_private = (GdkGCPrivate*) gc;
130
131   if (width == -1)
132     width = drawable_private->width;
133   if (height == -1)
134     height = drawable_private->height;
135
136   hdc = gdk_gc_predraw (drawable_private, gc_private);
137
138   GDK_NOTE (MISC, g_print ("gdk_draw_rectangle: %#x (%d) %s%dx%d@+%d+%d\n",
139                            drawable_private->xwindow,
140                            gc_private,
141                            (filled ? "fill " : ""),
142                            width, height, x, y));
143     
144 #if 0
145   {
146     HBRUSH hbr = GetCurrentObject (hdc, OBJ_BRUSH);
147     HPEN hpen = GetCurrentObject (hdc, OBJ_PEN);
148     LOGBRUSH lbr;
149     LOGPEN lpen;
150     GetObject (hbr, sizeof (lbr), &lbr);
151     GetObject (hpen, sizeof (lpen), &lpen);
152     
153     g_print ("current brush: style = %s, color = 0x%.08x\n",
154              (lbr.lbStyle == BS_SOLID ? "SOLID" : "???"),
155              lbr.lbColor);
156     g_print ("current pen: style = %s, width = %d, color = 0x%.08x\n",
157              (lpen.lopnStyle == PS_SOLID ? "SOLID" : "???"),
158              lpen.lopnWidth,
159              lpen.lopnColor);
160   }
161 #endif
162
163   if (filled)
164     oldpen = SelectObject (hdc, GetStockObject (NULL_PEN));
165   else
166     oldbrush = SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
167   
168   if (!Rectangle (hdc, x, y, x+width+1, y+height+1))
169     g_warning ("gdk_draw_rectangle: Rectangle failed");
170   
171   if (filled)
172     SelectObject (hdc, oldpen);
173   else
174     SelectObject (hdc, oldbrush);
175
176   gdk_gc_postdraw (drawable_private, gc_private);
177 }
178
179 void
180 gdk_draw_arc (GdkDrawable *drawable,
181               GdkGC       *gc,
182               gint         filled,
183               gint         x,
184               gint         y,
185               gint         width,
186               gint         height,
187               gint         angle1,
188               gint         angle2)
189 {
190   GdkWindowPrivate *drawable_private;
191   GdkGCPrivate *gc_private;
192   HDC hdc;
193   int nXStartArc, nYStartArc, nXEndArc, nYEndArc;
194
195   g_return_if_fail (drawable != NULL);
196   g_return_if_fail (gc != NULL);
197
198   drawable_private = (GdkWindowPrivate*) drawable;
199   if (drawable_private->destroyed)
200     return;
201   gc_private = (GdkGCPrivate*) gc;
202
203   if (width == -1)
204     width = drawable_private->width;
205   if (height == -1)
206     height = drawable_private->height;
207
208   GDK_NOTE (MISC, g_print ("gdk_draw_arc: %#x  %d,%d,%d,%d  %d %d\n",
209                            drawable_private->xwindow,
210                            x, y, width, height, angle1, angle2));
211
212   if (width != 0 && height != 0 && angle2 != 0)
213     {
214       hdc = gdk_gc_predraw (drawable_private, gc_private);
215
216       if (angle2 >= 360*64)
217         {
218           nXStartArc = nYStartArc = nXEndArc = nYEndArc = 0;
219         }
220       else if (angle2 > 0)
221         {
222           /* The 100. is just an arbitrary value */
223           nXStartArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
224           nYStartArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
225           nXEndArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
226           nYEndArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
227         }
228       else
229         {
230           nXEndArc = x + width/2 + 100. * cos(angle1/64.*2.*G_PI/360.);
231           nYEndArc = y + height/2 + -100. * sin(angle1/64.*2.*G_PI/360.);
232           nXStartArc = x + width/2 + 100. * cos((angle1+angle2)/64.*2.*G_PI/360.);
233           nYStartArc = y + height/2 + -100. * sin((angle1+angle2)/64.*2.*G_PI/360.);
234         }
235
236       if (filled)
237         {
238           GDK_NOTE (MISC, g_print ("...Pie(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
239                                    x, y, x+width, y+height,
240                                    nXStartArc, nYStartArc,
241                                    nXEndArc, nYEndArc));
242           Pie (hdc, x, y, x+width, y+height,
243                nXStartArc, nYStartArc, nXEndArc, nYEndArc);
244         }
245       else
246         {
247           GDK_NOTE (MISC, g_print ("...Arc(hdc,%d,%d,%d,%d,%d,%d,%d,%d)\n",
248                                    x, y, x+width, y+height,
249                                    nXStartArc, nYStartArc,
250                                    nXEndArc, nYEndArc));
251           Arc (hdc, x, y, x+width, y+height,
252                nXStartArc, nYStartArc, nXEndArc, nYEndArc);
253         }
254       gdk_gc_postdraw (drawable_private, gc_private);
255     }
256 }
257
258 void
259 gdk_draw_polygon (GdkDrawable *drawable,
260                   GdkGC       *gc,
261                   gint         filled,
262                   GdkPoint    *points,
263                   gint         npoints)
264 {
265   GdkWindowPrivate *drawable_private;
266   GdkGCPrivate *gc_private;
267   HDC hdc;
268   POINT *pts;
269   int i;
270
271   g_return_if_fail (drawable != NULL);
272   g_return_if_fail (gc != NULL);
273
274   drawable_private = (GdkWindowPrivate*) drawable;
275   if (drawable_private->destroyed)
276     return;
277   gc_private = (GdkGCPrivate*) gc;
278
279   GDK_NOTE (MISC, g_print ("gdk_draw_polygon: %#x (%d) %d\n",
280                            drawable_private->xwindow, gc_private,
281                            npoints));
282
283   if (npoints < 2)
284     return;
285
286   hdc = gdk_gc_predraw (drawable_private, gc_private);
287   pts = g_malloc ((npoints+1) * sizeof (POINT));
288
289   for (i = 0; i < npoints; i++)
290     {
291       pts[i].x = points[i].x;
292       pts[i].y = points[i].y;
293     }
294   
295   if ((points[0].x != points[npoints-1].x) ||
296       (points[0].y != points[npoints-1].y)) 
297     {
298       pts[npoints].x = points[0].x;
299       pts[npoints].y = points[0].y;
300       npoints++;
301     }
302   if (filled)
303     {
304       if (!Polygon (hdc, pts, npoints))
305         g_warning ("gdk_draw_polygon: Polygon failed");
306     }
307   else
308     {
309       if (!Polyline (hdc, pts, npoints))
310         g_warning ("gdk_draw_polygon: Polyline failed");
311     }
312   g_free (pts);
313   gdk_gc_postdraw (drawable_private, gc_private);
314 }
315
316 /* gdk_draw_string
317  */
318 void
319 gdk_draw_string (GdkDrawable *drawable,
320                  GdkFont     *font,
321                  GdkGC       *gc,
322                  gint         x,
323                  gint         y,
324                  const gchar *string)
325 {
326   gdk_draw_text (drawable, font, gc, x, y, string, strlen (string));
327 }
328
329 /* gdk_draw_text
330  *
331  * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
332  *
333  * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
334  */
335 void
336 gdk_draw_text (GdkDrawable *drawable,
337                GdkFont     *font,
338                GdkGC       *gc,
339                gint         x,
340                gint         y,
341                const gchar *text,
342                gint         text_length)
343 {
344   GdkWindowPrivate *drawable_private;
345   GdkFontPrivate *font_private;
346   GdkGCPrivate *gc_private;
347   HDC hdc;
348   HFONT xfont;
349   HGDIOBJ oldfont;
350
351   g_return_if_fail (drawable != NULL);
352   g_return_if_fail (font != NULL);
353   g_return_if_fail (gc != NULL);
354   g_return_if_fail (text != NULL);
355
356   drawable_private = (GdkWindowPrivate*) drawable;
357   if (drawable_private->destroyed)
358     return;
359   gc_private = (GdkGCPrivate*) gc;
360   font_private = (GdkFontPrivate*) font;
361
362   if (font->type == GDK_FONT_FONT)
363     {
364       hdc = gdk_gc_predraw (drawable_private, gc_private);
365       xfont = (HFONT) font_private->xfont;
366
367       GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
368                                "+%d+%d font: %#x \"%.*s\" length: %d\n",
369                                drawable_private->xwindow,
370                                gc_private, gc_private->xgc,
371                                x, y, xfont,
372                                (text_length > 10 ? 10 : text_length),
373                                text, text_length));
374       
375       if ((oldfont = SelectObject (hdc, xfont)) == NULL)
376         g_warning ("gdk_draw_text: SelectObject failed");
377       if (!TextOutA (hdc, x, y, text, text_length))
378         g_warning ("gdk_draw_text: TextOutA failed");
379       SelectObject (hdc, oldfont);
380       gdk_gc_postdraw (drawable_private, gc_private);
381     }
382   else
383     g_error ("undefined font type");
384 }
385
386 void
387 gdk_draw_text_wc (GdkDrawable    *drawable,
388                   GdkFont        *font,
389                   GdkGC          *gc,
390                   gint            x,
391                   gint            y,
392                   const GdkWChar *text,
393                   gint            text_length)
394 {
395   GdkWindowPrivate *drawable_private;
396   GdkFontPrivate *font_private;
397   GdkGCPrivate *gc_private;
398   gint i;
399   wchar_t *wcstr;
400
401   g_return_if_fail (drawable != NULL);
402   g_return_if_fail (font != NULL);
403   g_return_if_fail (gc != NULL);
404   g_return_if_fail (text != NULL);
405
406   drawable_private = (GdkWindowPrivate*) drawable;
407   if (drawable_private->destroyed)
408     return;
409   gc_private = (GdkGCPrivate*) gc;
410   font_private = (GdkFontPrivate*) font;
411
412   if (font->type == GDK_FONT_FONT)
413     {
414       HDC hdc;
415       HFONT xfont;
416       HGDIOBJ oldfont;
417
418       hdc = gdk_gc_predraw (drawable_private, gc_private);
419       xfont = (HFONT) font_private->xfont;
420
421       GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
422                                "+%d+%d font: %#x length: %d\n",
423                                drawable_private->xwindow,
424                                gc_private, gc_private->xgc,
425                                x, y, xfont,
426                                text_length));
427       
428       if ((oldfont = SelectObject (hdc, xfont)) == NULL)
429         g_warning ("gdk_draw_text: SelectObject failed");
430       wcstr = g_new (wchar_t, text_length);
431       for (i = 0; i < text_length; i++)
432         wcstr[i] = text[i];
433       if (!TextOutW (hdc, x, y, wcstr, text_length))
434         g_warning ("gdk_draw_text: TextOutW failed");
435       g_free (wcstr);
436       SelectObject (hdc, oldfont);
437       gdk_gc_postdraw (drawable_private, gc_private);
438     }
439   else
440     g_error ("undefined font type");
441 }
442
443 void
444 gdk_draw_pixmap (GdkDrawable *drawable,
445                  GdkGC       *gc,
446                  GdkPixmap   *src,
447                  gint         xsrc,
448                  gint         ysrc,
449                  gint         xdest,
450                  gint         ydest,
451                  gint         width,
452                  gint         height)
453 {
454   GdkWindowPrivate *drawable_private;
455   GdkWindowPrivate *src_private;
456   GdkGCPrivate *gc_private;
457   HDC hdc;
458   HDC srcdc;
459   HGDIOBJ hgdiobj;
460   HRGN src_rgn, draw_rgn, outside_rgn;
461   RECT r;
462
463   g_return_if_fail (drawable != NULL);
464   g_return_if_fail (src != NULL);
465   g_return_if_fail (gc != NULL);
466
467   drawable_private = (GdkWindowPrivate*) drawable;
468   src_private = (GdkWindowPrivate*) src;
469   if (drawable_private->destroyed || src_private->destroyed)
470     return;
471   gc_private = (GdkGCPrivate*) gc;
472
473   if (width == -1)
474     width = src_private->width; /* Or should we subtract xsrc? */
475   if (height == -1)
476     height = src_private->height; /* Ditto? */
477
478   GDK_NOTE (MISC, g_print ("gdk_draw_pixmap: dest: %#x "
479                            "src: %#x %dx%d@+%d+%d"
480                            " dest: %#x @+%d+%d\n",
481                            drawable_private->xwindow,
482                            src_private->xwindow,
483                            width, height, xsrc, ysrc,
484                            drawable_private->xwindow, xdest, ydest));
485
486   hdc = gdk_gc_predraw (drawable_private, gc_private);
487
488   src_rgn = CreateRectRgn (0, 0, src_private->width + 1, src_private->height + 1);
489   draw_rgn = CreateRectRgn (xsrc, ysrc, xsrc + width + 1, ysrc + height + 1);
490   SetRectEmpty (&r);
491   outside_rgn = CreateRectRgnIndirect (&r);
492   
493   if (drawable_private->window_type != GDK_WINDOW_PIXMAP)
494     {
495       /* If we are drawing on a window, calculate the region that is
496        * outside the source pixmap, and invalidate that, causing it to
497        * be cleared. XXX
498        */
499       if (CombineRgn (outside_rgn, draw_rgn, src_rgn, RGN_DIFF) != NULLREGION)
500         {
501           OffsetRgn (outside_rgn, xdest, ydest);
502           GDK_NOTE (MISC, (GetRgnBox (outside_rgn, &r),
503                            g_print ("...calling InvalidateRgn, "
504                                     "bbox: %dx%d@+%d+%d\n",
505                                     r.right - r.left - 1, r.bottom - r.top - 1,
506                                     r.left, r.top)));
507           InvalidateRgn (drawable_private->xwindow, outside_rgn, TRUE);
508         }
509     }
510
511 #if 1 /* Don't know if this is necessary  */
512   if (CombineRgn (draw_rgn, draw_rgn, src_rgn, RGN_AND) == COMPLEXREGION)
513     g_warning ("gdk_draw_pixmap: CombineRgn returned a COMPLEXREGION");
514
515   GetRgnBox (draw_rgn, &r);
516   if (r.left != xsrc
517       || r.top != ysrc
518       || r.right != xsrc + width + 1
519       || r.bottom != ysrc + height + 1)
520     {
521       xdest += r.left - xsrc;
522       xsrc = r.left;
523       ydest += r.top - ysrc;
524       ysrc = r.top;
525       width = r.right - xsrc - 1;
526       height = r.bottom - ysrc - 1;
527       
528       GDK_NOTE (MISC, g_print ("... restricted to src: %dx%d@+%d+%d, "
529                                "dest: @+%d+%d\n",
530                                width, height, xsrc, ysrc,
531                                xdest, ydest));
532     }
533 #endif
534
535   DeleteObject (src_rgn);
536   DeleteObject (draw_rgn);
537   DeleteObject (outside_rgn);
538
539   /* Strangely enough, this function is called also to bitblt
540    * from a window.
541    */
542   if (src_private->window_type == GDK_WINDOW_PIXMAP)
543     {
544       if ((srcdc = CreateCompatibleDC (hdc)) == NULL)
545         g_warning ("gdk_draw_pixmap: CreateCompatibleDC failed");
546       
547       if ((hgdiobj = SelectObject (srcdc, src_private->xwindow)) == NULL)
548         g_warning ("gdk_draw_pixmap: SelectObject #1 failed");
549       
550       if (!BitBlt (hdc, xdest, ydest, width, height,
551                    srcdc, xsrc, ysrc, SRCCOPY))
552         g_warning ("gdk_draw_pixmap: BitBlt failed");
553       
554       if ((SelectObject (srcdc, hgdiobj) == NULL))
555         g_warning ("gdk_draw_pixmap: SelectObject #2 failed");
556       
557       if (!DeleteDC (srcdc))
558         g_warning ("gdk_draw_pixmap: DeleteDC failed");
559     }
560   else
561     {
562       if (drawable_private->xwindow == src_private->xwindow)
563         {
564           /* Blitting inside a window, use ScrollDC */
565           RECT scrollRect, clipRect, emptyRect;
566           HRGN updateRgn;
567
568           scrollRect.left = MIN (xsrc, xdest);
569           scrollRect.top = MIN (ysrc, ydest);
570           scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1);
571           scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1);
572
573           clipRect.left = xdest;
574           clipRect.top = ydest;
575           clipRect.right = xdest + width + 1;
576           clipRect.bottom = ydest + height + 1;
577
578           SetRectEmpty (&emptyRect);
579           updateRgn = CreateRectRgnIndirect (&emptyRect);
580           if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc,
581                          &scrollRect, &clipRect,
582                          updateRgn, NULL))
583             g_warning ("gdk_draw_pixmap: ScrollDC failed");
584           if (!InvalidateRgn (drawable_private->xwindow, updateRgn, FALSE))
585             g_warning ("gdk_draw_pixmap: InvalidateRgn failed");
586           if (!UpdateWindow (drawable_private->xwindow))
587             g_warning ("gdk_draw_pixmap: UpdateWindow failed");
588         }
589       else
590         {
591           if ((srcdc = GetDC (src_private->xwindow)) == NULL)
592             g_warning ("gdk_draw_pixmap: GetDC failed");
593           
594           if (!BitBlt (hdc, xdest, ydest, width, height,
595                        srcdc, xsrc, ysrc, SRCCOPY))
596             g_warning ("gdk_draw_pixmap: BitBlt failed");
597           ReleaseDC (src_private->xwindow, srcdc);
598         }
599     }
600   gdk_gc_postdraw (drawable_private, gc_private);
601 }
602
603 void
604 gdk_draw_image (GdkDrawable *drawable,
605                 GdkGC       *gc,
606                 GdkImage    *image,
607                 gint         xsrc,
608                 gint         ysrc,
609                 gint         xdest,
610                 gint         ydest,
611                 gint         width,
612                 gint         height)
613 {
614   GdkImagePrivate *image_private;
615
616   g_return_if_fail (drawable != NULL);
617   g_return_if_fail (image != NULL);
618   g_return_if_fail (gc != NULL);
619
620   image_private = (GdkImagePrivate*) image;
621
622   g_return_if_fail (image_private->image_put != NULL);
623
624   if (width == -1)
625     width = image->width;
626   if (height == -1)
627     height = image->height;
628
629   (* image_private->image_put) (drawable, gc, image, xsrc, ysrc,
630                                 xdest, ydest, width, height);
631 }
632
633 void
634 gdk_draw_points (GdkDrawable *drawable,
635                  GdkGC       *gc,
636                  GdkPoint    *points,
637                  gint         npoints)
638 {
639   GdkWindowPrivate *drawable_private;
640   GdkGCPrivate *gc_private;
641   HDC hdc;
642   int i;
643
644   g_return_if_fail (drawable != NULL);
645   g_return_if_fail ((points != NULL) && (npoints > 0));
646   g_return_if_fail (gc != NULL);
647
648   drawable_private = (GdkWindowPrivate*) drawable;
649   if (drawable_private->destroyed)
650     return;
651   gc_private = (GdkGCPrivate*) gc;
652
653   hdc = gdk_gc_predraw (drawable_private, gc_private);
654   
655   GDK_NOTE (MISC, g_print ("gdk_draw_points: %#x destdc: (%d) %#x "
656                            "npoints: %d\n",
657                            drawable_private->xwindow, gc_private, hdc,
658                            npoints));
659
660   for (i = 0; i < npoints; i++)
661     {
662       if (!MoveToEx (hdc, points[i].x, points[i].y, NULL))
663         g_warning ("gdk_draw_points: MoveToEx failed");
664       if (!LineTo (hdc, points[i].x + 1, points[i].y))
665         g_warning ("gdk_draw_points: LineTo failed");
666     }
667   gdk_gc_postdraw (drawable_private, gc_private);
668 }
669
670 void
671 gdk_draw_segments (GdkDrawable *drawable,
672                    GdkGC       *gc,
673                    GdkSegment  *segs,
674                    gint         nsegs)
675 {
676   GdkWindowPrivate *drawable_private;
677   GdkGCPrivate *gc_private;
678   HDC hdc;
679   int i;
680
681   if (nsegs <= 0)
682     return;
683
684   g_return_if_fail (drawable != NULL);
685   g_return_if_fail (segs != NULL);
686   g_return_if_fail (gc != NULL);
687
688   drawable_private = (GdkWindowPrivate*) drawable;
689   if (drawable_private->destroyed)
690     return;
691   gc_private = (GdkGCPrivate*) gc;
692
693   hdc = gdk_gc_predraw (drawable_private, gc_private);
694
695   for (i = 0; i < nsegs; i++)
696     {
697       if (!MoveToEx (hdc, segs[i].x1, segs[i].y1, NULL))
698         g_warning ("gdk_draw_segments: MoveToEx failed");
699       if (!LineTo (hdc, segs[i].x2, segs[i].y2))
700         g_warning ("gdk_draw_segments: LineTo #1 failed");
701       
702       /* Draw end pixel */
703       if (gc_private->pen_width == 1)
704         if (!LineTo (hdc, segs[i].x2 + 1, segs[i].y2))
705           g_warning ("gdk_draw_segments: LineTo #2 failed");
706     }
707   gdk_gc_postdraw (drawable_private, gc_private);
708 }
709
710 void
711 gdk_draw_lines (GdkDrawable *drawable,
712                 GdkGC       *gc,
713                 GdkPoint    *points,
714                 gint         npoints)
715 {
716   GdkWindowPrivate *drawable_private;
717   GdkGCPrivate *gc_private;
718   HDC hdc;
719   POINT *pts;
720   int i;
721
722   if (npoints < 2)
723     return;
724
725   g_return_if_fail (drawable != NULL);
726   g_return_if_fail (points != NULL);
727   g_return_if_fail (gc != NULL);
728
729   drawable_private = (GdkWindowPrivate*) drawable;
730   gc_private = (GdkGCPrivate*) gc;
731
732   hdc = gdk_gc_predraw (drawable_private, gc_private);
733 #if 1
734   pts = g_malloc (npoints * sizeof (POINT));
735
736   for (i = 0; i < npoints; i++)
737     {
738       pts[i].x = points[i].x;
739       pts[i].y = points[i].y;
740     }
741   
742   if (!Polyline (hdc, pts, npoints))
743     g_warning ("gdk_draw_lines: Polyline(,,%d) failed", npoints);
744   
745   g_free (pts);
746   
747   /* Draw end pixel */
748   if (gc_private->pen_width == 1)
749     {
750       MoveToEx (hdc, points[npoints-1].x, points[npoints-1].y, NULL);
751       if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
752         g_warning ("gdk_draw_lines: LineTo failed");
753     }
754 #else
755   MoveToEx (hdc, points[0].x, points[0].y, NULL);
756   for (i = 1; i < npoints; i++)
757     if (!LineTo (hdc, points[i].x, points[i].y))
758       g_warning ("gdk_draw_lines: LineTo #1 failed");
759   
760   /* Draw end pixel */
761   if (gc_private->pen_width == 1)
762     if (!LineTo (hdc, points[npoints-1].x + 1, points[npoints-1].y))
763       g_warning ("gdk_draw_lines: LineTo #2 failed");
764 #endif  
765   gdk_gc_postdraw (drawable_private, gc_private);
766 }