252 lines
5.8 KiB
C
252 lines
5.8 KiB
C
/*
|
||
* tkWinPixmap.c --
|
||
*
|
||
* This file contains the Xlib emulation functions pertaining to creating
|
||
* and destroying pixmaps.
|
||
*
|
||
* Copyright (c) 1995 Sun Microsystems, Inc.
|
||
*
|
||
* See the file "license.terms" for information on usage and redistribution of
|
||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||
*/
|
||
|
||
#include "tkWinInt.h"
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tk_GetPixmap --
|
||
*
|
||
* Creates an in memory drawing surface.
|
||
*
|
||
* Results:
|
||
* Returns a handle to a new pixmap.
|
||
*
|
||
* Side effects:
|
||
* Allocates a new Win32 bitmap.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
Pixmap
|
||
Tk_GetPixmap(
|
||
Display *display,
|
||
Drawable d,
|
||
int width,
|
||
int height,
|
||
int depth)
|
||
{
|
||
TkWinDrawable *newTwdPtr, *twdPtr;
|
||
int planes;
|
||
Screen *screen;
|
||
|
||
display->request++;
|
||
|
||
newTwdPtr = (TkWinDrawable*) ckalloc(sizeof(TkWinDrawable));
|
||
newTwdPtr->type = TWD_BITMAP;
|
||
newTwdPtr->bitmap.depth = depth;
|
||
twdPtr = (TkWinDrawable *) d;
|
||
if (twdPtr->type != TWD_BITMAP) {
|
||
if (twdPtr->window.winPtr == NULL) {
|
||
newTwdPtr->bitmap.colormap = DefaultColormap(display,
|
||
DefaultScreen(display));
|
||
} else {
|
||
newTwdPtr->bitmap.colormap = twdPtr->window.winPtr->atts.colormap;
|
||
}
|
||
} else {
|
||
newTwdPtr->bitmap.colormap = twdPtr->bitmap.colormap;
|
||
}
|
||
screen = &display->screens[0];
|
||
planes = 1;
|
||
if (depth == screen->root_depth) {
|
||
planes = PTR2INT(screen->ext_data);
|
||
depth /= planes;
|
||
}
|
||
newTwdPtr->bitmap.handle =
|
||
CreateBitmap(width, height, (DWORD) planes, (DWORD) depth, NULL);
|
||
|
||
/*
|
||
* CreateBitmap tries to use memory on the graphics card. If it fails,
|
||
* call CreateDIBSection which uses real memory; slower, but at least
|
||
* still works. [Bug 2080533]
|
||
*/
|
||
|
||
if (newTwdPtr->bitmap.handle == NULL) {
|
||
static int repeatError = 0;
|
||
void *bits = NULL;
|
||
BITMAPINFO bitmapInfo;
|
||
HDC dc;
|
||
|
||
memset(&bitmapInfo, 0, sizeof(bitmapInfo));
|
||
bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader);
|
||
bitmapInfo.bmiHeader.biWidth = width;
|
||
bitmapInfo.bmiHeader.biHeight = height;
|
||
bitmapInfo.bmiHeader.biPlanes = planes;
|
||
bitmapInfo.bmiHeader.biBitCount = depth;
|
||
bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
||
bitmapInfo.bmiHeader.biSizeImage = 0;
|
||
dc = GetDC(NULL);
|
||
newTwdPtr->bitmap.handle = CreateDIBSection(dc, &bitmapInfo,
|
||
DIB_RGB_COLORS, &bits, 0, 0);
|
||
ReleaseDC(NULL, dc);
|
||
|
||
/*
|
||
* Oh no! Things are still going wrong. Pop up a warning message here
|
||
* (because things will probably crash soon) which will encourage
|
||
* people to report this as a bug...
|
||
*/
|
||
|
||
if (newTwdPtr->bitmap.handle == NULL && !repeatError) {
|
||
LPVOID lpMsgBuf;
|
||
|
||
repeatError = 1;
|
||
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||
NULL, GetLastError(),
|
||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||
(LPTSTR) &lpMsgBuf, 0, NULL)) {
|
||
MessageBox(NULL, (LPCTSTR) lpMsgBuf,
|
||
"Tk_GetPixmap: Error from CreateDIBSection",
|
||
MB_OK | MB_ICONINFORMATION);
|
||
LocalFree(lpMsgBuf);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (newTwdPtr->bitmap.handle == NULL) {
|
||
ckfree((char *) newTwdPtr);
|
||
return None;
|
||
}
|
||
|
||
return (Pixmap) newTwdPtr;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tk_FreePixmap --
|
||
*
|
||
* Release the resources associated with a pixmap.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Deletes the bitmap created by Tk_GetPixmap.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
Tk_FreePixmap(
|
||
Display *display,
|
||
Pixmap pixmap)
|
||
{
|
||
TkWinDrawable *twdPtr = (TkWinDrawable *) pixmap;
|
||
|
||
display->request++;
|
||
if (twdPtr != NULL) {
|
||
DeleteObject(twdPtr->bitmap.handle);
|
||
ckfree((char *) twdPtr);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkSetPixmapColormap --
|
||
*
|
||
* The following function is a hack used by the photo widget to
|
||
* explicitly set the colormap slot of a Pixmap.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TkSetPixmapColormap(
|
||
Pixmap pixmap,
|
||
Colormap colormap)
|
||
{
|
||
TkWinDrawable *twdPtr = (TkWinDrawable *)pixmap;
|
||
twdPtr->bitmap.colormap = colormap;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XGetGeometry --
|
||
*
|
||
* Retrieve the geometry of the given drawable. Note that this is a
|
||
* degenerate implementation that only returns the size of a pixmap or
|
||
* window.
|
||
*
|
||
* Results:
|
||
* Returns 0.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
int
|
||
XGetGeometry(
|
||
Display *display,
|
||
Drawable d,
|
||
Window *root_return,
|
||
int *x_return,
|
||
int *y_return,
|
||
unsigned int *width_return,
|
||
unsigned int *height_return,
|
||
unsigned int *border_width_return,
|
||
unsigned int *depth_return)
|
||
{
|
||
TkWinDrawable *twdPtr = (TkWinDrawable *)d;
|
||
|
||
if (twdPtr->type == TWD_BITMAP) {
|
||
HDC dc;
|
||
BITMAPINFO info;
|
||
|
||
if (twdPtr->bitmap.handle == NULL) {
|
||
Tcl_Panic("XGetGeometry: invalid pixmap");
|
||
}
|
||
dc = GetDC(NULL);
|
||
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
info.bmiHeader.biBitCount = 0;
|
||
if (!GetDIBits(dc, twdPtr->bitmap.handle, 0, 0, NULL, &info,
|
||
DIB_RGB_COLORS)) {
|
||
Tcl_Panic("XGetGeometry: unable to get bitmap size");
|
||
}
|
||
ReleaseDC(NULL, dc);
|
||
|
||
*width_return = info.bmiHeader.biWidth;
|
||
*height_return = info.bmiHeader.biHeight;
|
||
} else if (twdPtr->type == TWD_WINDOW) {
|
||
RECT rect;
|
||
|
||
if (twdPtr->window.handle == NULL) {
|
||
Tcl_Panic("XGetGeometry: invalid window");
|
||
}
|
||
GetClientRect(twdPtr->window.handle, &rect);
|
||
*width_return = rect.right - rect.left;
|
||
*height_return = rect.bottom - rect.top;
|
||
} else {
|
||
Tcl_Panic("XGetGeometry: invalid window");
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
/*
|
||
* Local Variables:
|
||
* mode: c
|
||
* c-basic-offset: 4
|
||
* fill-column: 78
|
||
* End:
|
||
*/
|