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