1/* 2 * tkWinPixmap.c -- 3 * 4 * This file contains the Xlib emulation functions pertaining to creating 5 * and destroying pixmaps. 6 * 7 * Copyright (c) 1995 Sun Microsystems, Inc. 8 * 9 * See the file "license.terms" for information on usage and redistribution of 10 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 * 12 * RCS: @(#) $Id$ 13 */ 14 15#include "tkWinInt.h" 16 17/* 18 *---------------------------------------------------------------------- 19 * 20 * Tk_GetPixmap -- 21 * 22 * Creates an in memory drawing surface. 23 * 24 * Results: 25 * Returns a handle to a new pixmap. 26 * 27 * Side effects: 28 * Allocates a new Win32 bitmap. 29 * 30 *---------------------------------------------------------------------- 31 */ 32 33Pixmap 34Tk_GetPixmap( 35 Display *display, 36 Drawable d, 37 int width, 38 int height, 39 int depth) 40{ 41 TkWinDrawable *newTwdPtr, *twdPtr; 42 int planes; 43 Screen *screen; 44 45 display->request++; 46 47 newTwdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable)); 48 newTwdPtr->type = TWD_BITMAP; 49 newTwdPtr->bitmap.depth = depth; 50 twdPtr = (TkWinDrawable *) d; 51 if (twdPtr->type != TWD_BITMAP) { 52 if (twdPtr->window.winPtr == NULL) { 53 newTwdPtr->bitmap.colormap = DefaultColormap(display, 54 DefaultScreen(display)); 55 } else { 56 newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap; 57 } 58 } else { 59 newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap; 60 } 61 screen = &display->screens[0]; 62 planes = 1; 63 if (depth == screen->root_depth) { 64 planes = (int) screen->ext_data; 65 depth /= planes; 66 } 67 newTwdPtr->bitmap.handle = 68 CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL); 69 70 /* 71 * CreateBitmap tries to use memory on the graphics card. If it fails, 72 * call CreateDIBSection which uses real memory; slower, but at least 73 * still works. [Bug 2080533] 74 */ 75 76 if (newTwdPtr->bitmap.handle == NULL) { 77 static int repeatError = 0; 78 void *bits = NULL; 79 BITMAPINFO bitmapInfo; 80 HDC dc; 81 82 memset(&bitmapInfo, 0, sizeof(bitmapInfo)); 83 bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader); 84 bitmapInfo.bmiHeader.biWidth = width; 85 bitmapInfo.bmiHeader.biHeight = height; 86 bitmapInfo.bmiHeader.biPlanes = planes; 87 bitmapInfo.bmiHeader.biBitCount = depth; 88 bitmapInfo.bmiHeader.biCompression = BI_RGB; 89 bitmapInfo.bmiHeader.biSizeImage = 0; 90 dc = GetDC(NULL); 91 newTwdPtr->bitmap.handle = CreateDIBSection(dc, &bitmapInfo, 92 DIB_RGB_COLORS, &bits, 0, 0); 93 ReleaseDC(NULL, dc); 94 95 /* 96 * Oh no! Things are still going wrong. Pop up a warning message here 97 * (because things will probably crash soon) which will encourage 98 * people to report this as a bug... 99 */ 100 101 if (newTwdPtr->bitmap.handle == NULL && !repeatError) { 102 LPVOID lpMsgBuf; 103 104 repeatError = 1; 105 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 106 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, 107 NULL, GetLastError(), 108 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 109 (LPTSTR) &lpMsgBuf, 0, NULL)) { 110 MessageBox(NULL, (LPCTSTR) lpMsgBuf, 111 "Tk_GetPixmap: Error from CreateDIBSection", 112 MB_OK | MB_ICONINFORMATION); 113 LocalFree(lpMsgBuf); 114 } 115 } 116 } 117 118 if (newTwdPtr->bitmap.handle == NULL) { 119 ckfree((char *) newTwdPtr); 120 return None; 121 } 122 123 return (Pixmap) newTwdPtr; 124} 125 126/* 127 *---------------------------------------------------------------------- 128 * 129 * Tk_FreePixmap -- 130 * 131 * Release the resources associated with a pixmap. 132 * 133 * Results: 134 * None. 135 * 136 * Side effects: 137 * Deletes the bitmap created by Tk_GetPixmap. 138 * 139 *---------------------------------------------------------------------- 140 */ 141 142void 143Tk_FreePixmap( 144 Display *display, 145 Pixmap pixmap) 146{ 147 TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap; 148 149 display->request++; 150 if (twdPtr != NULL) { 151 DeleteObject(twdPtr->bitmap.handle); 152 ckfree((char *) twdPtr); 153 } 154} 155 156/* 157 *---------------------------------------------------------------------- 158 * 159 * TkSetPixmapColormap -- 160 * 161 * The following function is a hack used by the photo widget to 162 * explicitly set the colormap slot of a Pixmap. 163 * 164 * Results: 165 * None. 166 * 167 * Side effects: 168 * None. 169 * 170 *---------------------------------------------------------------------- 171 */ 172 173void 174TkSetPixmapColormap( 175 Pixmap pixmap, 176 Colormap colormap) 177{ 178 TkWinDrawable *twdPtr = (TkWinDrawable *)pixmap; 179 twdPtr->bitmap.colormap = colormap; 180} 181 182/* 183 *---------------------------------------------------------------------- 184 * 185 * XGetGeometry -- 186 * 187 * Retrieve the geometry of the given drawable. Note that this is a 188 * degenerate implementation that only returns the size of a pixmap or 189 * window. 190 * 191 * Results: 192 * Returns 0. 193 * 194 * Side effects: 195 * None. 196 * 197 *---------------------------------------------------------------------- 198 */ 199 200int 201XGetGeometry( 202 Display *display, 203 Drawable d, 204 Window *root_return, 205 int *x_return, 206 int *y_return, 207 unsigned int *width_return, 208 unsigned int *height_return, 209 unsigned int *border_width_return, 210 unsigned int *depth_return) 211{ 212 TkWinDrawable *twdPtr = (TkWinDrawable *)d; 213 214 if (twdPtr->type == TWD_BITMAP) { 215 HDC dc; 216 BITMAPINFO info; 217 218 if (twdPtr->bitmap.handle == NULL) { 219 Tcl_Panic("XGetGeometry: invalid pixmap"); 220 } 221 dc = GetDC(NULL); 222 info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 223 info.bmiHeader.biBitCount = 0; 224 if (!GetDIBits(dc, twdPtr->bitmap.handle, 0, 0, NULL, &info, 225 DIB_RGB_COLORS)) { 226 Tcl_Panic("XGetGeometry: unable to get bitmap size"); 227 } 228 ReleaseDC(NULL, dc); 229 230 *width_return = info.bmiHeader.biWidth; 231 *height_return = info.bmiHeader.biHeight; 232 } else if (twdPtr->type == TWD_WINDOW) { 233 RECT rect; 234 235 if (twdPtr->window.handle == NULL) { 236 Tcl_Panic("XGetGeometry: invalid window"); 237 } 238 GetClientRect(twdPtr->window.handle, &rect); 239 *width_return = rect.right - rect.left; 240 *height_return = rect.bottom - rect.top; 241 } else { 242 Tcl_Panic("XGetGeometry: invalid window"); 243 } 244 return 1; 245} 246 247/* 248 * Local Variables: 249 * mode: c 250 * c-basic-offset: 4 251 * fill-column: 78 252 * End: 253 */ 254