win32_x11.c revision b3dfa806
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
267/*
268Permission to use, copy, modify, distribute, and sell this software and its
269documentation for any purpose is hereby granted without fee, provided that
270the above copyright notice appear in all copies and that both that
271copyright notice and this permission notice appear in supporting
272documentation, and that the name of M.I.T. not be used in advertising or
273publicity pertaining to distribution of the software without specific,
274written prior permission.  M.I.T. makes no representations about the
275suitability of this software for any purpose.  It is provided "as is"
276without express or implied warranty.
277*/
278
279/*
280 *    XParseGeometry parses strings of the form
281 *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
282 *   width, height, xoffset, and yoffset are unsigned integers.
283 *   Example:  "=80x24+300-49"
284 *   The equal sign is optional.
285 *   It returns a bitmask that indicates which of the four values
286 *   were actually found in the string.  For each value found,
287 *   the corresponding argument is updated;  for each value
288 *   not found, the corresponding argument is left unchanged.
289 */
290
291static int
292ReadInteger(char *string, char **NextString)
293{
294    register int Result = 0;
295    int Sign = 1;
296
297    if (*string == '+')
298	string++;
299    else if (*string == '-')
300    {
301	string++;
302	Sign = -1;
303    }
304    for (; (*string >= '0') && (*string <= '9'); string++)
305    {
306	Result = (Result * 10) + (*string - '0');
307    }
308    *NextString = string;
309    if (Sign >= 0)
310	return (Result);
311    else
312	return (-Result);
313}
314
315int XParseGeometry(char *string, int *x, int *y, unsigned int *width, unsigned int *height)
316{
317	int mask = NoValue;
318	register char *strind;
319	unsigned int tempWidth, tempHeight;
320	int tempX, tempY;
321	char *nextCharacter;
322
323	if ( (string == NULL) || (*string == '\0')) return(mask);
324	if (*string == '=')
325		string++;  /* ignore possible '=' at beg of geometry spec */
326
327	strind = (char *)string;
328	if (*strind != '+' && *strind != '-' && *strind != 'x') {
329		tempWidth = ReadInteger(strind, &nextCharacter);
330		if (strind == nextCharacter)
331		    return (0);
332		strind = nextCharacter;
333		mask |= WidthValue;
334	}
335
336	if (*strind == 'x' || *strind == 'X') {
337		strind++;
338		tempHeight = ReadInteger(strind, &nextCharacter);
339		if (strind == nextCharacter)
340		    return (0);
341		strind = nextCharacter;
342		mask |= HeightValue;
343	}
344
345	if ((*strind == '+') || (*strind == '-')) {
346		if (*strind == '-') {
347  			strind++;
348			tempX = -ReadInteger(strind, &nextCharacter);
349			if (strind == nextCharacter)
350			    return (0);
351			strind = nextCharacter;
352			mask |= XNegative;
353
354		}
355		else
356		{	strind++;
357			tempX = ReadInteger(strind, &nextCharacter);
358			if (strind == nextCharacter)
359			    return(0);
360			strind = nextCharacter;
361		}
362		mask |= XValue;
363		if ((*strind == '+') || (*strind == '-')) {
364			if (*strind == '-') {
365				strind++;
366				tempY = -ReadInteger(strind, &nextCharacter);
367				if (strind == nextCharacter)
368			    	    return(0);
369				strind = nextCharacter;
370				mask |= YNegative;
371
372			}
373			else
374			{
375				strind++;
376				tempY = ReadInteger(strind, &nextCharacter);
377				if (strind == nextCharacter)
378			    	    return(0);
379				strind = nextCharacter;
380			}
381			mask |= YValue;
382		}
383	}
384
385	/* If strind isn't at the end of the string the it's an invalid
386		geometry specification. */
387
388	if (*strind != '\0') return (0);
389
390	if (mask & XValue)
391	    *x = tempX;
392 	if (mask & YValue)
393	    *y = tempY;
394	if (mask & WidthValue)
395            *width = tempWidth;
396	if (mask & HeightValue)
397            *height = tempHeight;
398	return (mask);
399}
400