2 * X11DRV bitmap objects
4 * Copyright 1993 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(x11drv
);
33 /* GCs used for B&W and color bitmap operations */
34 static GC bitmap_gc
[32];
35 X_PHYSBITMAP BITMAP_stock_phys_bitmap
= { 0 }; /* phys bitmap for the default stock bitmap */
37 static XContext bitmap_context
; /* X context to associate a phys bitmap to a handle */
39 GC
get_bitmap_gc(int depth
)
41 if(depth
< 1 || depth
> 32)
44 return bitmap_gc
[depth
-1];
47 /***********************************************************************
50 void X11DRV_BITMAP_Init(void)
52 int depth_count
, index
, i
;
57 bitmap_context
= XUniqueContext();
58 BITMAP_stock_phys_bitmap
.depth
= 1;
59 BITMAP_stock_phys_bitmap
.pixmap
= XCreatePixmap( gdi_display
, root_window
, 1, 1, 1 );
60 bitmap_gc
[0] = XCreateGC( gdi_display
, BITMAP_stock_phys_bitmap
.pixmap
, 0, NULL
);
61 XSetGraphicsExposures( gdi_display
, bitmap_gc
[0], False
);
62 XSetSubwindowMode( gdi_display
, bitmap_gc
[0], IncludeInferiors
);
64 /* Create a GC for all available depths. GCs at depths other than 1-bit/screen_depth are for use
65 * in combination with XRender which allows us to create dibsections at more depths.
67 depth_list
= XListDepths(gdi_display
, DefaultScreen(gdi_display
), &depth_count
);
68 for (i
= 0; i
< depth_count
; i
++)
70 index
= depth_list
[i
] - 1;
71 if (bitmap_gc
[index
]) continue;
72 if ((tmpPixmap
= XCreatePixmap( gdi_display
, root_window
, 1, 1, depth_list
[i
])))
74 if ((bitmap_gc
[index
] = XCreateGC( gdi_display
, tmpPixmap
, 0, NULL
)))
76 XSetGraphicsExposures( gdi_display
, bitmap_gc
[index
], False
);
77 XSetSubwindowMode( gdi_display
, bitmap_gc
[index
], IncludeInferiors
);
79 XFreePixmap( gdi_display
, tmpPixmap
);
87 /***********************************************************************
88 * SelectBitmap (X11DRV.@)
90 HBITMAP
X11DRV_SelectBitmap( PHYSDEV dev
, HBITMAP hbitmap
)
92 X11DRV_PDEVICE
*physDev
= get_x11drv_dev( dev
);
93 X_PHYSBITMAP
*physBitmap
;
96 if (!GetObjectW( hbitmap
, sizeof(bitmap
), &bitmap
)) return 0;
98 if (hbitmap
== BITMAP_stock_phys_bitmap
.hbitmap
) physBitmap
= &BITMAP_stock_phys_bitmap
;
99 else if (!(physBitmap
= X11DRV_get_phys_bitmap( hbitmap
))) return 0;
101 physDev
->bitmap
= physBitmap
;
102 physDev
->drawable
= physBitmap
->pixmap
;
103 physDev
->color_shifts
= physBitmap
->trueColor
? &physBitmap
->color_shifts
: NULL
;
104 SetRect( &physDev
->drawable_rect
, 0, 0, bitmap
.bmWidth
, bitmap
.bmHeight
);
105 physDev
->dc_rect
= physDev
->drawable_rect
;
107 /* Change GC depth if needed */
109 if (physDev
->depth
!= physBitmap
->depth
)
111 physDev
->depth
= physBitmap
->depth
;
113 XFreeGC( gdi_display
, physDev
->gc
);
114 physDev
->gc
= XCreateGC( gdi_display
, physDev
->drawable
, 0, NULL
);
115 XSetGraphicsExposures( gdi_display
, physDev
->gc
, False
);
116 XSetSubwindowMode( gdi_display
, physDev
->gc
, IncludeInferiors
);
117 XFlush( gdi_display
);
125 /***********************************************************************
126 * X11DRV_create_phys_bitmap
128 BOOL
X11DRV_create_phys_bitmap( HBITMAP hbitmap
, const BITMAP
*bitmap
, int depth
,
129 int true_color
, const ColorShifts
*shifts
)
131 X_PHYSBITMAP
*physBitmap
;
133 if (!(physBitmap
= X11DRV_init_phys_bitmap( hbitmap
))) return FALSE
;
135 physBitmap
->depth
= depth
;
136 physBitmap
->trueColor
= true_color
;
137 if (true_color
) physBitmap
->color_shifts
= *shifts
;
140 physBitmap
->pixmap
= XCreatePixmap( gdi_display
, root_window
,
141 bitmap
->bmWidth
, bitmap
->bmHeight
, physBitmap
->depth
);
142 if (physBitmap
->pixmap
)
144 GC gc
= get_bitmap_gc( depth
);
145 XSetFunction( gdi_display
, gc
, GXclear
);
146 XFillRectangle( gdi_display
, physBitmap
->pixmap
, gc
, 0, 0, bitmap
->bmWidth
, bitmap
->bmHeight
);
147 XSetFunction( gdi_display
, gc
, GXcopy
);
150 if (!physBitmap
->pixmap
)
152 WARN("Can't create Pixmap\n");
153 HeapFree( GetProcessHeap(), 0, physBitmap
);
160 /****************************************************************************
161 * CreateBitmap (X11DRV.@)
163 * Create a device dependent X11 bitmap
165 * Returns TRUE on success else FALSE
167 BOOL
X11DRV_CreateBitmap( PHYSDEV dev
, HBITMAP hbitmap
)
171 if (!GetObjectW( hbitmap
, sizeof(bitmap
), &bitmap
)) return FALSE
;
173 /* Check parameters */
174 if (bitmap
.bmPlanes
!= 1) return FALSE
;
176 /* check if bpp is compatible with screen depth */
177 if (!((bitmap
.bmBitsPixel
== 1) || (bitmap
.bmBitsPixel
== screen_bpp
)))
179 WARN("Trying to make bitmap with planes=%d, bpp=%d\n",
180 bitmap
.bmPlanes
, bitmap
.bmBitsPixel
);
184 TRACE("(%p) %dx%d %d bpp\n", hbitmap
, bitmap
.bmWidth
, bitmap
.bmHeight
, bitmap
.bmBitsPixel
);
186 if (bitmap
.bmBitsPixel
== 1)
188 if (hbitmap
== BITMAP_stock_phys_bitmap
.hbitmap
)
190 ERR( "called for stock bitmap, please report\n" );
193 return X11DRV_create_phys_bitmap( hbitmap
, &bitmap
, 1, FALSE
, NULL
);
196 return X11DRV_create_phys_bitmap( hbitmap
, &bitmap
, screen_depth
,
197 (visual
->class == TrueColor
|| visual
->class == DirectColor
),
198 &X11DRV_PALETTE_default_shifts
);
202 /***********************************************************************
203 * DeleteBitmap (X11DRV.@)
205 BOOL
X11DRV_DeleteBitmap( HBITMAP hbitmap
)
207 X_PHYSBITMAP
*physBitmap
= X11DRV_get_phys_bitmap( hbitmap
);
213 if (GetObjectW( hbitmap
, sizeof(dib
), &dib
) == sizeof(dib
))
214 X11DRV_DIB_DeleteDIBSection( physBitmap
, &dib
);
216 if (physBitmap
->glxpixmap
)
217 destroy_glxpixmap( gdi_display
, physBitmap
->glxpixmap
);
219 if (physBitmap
->pixmap
) XFreePixmap( gdi_display
, physBitmap
->pixmap
);
220 XDeleteContext( gdi_display
, (XID
)hbitmap
, bitmap_context
);
222 HeapFree( GetProcessHeap(), 0, physBitmap
);
228 /***********************************************************************
229 * X11DRV_get_phys_bitmap
231 * Retrieve the X physical bitmap info.
233 X_PHYSBITMAP
*X11DRV_get_phys_bitmap( HBITMAP hbitmap
)
238 if (XFindContext( gdi_display
, (XID
)hbitmap
, bitmap_context
, (char **)&ret
)) ret
= NULL
;
244 /***********************************************************************
245 * X11DRV_init_phys_bitmap
247 * Initialize the X physical bitmap info.
249 X_PHYSBITMAP
*X11DRV_init_phys_bitmap( HBITMAP hbitmap
)
253 if ((ret
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ret
) )) != NULL
)
255 ret
->hbitmap
= hbitmap
;
257 XSaveContext( gdi_display
, (XID
)hbitmap
, bitmap_context
, (char *)ret
);
264 /***********************************************************************
267 * Retrieve the pixmap associated to a bitmap.
269 Pixmap
X11DRV_get_pixmap( HBITMAP hbitmap
)
271 X_PHYSBITMAP
*physBitmap
= X11DRV_get_phys_bitmap( hbitmap
);
273 if (!physBitmap
) return 0;
274 return physBitmap
->pixmap
;