1c041511dScube 2c041511dScube/* Copyright (c) Nate Robins, 1997. */ 3c041511dScube/* portions Copyright (c) Mark Kilgard, 1998. */ 4c041511dScube 5c041511dScube/* This program is freely distributable without licensing fees 6c041511dScube and is provided without guarantee or warrantee expressed or 7c041511dScube implied. This program is -not- in the public domain. */ 8c041511dScube 9c041511dScube#include "glutint.h" 10c041511dScube 11c041511dScube/* global variable that must be set for some functions to operate 12c041511dScube correctly. */ 13c041511dScubeHDC XHDC; 14c041511dScube 15c041511dScubeXVisualInfo* 16c041511dScubeXGetVisualInfo(Display* display, long mask, XVisualInfo* template, int* nitems) 17c041511dScube{ 18c041511dScube /* KLUDGE: this function needs XHDC to be set to the HDC currently 19c041511dScube being operated on before it is invoked! */ 20c041511dScube 21c041511dScube PIXELFORMATDESCRIPTOR* pfds; 22c041511dScube int i, n; 23c041511dScube 24c041511dScube n = DescribePixelFormat(XHDC, 0, 0, NULL); 25c041511dScube pfds = (PIXELFORMATDESCRIPTOR*)malloc(sizeof(PIXELFORMATDESCRIPTOR) * n); 26c041511dScube memset(pfds, 0, sizeof(PIXELFORMATDESCRIPTOR) * n); 27c041511dScube 28c041511dScube for (i = 0; i < n; i++) { 29c041511dScube DescribePixelFormat(XHDC, i + 1, sizeof(PIXELFORMATDESCRIPTOR), &pfds[i]); 30c041511dScube } 31c041511dScube 32c041511dScube *nitems = n; 33c041511dScube return pfds; 34c041511dScube} 35c041511dScube 36c041511dScubeColormap 37c041511dScubeXCreateColormap(Display* display, Window root, Visual* visual, int alloc) 38c041511dScube{ 39c041511dScube /* KLUDGE: this function needs XHDC to be set to the HDC currently 40c041511dScube being operated on before it is invoked! */ 41c041511dScube 42c041511dScube PIXELFORMATDESCRIPTOR pfd; 43c041511dScube LOGPALETTE *logical; 44c041511dScube HPALETTE palette; 45c041511dScube int n; 46c041511dScube 47c041511dScube /* grab the pixel format */ 48c041511dScube memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 49c041511dScube DescribePixelFormat(XHDC, GetPixelFormat(XHDC), 50c041511dScube sizeof(PIXELFORMATDESCRIPTOR), &pfd); 51c041511dScube 52c041511dScube if (!(pfd.dwFlags & PFD_NEED_PALETTE || 53c041511dScube pfd.iPixelType == PFD_TYPE_COLORINDEX)) 54c041511dScube { 55c041511dScube return 0; 56c041511dScube } 57c041511dScube 58c041511dScube n = 1 << pfd.cColorBits; 59c041511dScube 60c041511dScube /* allocate a bunch of memory for the logical palette (assume 256 61c041511dScube colors in a Win32 palette */ 62c041511dScube logical = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) + 63c041511dScube sizeof(PALETTEENTRY) * n); 64c041511dScube memset(logical, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n); 65c041511dScube 66c041511dScube /* set the entries in the logical palette */ 67c041511dScube logical->palVersion = 0x300; 68c041511dScube logical->palNumEntries = n; 69c041511dScube 70c041511dScube /* start with a copy of the current system palette */ 71c041511dScube GetSystemPaletteEntries(XHDC, 0, 256, &logical->palPalEntry[0]); 72c041511dScube 73c041511dScube if (pfd.iPixelType == PFD_TYPE_RGBA) { 74c041511dScube int redMask = (1 << pfd.cRedBits) - 1; 75c041511dScube int greenMask = (1 << pfd.cGreenBits) - 1; 76c041511dScube int blueMask = (1 << pfd.cBlueBits) - 1; 77c041511dScube int i; 78c041511dScube 79c041511dScube /* fill in an RGBA color palette */ 80c041511dScube for (i = 0; i < n; ++i) { 81c041511dScube logical->palPalEntry[i].peRed = 82c041511dScube (((i >> pfd.cRedShift) & redMask) * 255) / redMask; 83c041511dScube logical->palPalEntry[i].peGreen = 84c041511dScube (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; 85c041511dScube logical->palPalEntry[i].peBlue = 86c041511dScube (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; 87c041511dScube logical->palPalEntry[i].peFlags = 0; 88c041511dScube } 89c041511dScube } 90c041511dScube 91c041511dScube palette = CreatePalette(logical); 92c041511dScube free(logical); 93c041511dScube 94c041511dScube SelectPalette(XHDC, palette, FALSE); 95c041511dScube RealizePalette(XHDC); 96c041511dScube 97c041511dScube return palette; 98c041511dScube} 99c041511dScube 100c041511dScubevoid 101c041511dScubeXAllocColorCells(Display* display, Colormap colormap, Bool contig, 102c041511dScube unsigned long plane_masks_return[], unsigned int nplanes, 103c041511dScube unsigned long pixels_return[], unsigned int npixels) 104c041511dScube{ 105c041511dScube /* NOP -- we did all the allocating in XCreateColormap! */ 106c041511dScube} 107c041511dScube 108c041511dScubevoid 109c041511dScubeXStoreColor(Display* display, Colormap colormap, XColor* color) 110c041511dScube{ 111c041511dScube /* KLUDGE: set XHDC to 0 if the palette should NOT be realized after 112c041511dScube setting the color. set XHDC to the correct HDC if it should. */ 113c041511dScube 114c041511dScube PALETTEENTRY pe; 115c041511dScube 116c041511dScube /* X11 stores color from 0-65535, Win32 expects them to be 0-256, so 117c041511dScube twiddle the bits ( / 256). */ 118c041511dScube pe.peRed = color->red / 256; 119c041511dScube pe.peGreen = color->green / 256; 120c041511dScube pe.peBlue = color->blue / 256; 121c041511dScube 122c041511dScube /* make sure we use this flag, otherwise the colors might get mapped 123c041511dScube to another place in the colormap, and when we glIndex() that 124c041511dScube color, it may have moved (argh!!) */ 125c041511dScube pe.peFlags = PC_NOCOLLAPSE; 126c041511dScube 127c041511dScube /* the pixel field of the XColor structure is the index into the 128c041511dScube colormap */ 129c041511dScube SetPaletteEntries(colormap, color->pixel, 1, &pe); 130c041511dScube 131c041511dScube if (XHDC) { 132c041511dScube UnrealizeObject(colormap); 133c041511dScube SelectPalette(XHDC, colormap, FALSE); 134c041511dScube RealizePalette(XHDC); 135c041511dScube } 136c041511dScube} 137c041511dScube 138c041511dScubevoid 139c041511dScubeXSetWindowColormap(Display* display, Window window, Colormap colormap) 140c041511dScube{ 141c041511dScube HDC hdc = GetDC(window); 142c041511dScube 143c041511dScube /* if the third parameter is FALSE, the logical colormap is copied 144c041511dScube into the device palette when the application is in the 145c041511dScube foreground, if it is TRUE, the colors are mapped into the current 146c041511dScube palette in the best possible way. */ 147c041511dScube SelectPalette(hdc, colormap, FALSE); 148c041511dScube RealizePalette(hdc); 149c041511dScube 150c041511dScube /* note that we don't have to release the DC, since our window class 151c041511dScube uses the WC_OWNDC flag! */ 152c041511dScube} 153c041511dScube 154c041511dScubeBool 155c041511dScubeXTranslateCoordinates(Display *display, Window src, Window dst, 156c041511dScube int src_x, int src_y, 157c041511dScube int* dest_x_return, int* dest_y_return, 158c041511dScube Window* child_return) 159c041511dScube{ 160c041511dScube /* KLUDGE: this isn't really a translate coordinates into some other 161c041511dScube windows coordinate system...it only translates coordinates into the 162c041511dScube root window (screen) coordinate system. */ 163c041511dScube 164c041511dScube POINT point; 165c041511dScube 166c041511dScube point.x = src_x; 167c041511dScube point.y = src_y; 168c041511dScube 169c041511dScube ClientToScreen(src, &point); 170c041511dScube 171c041511dScube *dest_x_return = point.x; 172c041511dScube *dest_y_return = point.y; 173c041511dScube 174c041511dScube /* just to make compilers happy...we don't use the return value. */ 175c041511dScube return True; 176c041511dScube} 177c041511dScube 178c041511dScubeStatus 179c041511dScubeXGetGeometry(Display* display, Window window, Window* root_return, 180c041511dScube int* x_return, int* y_return, 181c041511dScube unsigned int* width_return, unsigned int* height_return, 182c041511dScube unsigned int *border_width_return, unsigned int* depth_return) 183c041511dScube{ 184c041511dScube /* KLUDGE: doesn't return the border_width or depth or root, x & y 185c041511dScube are in screen coordinates. */ 186c041511dScube 187c041511dScube RECT rect; 188c041511dScube POINT point; 189c041511dScube 190c041511dScube GetClientRect(window, &rect); 191c041511dScube 192c041511dScube point.x = 0; 193c041511dScube point.y = 0; 194c041511dScube ClientToScreen(window, &point); 195c041511dScube 196c041511dScube *x_return = point.x; 197c041511dScube *y_return = point.y; 198c041511dScube *width_return = rect.right; 199c041511dScube *height_return = rect.bottom; 200c041511dScube 201c041511dScube /* just to make compilers happy...we don't use the return value. */ 202c041511dScube return 1; 203c041511dScube} 204c041511dScube 205c041511dScubeint 206c041511dScubeDisplayWidthMM(Display* display, int screen) 207c041511dScube{ 208c041511dScube int width; 209c041511dScube HWND hwnd = GetDesktopWindow(); 210c041511dScube HDC hdc = GetDC(hwnd); 211c041511dScube 212c041511dScube width = GetDeviceCaps(hdc, HORZSIZE); 213c041511dScube 214c041511dScube /* make sure to release this DC (it's the desktops, not ours) */ 215c041511dScube ReleaseDC(hwnd, hdc); 216c041511dScube 217c041511dScube return width; 218c041511dScube} 219c041511dScube 220c041511dScubeint 221c041511dScubeDisplayHeightMM(Display* display, int screen) 222c041511dScube{ 223c041511dScube int height; 224c041511dScube HWND hwnd = GetDesktopWindow(); 225c041511dScube HDC hdc = GetDC(hwnd); 226c041511dScube 227c041511dScube height = GetDeviceCaps(hdc, VERTSIZE); 228c041511dScube 229c041511dScube /* make sure to release this DC (it's the desktops, not ours) */ 230c041511dScube ReleaseDC(hwnd, hdc); 231c041511dScube 232c041511dScube return height; 233c041511dScube} 234c041511dScube 235c041511dScubevoid 236c041511dScubeXWarpPointer(Display* display, Window src, Window dst, 237c041511dScube int src_x, int src_y, int src_width, int src_height, 238c041511dScube int dst_x, int dst_y) 239c041511dScube{ 240c041511dScube /* KLUDGE: this isn't really a warp pointer into some other windows 241c041511dScube coordinate system...it only warps the pointer into the root window 242c041511dScube (screen) coordinate system. */ 243c041511dScube 244c041511dScube POINT point; 245c041511dScube 246c041511dScube point.x = dst_x; 247c041511dScube point.y = dst_y; 248c041511dScube ClientToScreen(dst, &point); 249c041511dScube 250c041511dScube SetCursorPos(point.x, point.y); 251c041511dScube} 252c041511dScube 253c041511dScubeint 254c041511dScubeXPending(Display* display) 255c041511dScube{ 256c041511dScube /* similar functionality...I don't think that it is exact, but this 257c041511dScube will have to do. */ 258c041511dScube MSG msg; 259c041511dScube 260c041511dScube return PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); 261c041511dScube} 262c041511dScube 263c041511dScube/* the following function was stolen from the X sources as indicated. */ 264c041511dScube 265c041511dScube/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */ 266c041511dScube 267c041511dScube/* 268c041511dScubePermission to use, copy, modify, distribute, and sell this software and its 269c041511dScubedocumentation for any purpose is hereby granted without fee, provided that 270c041511dScubethe above copyright notice appear in all copies and that both that 271c041511dScubecopyright notice and this permission notice appear in supporting 272c041511dScubedocumentation, and that the name of M.I.T. not be used in advertising or 273c041511dScubepublicity pertaining to distribution of the software without specific, 274c041511dScubewritten prior permission. M.I.T. makes no representations about the 275c041511dScubesuitability of this software for any purpose. It is provided "as is" 276c041511dScubewithout express or implied warranty. 277c041511dScube*/ 278c041511dScube 279c041511dScube/* 280c041511dScube * XParseGeometry parses strings of the form 281c041511dScube * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where 282c041511dScube * width, height, xoffset, and yoffset are unsigned integers. 283c041511dScube * Example: "=80x24+300-49" 284c041511dScube * The equal sign is optional. 285c041511dScube * It returns a bitmask that indicates which of the four values 286c041511dScube * were actually found in the string. For each value found, 287c041511dScube * the corresponding argument is updated; for each value 288c041511dScube * not found, the corresponding argument is left unchanged. 289c041511dScube */ 290c041511dScube 291c041511dScubestatic int 292c041511dScubeReadInteger(char *string, char **NextString) 293c041511dScube{ 294c041511dScube register int Result = 0; 295c041511dScube int Sign = 1; 296c041511dScube 297c041511dScube if (*string == '+') 298c041511dScube string++; 299c041511dScube else if (*string == '-') 300c041511dScube { 301c041511dScube string++; 302c041511dScube Sign = -1; 303c041511dScube } 304c041511dScube for (; (*string >= '0') && (*string <= '9'); string++) 305c041511dScube { 306c041511dScube Result = (Result * 10) + (*string - '0'); 307c041511dScube } 308c041511dScube *NextString = string; 309c041511dScube if (Sign >= 0) 310c041511dScube return (Result); 311c041511dScube else 312c041511dScube return (-Result); 313c041511dScube} 314c041511dScube 315c041511dScubeint XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height) 316c041511dScube{ 317c041511dScube int mask = NoValue; 318c041511dScube register char *strind; 319c041511dScube unsigned int tempWidth, tempHeight; 320c041511dScube int tempX, tempY; 321c041511dScube char *nextCharacter; 322c041511dScube 323c041511dScube if ( (string == NULL) || (*string == '\0')) return(mask); 324c041511dScube if (*string == '=') 325c041511dScube string++; /* ignore possible '=' at beg of geometry spec */ 326c041511dScube 327c041511dScube strind = (char *)string; 328c041511dScube if (*strind != '+' && *strind != '-' && *strind != 'x') { 329c041511dScube tempWidth = ReadInteger(strind, &nextCharacter); 330c041511dScube if (strind == nextCharacter) 331c041511dScube return (0); 332c041511dScube strind = nextCharacter; 333c041511dScube mask |= WidthValue; 334c041511dScube } 335c041511dScube 336c041511dScube if (*strind == 'x' || *strind == 'X') { 337c041511dScube strind++; 338c041511dScube tempHeight = ReadInteger(strind, &nextCharacter); 339c041511dScube if (strind == nextCharacter) 340c041511dScube return (0); 341c041511dScube strind = nextCharacter; 342c041511dScube mask |= HeightValue; 343c041511dScube } 344c041511dScube 345c041511dScube if ((*strind == '+') || (*strind == '-')) { 346c041511dScube if (*strind == '-') { 347c041511dScube strind++; 348c041511dScube tempX = -ReadInteger(strind, &nextCharacter); 349c041511dScube if (strind == nextCharacter) 350c041511dScube return (0); 351c041511dScube strind = nextCharacter; 352c041511dScube mask |= XNegative; 353c041511dScube 354c041511dScube } 355c041511dScube else 356c041511dScube { strind++; 357c041511dScube tempX = ReadInteger(strind, &nextCharacter); 358c041511dScube if (strind == nextCharacter) 359c041511dScube return(0); 360c041511dScube strind = nextCharacter; 361c041511dScube } 362c041511dScube mask |= XValue; 363c041511dScube if ((*strind == '+') || (*strind == '-')) { 364c041511dScube if (*strind == '-') { 365c041511dScube strind++; 366c041511dScube tempY = -ReadInteger(strind, &nextCharacter); 367c041511dScube if (strind == nextCharacter) 368c041511dScube return(0); 369c041511dScube strind = nextCharacter; 370c041511dScube mask |= YNegative; 371c041511dScube 372c041511dScube } 373c041511dScube else 374c041511dScube { 375c041511dScube strind++; 376c041511dScube tempY = ReadInteger(strind, &nextCharacter); 377c041511dScube if (strind == nextCharacter) 378c041511dScube return(0); 379c041511dScube strind = nextCharacter; 380c041511dScube } 381c041511dScube mask |= YValue; 382c041511dScube } 383c041511dScube } 384c041511dScube 385c041511dScube /* If strind isn't at the end of the string the it's an invalid 386c041511dScube geometry specification. */ 387c041511dScube 388c041511dScube if (*strind != '\0') return (0); 389c041511dScube 390c041511dScube if (mask & XValue) 391c041511dScube *x = tempX; 392c041511dScube if (mask & YValue) 393c041511dScube *y = tempY; 394c041511dScube if (mask & WidthValue) 395c041511dScube *width = tempWidth; 396c041511dScube if (mask & HeightValue) 397c041511dScube *height = tempHeight; 398c041511dScube return (mask); 399c041511dScube} 400