]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/os/iopreader.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / os / iopreader.c
1 /* $XConsortium: iopreader.c,v 1.2 94/04/12 17:24:33 dpw Exp $ */
2
3 /* Copyright (c) 1987 by the Regents of the University of California
4  * Copyright (c) 1994 by the Vrije Universiteit, Amsterdam.
5  *
6  * Permission to use, copy, modify, and distribute this
7  * software and its documentation for any purpose and without
8  * fee is hereby granted, provided that the above copyright
9  * notice appear in all copies.  The University of California
10  * and the Vrije Universiteit make no representations about
11  * the suitability of this software for any purpose.
12  * It is provided "as is" without express or implied warranty.
13  */
14
15 #ifdef AMOEBA
16 /*
17  * iopreader.c
18  *
19  */
20 #define port am_port_t
21 #include <amoeba.h>
22 #include <ampolicy.h>
23 #include <cmdreg.h>
24 #include <stdcom.h>
25 #include <stderr.h>
26 #include <server/iop/iop.h>
27 #undef port
28
29 #include "osdep.h"
30
31 #define DEVREADER_STACK 8000
32 #define MAXEVENTQUEUE   32
33
34 capability iopcap;
35
36 static mutex lock;
37 static semaphore empty, filled;
38
39 static IOPEvent event_queue[MAXEVENTQUEUE];
40 static int event_qin, event_qout;
41
42 void IOPCleanUp();
43 static void IOPServerReader();
44
45 /*
46  * Initialize the IOP server
47  */
48 void
49 InitializeIOPServerReader()
50 {
51     capability          hostcap;
52     errstat             err;
53
54     /*
55      * Initialize event queue
56      */
57     event_qin = event_qout = 0;
58     sema_init(&empty, MAXEVENTQUEUE);
59     sema_init(&filled, 0);
60     mu_init(&lock);
61
62     /* 
63      * Get IOP capability, and enable the server
64      */
65     if (XServerHostName == NULL)
66         FatalError("No hostname, no screen\n");
67     
68     if ((err = host_lookup(XServerHostName, &hostcap)) != STD_OK ||
69         (err = dir_lookup(&hostcap, DEF_IOPSVRNAME, &iopcap)) != STD_OK)
70     {
71         FatalError("Cannot find IOP server for %s: %s\n",
72                     XServerHostName, err_why(err));
73     }
74
75     /*
76      * Enable IOP server
77      */
78     if ((err = iop_enable(&iopcap)) != STD_OK)
79         FatalError("iop_enable failed (%s)\n", err_why(err));
80
81     /*
82      * Start IOP reader thread
83      */
84     atexit(IOPCleanUp);
85     if (thread_newthread(IOPServerReader, DEVREADER_STACK, 0, 0) <= 0)
86         FatalError("Cannot start IOP reader thread\n");
87 }
88
89 /*
90  * IOP clean up, actuall disable the IOP server. Its the IOP's own choice
91  * what do do (perhaps restore the screen?).
92  */
93 void
94 IOPCleanUp()
95 {
96     errstat err;
97
98     if ((err = iop_disable(&iopcap)) != STD_OK)
99         ErrorF("iop_disable failed (%s)\n", err_why(err));
100 }
101
102 /*
103  * This threads polls the IOP server for events. Once an event (or a
104  * number of events) are read, they are queued up using a traditional
105  * producer/consumer approach.
106  */
107 static void
108 IOPServerReader()
109 {
110     IOPEvent            queue[MAXEVENTQUEUE-1];
111     int                 nevents, i;
112     errstat             err;
113
114     WaitForInitialization();
115
116 #ifdef XDEBUG
117     if (amDebug) ErrorF("IOPServerReader() running ...\n");
118 #endif
119
120     for (;;) {
121         do {
122             nevents = MAXEVENTQUEUE - 1;
123             err = iop_getevents(&iopcap, queue, &nevents);
124             if (err != STD_OK) {
125                 if (err != RPC_FAILURE) {
126                     ErrorF("iop_getevents failed (%s)\n", err_why(err));
127                 }
128                 nevents = 0;
129             }
130         } while (nevents <= 0);
131
132         /* store event(s) in the global event queue */
133         sema_mdown(&empty, nevents);
134         mu_lock(&lock);
135         for (i = 0; i < nevents; i++) {
136             event_queue[event_qin] = queue[i];
137             event_qin = (event_qin + 1) % MAXEVENTQUEUE;
138         }
139         mu_unlock(&lock);
140         sema_mup(&filled, nevents);
141         WakeUpMainThread();
142     }
143 }
144
145 /*
146  * Return the number of IOP events waiting
147  */
148 int
149 AmoebaEventsAvailable()
150 {
151     return sema_level(&filled);
152 }
153
154 /*
155  * Get the IOP events from the queue. ``size'' is the maximum the
156  * requestor cares to handle, the actual size read is returned as
157  * result.
158  */
159 int
160 AmoebaGetEvents(queue, size)
161     IOPEvent    *queue;
162     int         size;
163 {
164     int         nevents, i;
165
166     if (sema_level(&filled) <= 0) return 0;
167     if ((nevents = sema_level(&filled)) > size)
168         nevents = size;
169     sema_mdown(&filled, nevents);
170     mu_lock(&lock);
171     for (i = 0; i < nevents; i++) {
172         queue[i] = event_queue[event_qout];
173         event_qout = (event_qout + 1) % MAXEVENTQUEUE;
174     }
175     mu_unlock(&lock);
176     sema_mup(&empty, nevents);
177     return nevents;
178 }
179 #endif /* AMOEBA */