wined3d: Add zero/near zero vertex rhw special case.
[wine] / dlls / gdi32 / env.c
1 /*
2  * Driver Environment functions
3  *
4  * Note: This has NOTHING to do with the task/process environment!
5  *
6  * Copyright 1997 Marcus Meissner
7  * Copyright 1998 Andreas Mohr
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include "config.h"
25
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "wine/wingdi16.h"
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
37
38 typedef struct {
39         ATOM atom;
40         HGLOBAL16 handle;
41 } ENVTABLE;
42
43 static ENVTABLE EnvTable[20];
44
45 static ENVTABLE *SearchEnvTable(ATOM atom)
46 {
47     INT16 i;
48
49     for (i = 19; i >= 0; i--) {
50       if (EnvTable[i].atom == atom)
51         return &EnvTable[i];
52     }
53     return NULL;
54 }
55
56 static ATOM GDI_GetNullPortAtom(void)
57 {
58     static ATOM NullPortAtom = 0;
59     if (!NullPortAtom)
60     {
61         char NullPort[256];
62
63         GetProfileStringA( "windows", "nullport", "none",
64                              NullPort, sizeof(NullPort) );
65         NullPortAtom = AddAtomA( NullPort );
66     }
67     return NullPortAtom;
68 }
69
70 static ATOM PortNameToAtom(LPCSTR lpPortName, BOOL16 add)
71 {
72     char buffer[256];
73
74     lstrcpynA( buffer, lpPortName, sizeof(buffer) );
75
76     if (buffer[0] && buffer[strlen(buffer)-1] == ':') buffer[strlen(buffer)-1] = 0;
77
78     if (add)
79         return AddAtomA(buffer);
80     else
81         return FindAtomA(buffer);
82 }
83
84
85 /***********************************************************************
86  *           GetEnvironment   (GDI.133)
87  */
88 INT16 WINAPI GetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nMaxSize)
89 {
90     ATOM atom;
91     LPCSTR p;
92     ENVTABLE *env;
93     WORD size;
94
95     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nMaxSize);
96
97     if (!(atom = PortNameToAtom(lpPortName, FALSE)))
98         return 0;
99     if (atom == GDI_GetNullPortAtom())
100         if (!(atom = FindAtomA((LPCSTR)lpdev)))
101             return 0;
102     if (!(env = SearchEnvTable(atom)))
103         return 0;
104     size = GlobalSize16(env->handle);
105     if (!lpdev) return 0;
106     if (size < nMaxSize) nMaxSize = size;
107     if (!(p = GlobalLock16(env->handle))) return 0;
108     memcpy(lpdev, p, nMaxSize);
109     GlobalUnlock16(env->handle);
110     return nMaxSize;
111 }
112
113
114 /***********************************************************************
115  *          SetEnvironment   (GDI.132)
116  */
117 INT16 WINAPI SetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nCount)
118 {
119     ATOM atom;
120     BOOL16 nullport = FALSE;
121     LPCSTR port_name;
122     LPSTR device_mode;
123     ENVTABLE *env;
124     HGLOBAL16 handle;
125
126     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nCount);
127
128     if ((atom = PortNameToAtom(lpPortName, FALSE))) {
129         if (atom == GDI_GetNullPortAtom()) {
130             nullport = TRUE;
131             atom = FindAtomA((LPCSTR)lpdev);
132         }
133         env = SearchEnvTable(atom);
134         GlobalFree16(env->handle);
135         env->atom = 0;
136     }
137     if (nCount) { /* store DEVMODE struct */
138         if (nullport)
139             port_name = (LPSTR)lpdev;
140         else
141             port_name = lpPortName;
142
143         if ((atom = PortNameToAtom(port_name, TRUE))
144          && (env = SearchEnvTable(0))
145          && (handle = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, nCount))) {
146             if (!(device_mode = GlobalLock16(handle))) {
147                 GlobalFree16(handle);
148                 return 0;
149             }
150             env->atom = atom;
151             env->handle = handle;
152             memcpy(device_mode, lpdev, nCount);
153             GlobalUnlock16(handle);
154             return handle;
155         }
156         else return 0;
157     }
158     else return -1;
159 }