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 X_PHYSBITMAP
*X11DRV_create_phys_bitmap( HBITMAP hbitmap
, const BITMAP
*bitmap
, int depth
)
130 X_PHYSBITMAP
*physBitmap
;
132 if (bitmap
->bmWidth
> 65535 || bitmap
->bmHeight
> 65535 || bitmap
->bmPlanes
!= 1 ||
133 (bitmap
->bmBitsPixel
!= 1 && bitmap
->bmBitsPixel
!= screen_bpp
))
135 WARN( "Trying to create invalid pixmap %dx%d planes %d bpp %d\n",
136 bitmap
->bmWidth
, bitmap
->bmHeight
, bitmap
->bmPlanes
, bitmap
->bmBitsPixel
);
140 if (!(physBitmap
= X11DRV_init_phys_bitmap( hbitmap
))) return NULL
;
142 physBitmap
->depth
= depth
;
145 physBitmap
->pixmap
= XCreatePixmap( gdi_display
, root_window
,
146 bitmap
->bmWidth
, bitmap
->bmHeight
, physBitmap
->depth
);
147 if (physBitmap
->pixmap
)
149 GC gc
= get_bitmap_gc( depth
);
150 XSetFunction( gdi_display
, gc
, GXclear
);
151 XFillRectangle( gdi_display
, physBitmap
->pixmap
, gc
, 0, 0, bitmap
->bmWidth
, bitmap
->bmHeight
);
152 XSetFunction( gdi_display
, gc
, GXcopy
);
155 if (!physBitmap
->pixmap
)
157 WARN("Can't create Pixmap\n");
158 HeapFree( GetProcessHeap(), 0, physBitmap
);
161 TRACE( "(%p) %dx%d %d bpp -> %lx\n",
162 hbitmap
, bitmap
->bmWidth
, bitmap
->bmHeight
, bitmap
->bmBitsPixel
, physBitmap
->pixmap
);
167 /****************************************************************************
168 * CreateBitmap (X11DRV.@)
170 * Create a device dependent X11 bitmap
172 * Returns TRUE on success else FALSE
174 BOOL
X11DRV_CreateBitmap( PHYSDEV dev
, HBITMAP hbitmap
)
177 X_PHYSBITMAP
*phys_bitmap
;
179 if (!GetObjectW( hbitmap
, sizeof(bitmap
), &bitmap
)) return FALSE
;
181 if (bitmap
.bmBitsPixel
== 1)
183 if (!(phys_bitmap
= X11DRV_create_phys_bitmap( hbitmap
, &bitmap
, 1 ))) return FALSE
;
184 phys_bitmap
->trueColor
= FALSE
;
188 if (!(phys_bitmap
= X11DRV_create_phys_bitmap( hbitmap
, &bitmap
, screen_depth
))) return FALSE
;
189 phys_bitmap
->trueColor
= (visual
->class == TrueColor
|| visual
->class == DirectColor
);
190 phys_bitmap
->color_shifts
= X11DRV_PALETTE_default_shifts
;
196 /****************************************************************************
197 * CopyBitmap (X11DRV.@)
199 BOOL
X11DRV_CopyBitmap( HBITMAP src
, HBITMAP dst
)
201 X_PHYSBITMAP
*phys_src
, *phys_dst
;
204 if (!(phys_src
= X11DRV_get_phys_bitmap( src
))) return FALSE
;
205 if (!GetObjectW( dst
, sizeof(bitmap
), &bitmap
)) return FALSE
;
207 TRACE("%p->%p %dx%d %d bpp\n", src
, dst
, bitmap
.bmWidth
, bitmap
.bmHeight
, bitmap
.bmBitsPixel
);
209 if (!(phys_dst
= X11DRV_init_phys_bitmap( dst
))) return FALSE
;
211 phys_dst
->depth
= phys_src
->depth
;
212 phys_dst
->format
= phys_src
->format
;
213 phys_dst
->trueColor
= phys_src
->trueColor
;
214 if (phys_dst
->trueColor
) phys_dst
->color_shifts
= phys_src
->color_shifts
;
217 phys_dst
->pixmap
= XCreatePixmap( gdi_display
, root_window
,
218 bitmap
.bmWidth
, bitmap
.bmHeight
, phys_dst
->depth
);
219 XCopyArea( gdi_display
, phys_src
->pixmap
, phys_dst
->pixmap
,
220 get_bitmap_gc(phys_dst
->depth
), 0, 0, bitmap
.bmWidth
, bitmap
.bmHeight
, 0, 0 );
223 if (!phys_dst
->pixmap
)
225 WARN("Can't create Pixmap\n");
226 HeapFree( GetProcessHeap(), 0, phys_dst
);
233 /***********************************************************************
234 * DeleteBitmap (X11DRV.@)
236 BOOL
X11DRV_DeleteBitmap( HBITMAP hbitmap
)
238 X_PHYSBITMAP
*physBitmap
= X11DRV_get_phys_bitmap( hbitmap
);
243 if (physBitmap
->pixmap
) XFreePixmap( gdi_display
, physBitmap
->pixmap
);
244 XDeleteContext( gdi_display
, (XID
)hbitmap
, bitmap_context
);
246 HeapFree( GetProcessHeap(), 0, physBitmap
);
252 /***********************************************************************
253 * X11DRV_get_phys_bitmap
255 * Retrieve the X physical bitmap info.
257 X_PHYSBITMAP
*X11DRV_get_phys_bitmap( HBITMAP hbitmap
)
262 if (XFindContext( gdi_display
, (XID
)hbitmap
, bitmap_context
, (char **)&ret
)) ret
= NULL
;
268 /***********************************************************************
269 * X11DRV_init_phys_bitmap
271 * Initialize the X physical bitmap info.
273 X_PHYSBITMAP
*X11DRV_init_phys_bitmap( HBITMAP hbitmap
)
277 if ((ret
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ret
) )) != NULL
)
279 ret
->hbitmap
= hbitmap
;
281 XSaveContext( gdi_display
, (XID
)hbitmap
, bitmap_context
, (char *)ret
);
288 /***********************************************************************
291 * Retrieve the pixmap associated to a bitmap.
293 Pixmap
X11DRV_get_pixmap( HBITMAP hbitmap
)
295 X_PHYSBITMAP
*physBitmap
= X11DRV_get_phys_bitmap( hbitmap
);
297 if (!physBitmap
) return 0;
298 return physBitmap
->pixmap
;