xref: /inferno-os/emu/Nt/ie-win.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 #define Unknown win_Unknown
2 #include	<windows.h>
3 #undef Unknown
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"error.h"
7 
8 #include	"keyboard.h"
9 #include	"cursor.h"
10 #include	"ieplugin.h"
11 
12 /*
13  * image channel descriptors - copied from draw.h as it clashes with windows.h on many things
14  */
15 enum {
16 	CRed = 0,
17 	CGreen,
18 	CBlue,
19 	CGrey,
20 	CAlpha,
21 	CMap,
22 	CIgnore,
23 	NChan,
24 };
25 
26 #define __DC(type, nbits)	((((type)&15)<<4)|((nbits)&15))
27 #define CHAN1(a,b)	__DC(a,b)
28 #define CHAN2(a,b,c,d)	(CHAN1((a),(b))<<8|__DC((c),(d)))
29 #define CHAN3(a,b,c,d,e,f)	(CHAN2((a),(b),(c),(d))<<8|__DC((e),(f)))
30 #define CHAN4(a,b,c,d,e,f,g,h)	(CHAN3((a),(b),(c),(d),(e),(f))<<8|__DC((g),(h)))
31 
32 #define NBITS(c) ((c)&15)
33 #define TYPE(c) (((c)>>4)&15)
34 
35 enum {
36 	GREY1	= CHAN1(CGrey, 1),
37 	GREY2	= CHAN1(CGrey, 2),
38 	GREY4	= CHAN1(CGrey, 4),
39 	GREY8	= CHAN1(CGrey, 8),
40 	CMAP8	= CHAN1(CMap, 8),
41 	RGB15	= CHAN4(CIgnore, 1, CRed, 5, CGreen, 5, CBlue, 5),
42 	RGB16	= CHAN3(CRed, 5, CGreen, 6, CBlue, 5),
43 	RGB24	= CHAN3(CRed, 8, CGreen, 8, CBlue, 8),
44 	RGBA32	= CHAN4(CRed, 8, CGreen, 8, CBlue, 8, CAlpha, 8),
45 	ARGB32	= CHAN4(CAlpha, 8, CRed, 8, CGreen, 8, CBlue, 8),	/* stupid VGAs */
46 	XRGB32  = CHAN4(CIgnore, 8, CRed, 8, CGreen, 8, CBlue, 8),
47 };
48 
49 extern ulong displaychan;
50 
51 extern void drawend(void);
52 
53 extern	int	chantodepth(ulong);
54 extern	int	main(int argc, char **argv);
55 static	void	dprint(char*, ...);
56 static	DWORD WINAPI	winproc(LPVOID);
57 
58 static	HINSTANCE	inst;
59 static	HINSTANCE	previnst;
60 static	int		attached;
61 static	ulong	*data;
62 
63 extern	DWORD	PlatformId;
64 char*	gkscanid = "emu_win32vk";
65 
66 extern int cflag;
67 Plugin *plugin = NULL;
68 
69 DWORD WINAPI
70 pluginproc(LPVOID p)
71 {
72 	int x, y, b;
73 
74 	for (;;) {
75 		WaitForSingleObject(plugin->dopop, INFINITE);
76 		switch (POP.op) {
77 		case Pgfxkey:
78 			if(gkbdq != nil)
79 				gkbdputc(gkbdq, POP.u.key);
80 			break;
81 		case Pmouse:
82 			x = POP.u.m.x;
83 			y = POP.u.m.y;
84 			b = POP.u.m.b;
85 			mousetrack(b, x, y, 0);
86 			break;
87 		}
88 		SetEvent(plugin->popdone);
89 	}
90 }
91 
92 int WINAPI
93 WinMain(HINSTANCE winst, HINSTANCE wprevinst, LPSTR cmdline, int wcmdshow)
94 {
95 	HANDLE sharedmem;
96 	uint pid = _getpid();
97 	char iname[16];
98 	inst = winst;
99 	previnst = wprevinst;
100 	sprint(iname, "%uX", pid);
101 	sharedmem = OpenFileMapping(FILE_MAP_WRITE, FALSE, iname);
102 	if (sharedmem != NULL)
103 		plugin = MapViewOfFile(sharedmem, FILE_MAP_WRITE, 0, 0, 0);
104 	if (plugin != NULL) {
105 		DWORD tid;
106 		int i;
107 		Xsize = plugin->Xsize;
108 		Ysize = plugin->Ysize;
109 		displaychan = plugin->cdesc;
110 		cflag = plugin->cflag;
111 		for (i = 0; i < PI_NCLOSE; i++)
112 			CloseHandle(plugin->closehandles[i]);
113 		CreateThread(0, 0, pluginproc, 0, 0, &tid);
114 
115 		/* cmdline passed into WinMain does not contain name of executable.
116 		 * The globals __argc and __argv to include this info - like UNIX
117 		 */
118 		main(__argc, __argv);
119 		UnmapViewOfFile(plugin);
120 		plugin = NULL;
121 	}
122 	if (sharedmem != NULL)
123 		CloseHandle(sharedmem);
124 	return 0;
125 }
126 
127 static Lock ioplock;
128 
129 void
130 newiop()
131 {
132 	lock(&ioplock);
133 }
134 
135 int
136 sendiop()
137 {
138 	int val;
139 	SetEvent(plugin->doiop);
140 	WaitForSingleObject(plugin->iopdone, INFINITE);
141 	val = plugin->iop.val;
142 	unlock(&ioplock);
143 	return val;
144 }
145 
146 void
147 dprint(char *fmt, ...)
148 {
149 	va_list arg;
150 	char buf[128];
151 
152 	va_start(arg, fmt);
153 	vseprint(buf, buf+sizeof(buf), fmt, (LPSTR)arg);
154 	va_end(arg);
155 	OutputDebugString("inferno: ");
156 	OutputDebugString(buf);
157 }
158 
159 uchar*
160 attachscreen(IRectangle *r, ulong *chan, int *d, int *width, int *softscreen)
161 {
162 	int k;
163 
164 	if (!attached) {
165 		newiop();
166 		IOP.op = Iattachscr;
167 		if (sendiop() != 0)
168 			return nil;
169 		data = plugin->screen;
170 		attached = 1;
171 	}
172 	r->min.x = 0;
173 	r->min.y = 0;
174 	r->max.x = Xsize;
175 	r->max.y = Ysize;
176 
177 	if(displaychan == 0)
178 		displaychan = CMAP8;
179 	*chan = displaychan;
180 
181 	k = chantodepth(displaychan);
182 	*d = k;
183 	*width = (Xsize/4)*(k/8);
184 	*softscreen = 1;
185 	return (uchar*)data;
186 }
187 
188 void
189 flushmemscreen(IRectangle r)
190 {
191 	if(r.max.x<=r.min.x || r.max.y<=r.min.y)
192 		return;
193 	newiop();
194 	IOP.op = Iflushscr;
195 	IOP.u.r = r;
196 	sendiop();
197 }
198 
199 void
200 setpointer(int x, int y)
201 {
202 	USED(x); USED(y);
203 	// TODO
204 }
205 
206 void
207 drawcursor(Drawcursor* c)
208 {
209 	USED(c);
210 	// TODO
211 }
212 
213 char*
214 clipread(void)
215 {
216 	return nil;
217 }
218 
219 int
220 clipwrite(char *p)
221 {
222 	USED(p);
223 	return -1;
224 }
225