Shi Quan He (of Corel)
[wine] / graphics / 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 #include <stdio.h>
10 #include <string.h>
11 #include "config.h"
12 #include "gdi.h"
13 #include "debugtools.h"
14 #include "heap.h"
15
16 DEFAULT_DEBUG_CHANNEL(gdi)
17
18 typedef struct {
19         ATOM atom;
20         HGLOBAL16 handle;
21 } ENVTABLE;
22
23 static ENVTABLE EnvTable[20];
24
25 static ENVTABLE *SearchEnvTable(ATOM atom)
26 {
27     INT16 i;
28     
29     for (i = 19; i >= 0; i--) {
30       if (EnvTable[i].atom == atom)
31         return &EnvTable[i];
32     }
33     return NULL;
34 }
35
36 static ATOM GDI_GetNullPortAtom(void)
37 {
38     static ATOM NullPortAtom = 0;
39     if (!NullPortAtom)
40     {
41         char NullPort[256];
42         
43         GetProfileStringA( "windows", "nullport", "none",
44                              NullPort, sizeof(NullPort) );
45         NullPortAtom = AddAtomA( NullPort );
46     }
47     return NullPortAtom;
48 }
49
50 static ATOM PortNameToAtom(LPCSTR lpPortName, BOOL16 add)
51 {
52     char *p;
53     BOOL needfree = FALSE;
54     ATOM ret;
55
56     if (lpPortName[strlen(lpPortName) - 1] == ':') {
57         p = HEAP_strdupA(GetProcessHeap(), 0, lpPortName);
58         p[strlen(lpPortName) - 1] = '\0';
59         needfree = TRUE;
60     }
61     else
62         p = (char *)lpPortName;
63
64     if (add)
65         ret = AddAtomA(p);
66     else
67         ret =  FindAtomA(p);
68
69     if(needfree) HeapFree(GetProcessHeap(), 0, p);
70
71     return ret;
72 }
73
74
75 /***********************************************************************
76  *           GetEnvironment   (GDI.134)
77  */
78 INT16 WINAPI GetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nMaxSize)
79 {
80     ATOM atom;
81     LPCSTR p;
82     ENVTABLE *env;
83     WORD size;
84
85     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nMaxSize);
86
87     if (!(atom = PortNameToAtom(lpPortName, FALSE)))
88         return 0;
89     if (atom == GDI_GetNullPortAtom())
90         if (!(atom = FindAtomA((LPCSTR)lpdev)))
91             return 0;
92     if (!(env = SearchEnvTable(atom)))
93         return 0;
94     size = GlobalSize16(env->handle);
95     if (!lpdev) return 0;
96     if (size < nMaxSize) nMaxSize = size;
97     if (!(p = GlobalLock16(env->handle))) return 0;
98     memcpy(lpdev, p, nMaxSize);
99     GlobalUnlock16(env->handle);
100     return nMaxSize;
101 }
102
103
104 /***********************************************************************
105  *          SetEnvironment   (GDI.132)
106  */
107 INT16 WINAPI SetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nCount)
108 {
109     ATOM atom; 
110     BOOL16 nullport = FALSE;
111     LPSTR p;
112     ENVTABLE *env;
113     HGLOBAL16 handle;
114
115     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nCount);
116
117     if ((atom = PortNameToAtom(lpPortName, FALSE))) {
118         if (atom == GDI_GetNullPortAtom()) {
119             nullport = TRUE;
120             atom = FindAtomA((LPCSTR)lpdev);
121         }
122         env = SearchEnvTable(atom);
123         GlobalFree16(env->handle);
124         env->atom = 0;
125     }
126     if (nCount) { /* store DEVMODE struct */
127         if (nullport)
128             p = (LPSTR)lpdev;
129         else
130             p = (LPSTR)lpPortName;
131
132         if ((atom = PortNameToAtom(p, TRUE))
133          && (env = SearchEnvTable(0))
134          && (handle = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, nCount))) {
135             if (!(p = GlobalLock16(handle))) {
136                 GlobalFree16(handle);
137                 return 0;
138             }
139             env->atom = atom;
140             env->handle = handle;
141             memcpy(p, lpdev, nCount);
142             GlobalUnlock16(handle);
143             return handle;
144         }
145         else return 0;
146     }
147     else return -1;
148 }