gdkimage-win32.c

Go to the documentation of this file.
00001 /* GDK - The GIMP Drawing Kit
00002  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
00022  * file for a list of people on the GTK+ Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
00025  */
00026 
00027 #include "config.h"
00028 
00029 #include "gdk.h"                /* For gdk_error_trap_* / gdk_flush_* */
00030 #include "gdkimage.h"
00031 #include "gdkprivate.h"
00032 #include "gdkwin32.h"
00033 
00034 static void gdk_win32_image_destroy(GdkImage * image);
00035 static void gdk_image_put(GdkImage * image,
00036                           GdkDrawable * drawable,
00037                           GdkGC * gc,
00038                           gint xsrc,
00039                           gint ysrc,
00040                           gint xdest, gint ydest, gint width, gint height);
00041 
00042 static GdkImageClass image_class = {
00043    gdk_win32_image_destroy,
00044    gdk_image_put
00045 };
00046 
00047 static GList *image_list = NULL;
00048 
00049 void gdk_image_exit(void)
00050 {
00051    GdkImage *image;
00052 
00053    while (image_list) {
00054       image = image_list->data;
00055       gdk_win32_image_destroy(image);
00056    }
00057 }
00058 
00059 GdkImage *gdk_image_new_bitmap(GdkVisual * visual, gpointer data, gint w,
00060                                gint h)
00061 /*
00062  * Desc: create a new bitmap image
00063  */
00064 {
00065    Visual *xvisual;
00066    GdkImage *image;
00067    GdkImagePrivateWin32 *private;
00068    struct {
00069       BITMAPINFOHEADER bmiHeader;
00070       union {
00071          WORD bmiIndices[2];
00072          RGBQUAD bmiColors[2];
00073       } u;
00074    } bmi;
00075    char *bits;
00076    int bpl = (w - 1) / 8 + 1;
00077    int bpl32 = ((w - 1) / 32 + 1) * 4;
00078 
00079    private = g_new(GdkImagePrivateWin32, 1);
00080    image = (GdkImage *) private;
00081    private->base.ref_count = 1;
00082    private->base.klass = &image_class;
00083 
00084    image->type = GDK_IMAGE_SHARED;
00085    image->visual = visual;
00086    image->width = w;
00087    image->height = h;
00088    image->depth = 1;
00089    xvisual = ((GdkVisualPrivate *) visual)->xvisual;
00090 
00091    GDK_NOTE(MISC, g_print("gdk_image_new_bitmap: %dx%d\n", w, h));
00092 
00093    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00094    bmi.bmiHeader.biWidth = w;
00095    bmi.bmiHeader.biHeight = -h;
00096    bmi.bmiHeader.biPlanes = 1;
00097    bmi.bmiHeader.biBitCount = 1;
00098    bmi.bmiHeader.biCompression = BI_RGB;
00099    bmi.bmiHeader.biSizeImage = 0;
00100    bmi.bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter = 0;
00101    bmi.bmiHeader.biClrUsed = 0;
00102    bmi.bmiHeader.biClrImportant = 0;
00103 
00104    bmi.u.bmiColors[0].rgbBlue =
00105        bmi.u.bmiColors[0].rgbGreen = bmi.u.bmiColors[0].rgbRed = 0x00;
00106    bmi.u.bmiColors[0].rgbReserved = 0x00;
00107 
00108    bmi.u.bmiColors[1].rgbBlue =
00109        bmi.u.bmiColors[1].rgbGreen = bmi.u.bmiColors[1].rgbRed = 0xFF;
00110    bmi.u.bmiColors[1].rgbReserved = 0x00;
00111 
00112    private->ximage = CreateDIBSection(gdk_DC, (BITMAPINFO *) & bmi,
00113                                       DIB_RGB_COLORS, &bits, NULL, 0);
00114    if (bpl != bpl32) {
00115       /* Win32 expects scanlines in DIBs to be 32 bit aligned */
00116       int i;
00117       for (i = 0; i < h; i++)
00118          memmove(bits + i * bpl32, ((char *) data) + i * bpl, bpl);
00119    } else
00120       memmove(bits, data, bpl * h);
00121    image->mem = bits;
00122    image->bpl = bpl32;
00123    image->byte_order = GDK_MSB_FIRST;
00124 
00125    image->bpp = 1;
00126    return (image);
00127 }                               /* gdk_image_new_bitmap() */
00128 
00129 void gdk_image_init(void)
00130 {
00131 }
00132 
00133 static GdkImage *gdk_image_new_with_depth(GdkImageType type,
00134                                           GdkVisual * visual,
00135                                           gint width,
00136                                           gint height, gint depth)
00137 {
00138    GdkImage *image;
00139    GdkImagePrivateWin32 *private;
00140    Visual *xvisual;
00141    struct {
00142       BITMAPINFOHEADER bmiHeader;
00143       union {
00144          WORD bmiIndices[256];
00145          DWORD bmiMasks[3];
00146          RGBQUAD bmiColors[256];
00147       } u;
00148    } bmi;
00149    UINT iUsage;
00150    int i;
00151 
00152    if (type == GDK_IMAGE_FASTEST || type == GDK_IMAGE_NORMAL)
00153       type = GDK_IMAGE_SHARED;
00154 
00155    GDK_NOTE(MISC, g_print("gdk_image_new_with_depth: %dx%dx%d %s\n",
00156                           width, height, depth,
00157                           (type == GDK_IMAGE_SHARED ? "shared" :
00158                            (type ==
00159                             GDK_IMAGE_SHARED_PIXMAP ? "shared_pixmap" :
00160                             "???"))));
00161 
00162    private = g_new(GdkImagePrivateWin32, 1);
00163    image = (GdkImage *) private;
00164 
00165    private->base.ref_count = 1;
00166    private->base.klass = &image_class;
00167 
00168    image->type = type;
00169    image->visual = visual;
00170    image->width = width;
00171    image->height = height;
00172    image->depth = depth;
00173 
00174    xvisual = ((GdkVisualPrivate *) visual)->xvisual;
00175 
00176    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00177    bmi.bmiHeader.biWidth = width;
00178    bmi.bmiHeader.biHeight = -height;
00179    bmi.bmiHeader.biPlanes = 1;
00180    if (depth == 15)
00181       bmi.bmiHeader.biBitCount = 16;
00182    else
00183       bmi.bmiHeader.biBitCount = depth;
00184 #if 1
00185    if (depth == 16)
00186       bmi.bmiHeader.biCompression = BI_BITFIELDS;
00187    else
00188 #endif
00189       bmi.bmiHeader.biCompression = BI_RGB;
00190    bmi.bmiHeader.biSizeImage = 0;
00191    bmi.bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter = 0;
00192    bmi.bmiHeader.biClrUsed = 0;
00193    bmi.bmiHeader.biClrImportant = 0;
00194 
00195    if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR) {
00196       iUsage = DIB_PAL_COLORS;
00197       for (i = 0; i < 256; i++)
00198          bmi.u.bmiIndices[i] = i;
00199    } else {
00200       if (depth == 1) {
00201          bmi.u.bmiColors[0].rgbBlue =
00202              bmi.u.bmiColors[0].rgbGreen =
00203              bmi.u.bmiColors[0].rgbRed = 0x00;
00204          bmi.u.bmiColors[0].rgbReserved = 0x00;
00205 
00206          bmi.u.bmiColors[1].rgbBlue =
00207              bmi.u.bmiColors[1].rgbGreen =
00208              bmi.u.bmiColors[1].rgbRed = 0xFF;
00209          bmi.u.bmiColors[1].rgbReserved = 0x00;
00210 
00211       }
00212 #if 1
00213       else if (depth == 16) {
00214          bmi.u.bmiMasks[0] = visual->red_mask;
00215          bmi.u.bmiMasks[1] = visual->green_mask;
00216          bmi.u.bmiMasks[2] = visual->blue_mask;
00217       }
00218 #endif
00219       iUsage = DIB_RGB_COLORS;
00220    }
00221 
00222    private->ximage =
00223        CreateDIBSection(gdk_DC, (BITMAPINFO *) & bmi, iUsage,
00224                         &image->mem, NULL, 0);
00225 
00226    if (private->ximage == NULL) {
00227       WIN32_GDI_FAILED("CreateDIBSection");
00228       g_free(image);
00229       return NULL;
00230    }
00231 
00232    switch (depth) {
00233    case 1:
00234    case 8:
00235       image->bpp = 1;
00236       break;
00237    case 15:
00238    case 16:
00239       image->bpp = 2;
00240       break;
00241    case 24:
00242       image->bpp = 3;
00243       break;
00244    case 32:
00245       image->bpp = 4;
00246       break;
00247    default:
00248       g_warning("gdk_image_new_with_depth: depth = %d", depth);
00249       g_assert_not_reached();
00250    }
00251    image->byte_order = GDK_LSB_FIRST;
00252    if (depth == 1)
00253       image->bpl = ((width - 1) / 32 + 1) * 4;
00254    else
00255       image->bpl = ((width * image->bpp - 1) / 4 + 1) * 4;
00256 
00257    GDK_NOTE(MISC, g_print("... = %#x mem = %#x, bpl = %d\n",
00258                           private->ximage, image->mem, image->bpl));
00259 
00260    return image;
00261 }
00262 
00263 GdkImage *gdk_image_new(GdkImageType type,
00264                         GdkVisual * visual, gint width, gint height)
00265 {
00266    GdkVisualPrivate *visual_private = (GdkVisualPrivate *) visual;
00267    return gdk_image_new_with_depth(type, visual, width, height,
00268 #if 0
00269                                    visual_private->xvisual->bitspixel);
00270 #else
00271                                    visual->depth);
00272 #endif
00273 }
00274 
00275 GdkImage *gdk_image_bitmap_new(GdkImageType type,
00276                                GdkVisual * visual, gint width, gint height)
00277 {
00278    return gdk_image_new_with_depth(type, visual, width, height, 1);
00279 }
00280 
00281 GdkImage *gdk_image_get(GdkWindow * window,
00282                         gint x, gint y, gint width, gint height)
00283 {
00284    GdkImage *image;
00285    GdkImagePrivateWin32 *private;
00286    HDC hdc, memdc;
00287    struct {
00288       BITMAPINFOHEADER bmiHeader;
00289       union {
00290          WORD bmiIndices[256];
00291          DWORD bmiMasks[3];
00292          RGBQUAD bmiColors[256];
00293       } u;
00294    } bmi;
00295    HGDIOBJ oldbitmap1, oldbitmap2;
00296    UINT iUsage;
00297    BITMAP bm;
00298    int i;
00299 
00300    g_return_val_if_fail(window != NULL, NULL);
00301 
00302    if (GDK_DRAWABLE_DESTROYED(window))
00303       return NULL;
00304 
00305    GDK_NOTE(MISC, g_print("gdk_image_get: %#x %dx%d@+%d+%d\n",
00306                           GDK_DRAWABLE_XID(window), width, height, x, y));
00307 
00308    private = g_new(GdkImagePrivateWin32, 1);
00309    image = (GdkImage *) private;
00310 
00311    private->base.ref_count = 1;
00312    private->base.klass = &image_class;
00313 
00314    image->type = GDK_IMAGE_SHARED;
00315    image->visual = gdk_window_get_visual(window);
00316    image->width = width;
00317    image->height = height;
00318 
00319    /* This function is called both to blit from a window and from
00320     * a pixmap.
00321     */
00322    if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00323       if ((hdc = CreateCompatibleDC(NULL)) == NULL) {
00324          WIN32_GDI_FAILED("CreateCompatibleDC");
00325          g_free(image);
00326          return NULL;
00327       }
00328       if ((oldbitmap1 =
00329            SelectObject(hdc, GDK_DRAWABLE_XID(window))) == NULL) {
00330          WIN32_GDI_FAILED("SelectObject");
00331          DeleteDC(hdc);
00332          g_free(image);
00333          return NULL;
00334       }
00335       GetObject(GDK_DRAWABLE_XID(window), sizeof(BITMAP), &bm);
00336       GDK_NOTE(MISC,
00337                g_print
00338                ("gdk_image_get: bmWidth = %d, bmHeight = %d, bmWidthBytes = %d, bmBitsPixel = %d\n",
00339                 bm.bmWidth, bm.bmHeight, bm.bmWidthBytes, bm.bmBitsPixel));
00340       image->depth = bm.bmBitsPixel;
00341       if (image->depth <= 8) {
00342          iUsage = DIB_PAL_COLORS;
00343          for (i = 0; i < 256; i++)
00344             bmi.u.bmiIndices[i] = i;
00345       } else
00346          iUsage = DIB_RGB_COLORS;
00347    } else {
00348       if ((hdc = GetDC(GDK_DRAWABLE_XID(window))) == NULL) {
00349          WIN32_GDI_FAILED("GetDC");
00350          g_free(image);
00351          return NULL;
00352       }
00353       image->depth = gdk_visual_get_system()->depth;
00354       if (image->visual->type == GDK_VISUAL_PSEUDO_COLOR) {
00355          iUsage = DIB_PAL_COLORS;
00356          for (i = 0; i < 256; i++)
00357             bmi.u.bmiIndices[i] = i;
00358       } else
00359          iUsage = DIB_RGB_COLORS;
00360    }
00361 
00362    if ((memdc = CreateCompatibleDC(hdc)) == NULL) {
00363       WIN32_GDI_FAILED("CreateCompatibleDC");
00364       if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00365          SelectObject(hdc, oldbitmap1);
00366          DeleteDC(hdc);
00367       } else {
00368          ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
00369       }
00370       g_free(image);
00371       return NULL;
00372    }
00373 
00374    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00375    bmi.bmiHeader.biWidth = width;
00376    bmi.bmiHeader.biHeight = -height;
00377    bmi.bmiHeader.biPlanes = 1;
00378    bmi.bmiHeader.biBitCount = image->depth;
00379    if (image->depth == 16) {
00380       bmi.bmiHeader.biCompression = BI_BITFIELDS;
00381       if (image->visual == NULL) {
00382          /* XXX ??? Is it always this if depth==16 and a pixmap? Guess so. */
00383          bmi.u.bmiMasks[0] = 0xf800;
00384          bmi.u.bmiMasks[1] = 0x07e0;
00385          bmi.u.bmiMasks[2] = 0x001f;
00386       } else {
00387          bmi.u.bmiMasks[0] = image->visual->red_mask;
00388          bmi.u.bmiMasks[1] = image->visual->green_mask;
00389          bmi.u.bmiMasks[2] = image->visual->blue_mask;
00390       }
00391    } else
00392       bmi.bmiHeader.biCompression = BI_RGB;
00393    bmi.bmiHeader.biSizeImage = 0;
00394    bmi.bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter = 0;
00395    bmi.bmiHeader.biClrUsed = 0;
00396    bmi.bmiHeader.biClrImportant = 0;
00397 
00398    if ((private->ximage =
00399         CreateDIBSection(hdc, (BITMAPINFO *) & bmi, iUsage,
00400                          &image->mem, NULL, 0)) == NULL) {
00401       WIN32_GDI_FAILED("CreateDIBSection");
00402       DeleteDC(memdc);
00403       if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00404          SelectObject(hdc, oldbitmap1);
00405          DeleteDC(hdc);
00406       } else {
00407          ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
00408       }
00409       g_free(image);
00410       return NULL;
00411    }
00412 
00413    if ((oldbitmap2 = SelectObject(memdc, private->ximage)) == NULL) {
00414       WIN32_GDI_FAILED("SelectObject");
00415       DeleteObject(private->ximage);
00416       DeleteDC(memdc);
00417       if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00418          SelectObject(hdc, oldbitmap1);
00419          DeleteDC(hdc);
00420       } else {
00421          ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
00422       }
00423       g_free(image);
00424       return NULL;
00425    }
00426 
00427    if (!BitBlt(memdc, 0, 0, width, height, hdc, x, y, SRCCOPY)) {
00428       WIN32_GDI_FAILED("BitBlt");
00429       SelectObject(memdc, oldbitmap2);
00430       DeleteObject(private->ximage);
00431       DeleteDC(memdc);
00432       if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00433          SelectObject(hdc, oldbitmap1);
00434          DeleteDC(hdc);
00435       } else {
00436          ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
00437       }
00438       g_free(image);
00439       return NULL;
00440    }
00441 
00442    if (SelectObject(memdc, oldbitmap2) == NULL)
00443       WIN32_GDI_FAILED("SelectObject");
00444 
00445    if (!DeleteDC(memdc))
00446       WIN32_GDI_FAILED("DeleteDC");
00447 
00448    if (GDK_DRAWABLE_TYPE(window) == GDK_DRAWABLE_PIXMAP) {
00449       SelectObject(hdc, oldbitmap1);
00450       DeleteDC(hdc);
00451    } else {
00452       ReleaseDC(GDK_DRAWABLE_XID(window), hdc);
00453    }
00454 
00455    switch (image->depth) {
00456    case 1:
00457    case 8:
00458       image->bpp = 1;
00459       break;
00460    case 15:
00461    case 16:
00462       image->bpp = 2;
00463       break;
00464    case 24:
00465       image->bpp = 3;
00466       break;
00467    case 32:
00468       image->bpp = 4;
00469       break;
00470    default:
00471       g_warning("gdk_image_get: image->depth = %d", image->depth);
00472       g_assert_not_reached();
00473    }
00474    image->byte_order = GDK_LSB_FIRST;
00475    if (image->depth == 1)
00476       image->bpl = ((width - 1) / 32 + 1) * 4;
00477    else
00478       image->bpl = ((width * image->bpp - 1) / 4 + 1) * 4;
00479 
00480    GDK_NOTE(MISC, g_print("... = %#x mem = %#x, bpl = %d\n",
00481                           private->ximage, image->mem, image->bpl));
00482 
00483    return image;
00484 }
00485 
00486 guint32 gdk_image_get_pixel(GdkImage * image, gint x, gint y)
00487 {
00488    guint32 pixel;
00489 
00490    g_return_val_if_fail(image != NULL, 0);
00491 
00492    g_return_val_if_fail(x >= 0 && x < image->width
00493                         && y >= 0 && y < image->height, 0);
00494 
00495    if (image->depth == 1)
00496       pixel =
00497           (((char *) image->mem)[y * image->bpl +
00498                                  (x >> 3)] & (1 << (7 - (x & 0x7)))) != 0;
00499    else {
00500       guchar *pixelp =
00501           (guchar *) image->mem + y * image->bpl + x * image->bpp;
00502 
00503       switch (image->bpp) {
00504       case 1:
00505          pixel = *pixelp;
00506          break;
00507 
00508          /* Windows is always LSB, no need to check image->byte_order. */
00509       case 2:
00510          pixel = pixelp[0] | (pixelp[1] << 8);
00511          break;
00512 
00513       case 3:
00514          pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
00515          break;
00516 
00517       case 4:
00518          pixel = pixelp[0] | (pixelp[1] << 8) | (pixelp[2] << 16);
00519          break;
00520       }
00521    }
00522 
00523    return pixel;
00524 }
00525 
00526 void gdk_image_put_pixel(GdkImage * image, gint x, gint y, guint32 pixel)
00527 {
00528    g_return_if_fail(image != NULL);
00529 
00530    g_return_if_fail(x >= 0 && x < image->width && y >= 0
00531                     && y < image->height);
00532 
00533    if (image->depth == 1)
00534       if (pixel & 1)
00535          ((guchar *) image->mem)[y * image->bpl + (x >> 3)] |=
00536              (1 << (7 - (x & 0x7)));
00537       else
00538          ((guchar *) image->mem)[y * image->bpl + (x >> 3)] &=
00539              ~(1 << (7 - (x & 0x7)));
00540    else {
00541       guchar *pixelp =
00542           (guchar *) image->mem + y * image->bpl + x * image->bpp;
00543 
00544       /* Windows is always LSB, no need to check image->byte_order. */
00545       switch (image->bpp) {
00546       case 4:
00547          pixelp[3] = 0;
00548       case 3:
00549          pixelp[2] = ((pixel >> 16) & 0xFF);
00550       case 2:
00551          pixelp[1] = ((pixel >> 8) & 0xFF);
00552       case 1:
00553          pixelp[0] = (pixel & 0xFF);
00554       }
00555    }
00556 }
00557 
00558 static void gdk_win32_image_destroy(GdkImage * image)
00559 {
00560    GdkImagePrivateWin32 *private;
00561 
00562    g_return_if_fail(image != NULL);
00563 
00564    private = (GdkImagePrivateWin32 *) image;
00565 
00566    GDK_NOTE(MISC, g_print("gdk_win32_image_destroy: %#x%s\n",
00567                           private->ximage,
00568                           (image->type == GDK_IMAGE_SHARED_PIXMAP ?
00569                            " (shared pixmap)" : "")));
00570 
00571    switch (image->type) {
00572    case GDK_IMAGE_SHARED_PIXMAP:
00573       break;                    /* The Windows bitmap has already been
00574                                  * (or will be) deleted when freeing
00575                                  * the corresponding pixmap.
00576                                  */
00577 
00578    case GDK_IMAGE_SHARED:
00579       if (!DeleteObject(private->ximage))
00580          WIN32_GDI_FAILED("DeleteObject");
00581       break;
00582 
00583    default:
00584       g_assert_not_reached();
00585    }
00586 
00587    g_free(image);
00588 }
00589 
00590 static void
00591 gdk_image_put(GdkImage * image,
00592               GdkDrawable * drawable,
00593               GdkGC * gc,
00594               gint xsrc,
00595               gint ysrc, gint xdest, gint ydest, gint width, gint height)
00596 {
00597    GdkDrawablePrivate *drawable_private;
00598    GdkImagePrivateWin32 *image_private;
00599    GdkGCPrivate *gc_private;
00600    HDC hdc;
00601    GdkColormapPrivateWin32 *colormap_private;
00602 
00603    g_return_if_fail(drawable != NULL);
00604    g_return_if_fail(image != NULL);
00605    g_return_if_fail(gc != NULL);
00606 
00607    if (GDK_DRAWABLE_DESTROYED(drawable))
00608       return;
00609    image_private = (GdkImagePrivateWin32 *) image;
00610    drawable_private = (GdkDrawablePrivate *) drawable;
00611    gc_private = (GdkGCPrivate *) gc;
00612 
00613    hdc = gdk_gc_predraw(drawable, gc_private, 0);
00614    colormap_private =
00615        (GdkColormapPrivateWin32 *) drawable_private->colormap;
00616    if (colormap_private && colormap_private->xcolormap->rc_palette) {
00617       DIBSECTION ds;
00618       static struct {
00619          BITMAPINFOHEADER bmiHeader;
00620          WORD bmiIndices[256];
00621       } bmi;
00622       static gboolean bmi_inited = FALSE;
00623       int i;
00624 
00625       if (!bmi_inited) {
00626          for (i = 0; i < 256; i++)
00627             bmi.bmiIndices[i] = i;
00628          bmi_inited = TRUE;
00629       }
00630 
00631       if (GetObject(image_private->ximage, sizeof(DIBSECTION),
00632                     &ds) != sizeof(DIBSECTION)) {
00633          WIN32_GDI_FAILED("GetObject");
00634       }
00635 #if 0
00636       g_print
00637           ("xdest = %d, ydest = %d, xsrc = %d, ysrc = %d, width = %d, height = %d\n",
00638            xdest, ydest, xsrc, ysrc, width, height);
00639       g_print
00640           ("bmWidth = %d, bmHeight = %d, bmBitsPixel = %d, bmBits = %p\n",
00641            ds.dsBm.bmWidth, ds.dsBm.bmHeight, ds.dsBm.bmBitsPixel,
00642            ds.dsBm.bmBits);
00643       g_print
00644           ("biWidth = %d, biHeight = %d, biBitCount = %d, biClrUsed = %d\n",
00645            ds.dsBmih.biWidth, ds.dsBmih.biHeight, ds.dsBmih.biBitCount,
00646            ds.dsBmih.biClrUsed);
00647 #endif
00648       bmi.bmiHeader = ds.dsBmih;
00649       /* I have spent hours on getting the parameters to
00650        * SetDIBitsToDevice right. I wonder what drugs the guys in
00651        * Redmond were on when they designed this API.
00652        */
00653       if (SetDIBitsToDevice(hdc,
00654                             xdest, ydest,
00655                             width, height,
00656                             xsrc, (-ds.dsBmih.biHeight) - height - ysrc,
00657                             0, -ds.dsBmih.biHeight,
00658                             ds.dsBm.bmBits,
00659                             (CONST BITMAPINFO *) & bmi,
00660                             DIB_PAL_COLORS) == 0)
00661          WIN32_GDI_FAILED("SetDIBitsToDevice");
00662    } else {
00663       HDC memdc;
00664       HGDIOBJ oldbitmap;
00665 
00666       if ((memdc = CreateCompatibleDC(hdc)) == NULL) {
00667          WIN32_GDI_FAILED("CreateCompatibleDC");
00668          gdk_gc_postdraw(drawable, gc_private, 0);
00669          return;
00670       }
00671 
00672       if ((oldbitmap = SelectObject(memdc, image_private->ximage)) == NULL) {
00673          WIN32_GDI_FAILED("SelectObject");
00674          gdk_gc_postdraw(drawable, gc_private, 0);
00675          return;
00676       }
00677       if (!BitBlt(hdc, xdest, ydest, width, height,
00678                   memdc, xsrc, ysrc, SRCCOPY))
00679          WIN32_GDI_FAILED("BitBlt");
00680 
00681       if (SelectObject(memdc, oldbitmap) == NULL)
00682          WIN32_GDI_FAILED("SelectObject");
00683 
00684       if (!DeleteDC(memdc))
00685          WIN32_GDI_FAILED("DeleteDC");
00686    }
00687    gdk_gc_postdraw(drawable, gc_private, 0);
00688 }

Generated on Tue Jul 5 14:14:40 2011 for ROOT_528-00b_version by  doxygen 1.5.1