2 * Copyright 1990 Network Computing Devices
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Network Computing Devices not be
9 * used in advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission. Network Computing
11 * Devices makes no representations about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied
15 * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
17 * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
18 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
20 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
21 * OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: Dave Lemke, Network Computing Devices, Inc
26 * font server i/o routines
35 #include "X11/Xwindows.h"
40 #include "X11/Xtrans/Xtrans.h"
41 #include "X11/Xpoll.h"
42 #include <X11/fonts/FS.h>
43 #include <X11/fonts/FSproto.h>
44 #include <X11/fonts/fontmisc.h>
45 #include <X11/fonts/fontstruct.h>
46 #include "fservestr.h"
50 #include <sys/types.h>
53 #include <sys/socket.h>
60 #define EWOULDBLOCK WSAEWOULDBLOCK
62 #define EINTR WSAEINTR
67 static int padlength[4] = {0, 3, 2, 1};
71 _fs_resize (FSBufPtr buf, long size);
74 _fs_downsize (FSBufPtr buf, long size);
77 _fs_poll_connect (XtransConnInfo trans_conn, int timeout)
81 int fs_fd = _FontTransGetConnectionNumber (trans_conn);
89 FD_SET (fs_fd, &w_mask);
90 ret = Select (fs_fd + 1, NULL, &w_mask, NULL, &tv);
91 } while (ret < 0 && ECHECK(EINTR));
100 _fs_connect(char *servername, int *err)
102 XtransConnInfo trans_conn; /* transport connection object */
108 * Open the network connection.
110 if( (trans_conn=_FontTransOpenCOTSClient(servername)) == NULL )
117 * Set the connection non-blocking since we use select() to block.
120 _FontTransSetOption(trans_conn, TRANS_NONBLOCKING, 1);
123 i = _FontTransConnect(trans_conn,servername);
124 } while ((i == TRANS_TRY_CONNECT_AGAIN) && (retries-- > 0));
128 if (i == TRANS_IN_PROGRESS)
136 if (ret == FSIO_ERROR)
138 _FontTransClose(trans_conn);
147 _fs_fill (FSFpePtr conn)
153 if (_fs_flush (conn) < 0)
156 * Don't go overboard here; stop reading when we've
157 * got enough to satisfy the pending request
159 while ((conn->inNeed - (conn->inBuf.insert - conn->inBuf.remove)) > 0)
161 avail = conn->inBuf.size - conn->inBuf.insert;
163 * For SVR4 with a unix-domain connection, ETEST() after selecting
164 * readable means the server has died. To do this here, we look for
165 * two consecutive reads returning ETEST().
168 bytes_read =_FontTransRead(conn->trans_conn,
169 conn->inBuf.buf + conn->inBuf.insert,
171 if (bytes_read > 0) {
172 conn->inBuf.insert += bytes_read;
177 if (bytes_read == 0 || ETEST ())
182 if (_fs_wait_for_readable (conn, 0) == FSIO_BLOCK)
187 _fs_connection_died (conn);
195 * Make space and return whether data have already arrived
199 _fs_start_read (FSFpePtr conn, long size, char **buf)
204 if (fs_inqueued(conn) < size)
206 if (_fs_resize (&conn->inBuf, size) != FSIO_READY)
208 _fs_connection_died (conn);
211 ret = _fs_fill (conn);
212 if (ret == FSIO_ERROR)
214 if (ret == FSIO_BLOCK || fs_inqueued(conn) < size)
218 *buf = conn->inBuf.buf + conn->inBuf.remove;
223 _fs_done_read (FSFpePtr conn, long size)
225 if (conn->inBuf.insert - conn->inBuf.remove < size)
228 fprintf (stderr, "_fs_done_read skipping to many bytes\n");
232 conn->inBuf.remove += size;
233 conn->inNeed -= size;
234 _fs_downsize (&conn->inBuf, FS_BUF_MAX);
238 _fs_pad_length (long len)
240 return len + padlength[len&3];
244 _fs_flush (FSFpePtr conn)
249 /* XXX - hack. The right fix is to remember that the font server
250 has gone away when we first discovered it. */
254 while ((remain = conn->outBuf.insert - conn->outBuf.remove) > 0)
256 bytes_written = _FontTransWrite(conn->trans_conn,
257 conn->outBuf.buf + conn->outBuf.remove,
259 if (bytes_written > 0)
261 conn->outBuf.remove += bytes_written;
265 if (bytes_written == 0 || ETEST ())
267 conn->brokenWriteTime = GetTimeInMillis () + FS_FLUSH_POLL;
268 _fs_mark_block (conn, FS_BROKEN_WRITE);
273 _fs_connection_died (conn);
278 if (conn->outBuf.remove == conn->outBuf.insert)
280 _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE);
281 if (conn->outBuf.size > FS_BUF_INC)
282 conn->outBuf.buf = realloc (conn->outBuf.buf, FS_BUF_INC);
283 conn->outBuf.remove = conn->outBuf.insert = 0;
289 _fs_resize (FSBufPtr buf, long size)
296 if (buf->remove != buf->insert)
299 buf->buf + buf->remove,
300 buf->insert - buf->remove);
302 buf->insert -= buf->remove;
305 if (buf->size - buf->remove < size)
307 new_size = ((buf->remove + size + FS_BUF_INC) / FS_BUF_INC) * FS_BUF_INC;
308 new = realloc (buf->buf, new_size);
312 buf->size = new_size;
318 _fs_downsize (FSBufPtr buf, long size)
320 if (buf->insert == buf->remove)
322 buf->insert = buf->remove = 0;
323 if (buf->size > size)
325 buf->buf = realloc (buf->buf, size);
332 _fs_io_reinit (FSFpePtr conn)
334 conn->outBuf.insert = conn->outBuf.remove = 0;
335 _fs_downsize (&conn->outBuf, FS_BUF_INC);
336 conn->inBuf.insert = conn->inBuf.remove = 0;
337 _fs_downsize (&conn->inBuf, FS_BUF_MAX);
341 _fs_io_init (FSFpePtr conn)
343 conn->outBuf.insert = conn->outBuf.remove = 0;
344 conn->outBuf.buf = malloc (FS_BUF_INC);
345 if (!conn->outBuf.buf)
347 conn->outBuf.size = FS_BUF_INC;
349 conn->inBuf.insert = conn->inBuf.remove = 0;
350 conn->inBuf.buf = malloc (FS_BUF_INC);
351 if (!conn->inBuf.buf)
353 free (conn->outBuf.buf);
354 conn->outBuf.buf = 0;
357 conn->inBuf.size = FS_BUF_INC;
363 _fs_io_fini (FSFpePtr conn)
365 if (conn->outBuf.buf)
366 free (conn->outBuf.buf);
368 free (conn->inBuf.buf);
372 _fs_do_write(FSFpePtr conn, const char *data, long len, long size)
376 fprintf(stderr, "tried to write 0 bytes \n");
381 if (conn->fs_fd == -1)
384 while (conn->outBuf.insert + size > conn->outBuf.size)
386 if (_fs_flush (conn) < 0)
388 if (_fs_resize (&conn->outBuf, size) < 0)
390 _fs_connection_died (conn);
394 memcpy (conn->outBuf.buf + conn->outBuf.insert, data, len);
396 memset (conn->outBuf.buf + conn->outBuf.insert + len, 0, size - len);
397 conn->outBuf.insert += size;
398 _fs_mark_block (conn, FS_PENDING_WRITE);
403 * Write the indicated bytes
406 _fs_write (FSFpePtr conn, const char *data, long len)
408 return _fs_do_write (conn, data, len, len);
412 * Write the indicated bytes adding any appropriate pad
415 _fs_write_pad(FSFpePtr conn, const char *data, long len)
417 return _fs_do_write (conn, data, len, len + padlength[len & 3]);
421 _fs_wait_for_readable(FSFpePtr conn, int ms)
433 tv.tv_sec = ms / 1000;
434 tv.tv_usec = (ms % 1000) * 1000;
435 FD_SET(conn->fs_fd, &r_mask);
436 FD_SET(conn->fs_fd, &e_mask);
437 result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, &tv);
440 if (ECHECK(EINTR) || ECHECK(EAGAIN))
447 if (FD_ISSET(conn->fs_fd, &r_mask))