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