📄 fserve.c
字号:
else fsfont->inkMetrics = pCI; if (_fs_read_pad(conn, (char *) fsci, SIZEOF(fsXCharInfo) * rep.num_extents) == -1) { fs_free_font(bfont); xfree(fsci); return StillWorking; } fsd->glyphs_to_get = 0; fscip = (pointer) fsci; ci = fsfont->inkMetrics; for (i = 0; i < rep.num_extents; i++) { memcpy(&fscilocal, fscip, SIZEOF(fsXCharInfo)); /* align it */ _fs_convert_char_info(&fscilocal, &ci->metrics); fscip += SIZEOF(fsXCharInfo); /* Initialize the bits field for later glyph-caching use */ if (NONZEROMETRICS(&ci->metrics)) { if (!haveInk && (ci->metrics.leftSideBearing == ci->metrics.rightSideBearing || ci->metrics.ascent == -ci->metrics.descent)) pCI[i].bits = &_fs_glyph_zero_length; else { pCI[i].bits = &_fs_glyph_undefined; fsd->glyphs_to_get++; } } else pCI[i].bits = (char *)0; ci++; } xfree(fsci); /* build bitmap metrics, ImageRectMax style */ if (haveInk) { FontInfoRec *fi = &bfont->pfont->info; CharInfoPtr ii; ci = fsfont->encoding; ii = fsfont->inkMetrics; for (i = 0; i < rep.num_extents; i++, ci++, ii++) { if (NONZEROMETRICS(&ii->metrics)) { ci->metrics.leftSideBearing = FONT_MIN_LEFT(fi); ci->metrics.rightSideBearing = FONT_MAX_RIGHT(fi); ci->metrics.ascent = FONT_MAX_ASCENT(fi); ci->metrics.descent = FONT_MAX_DESCENT(fi); ci->metrics.characterWidth = FONT_MAX_WIDTH(fi); ci->metrics.attributes = ii->metrics.attributes; } else { ci->metrics = ii->metrics; } } } { unsigned int r, c, numCols, firstCol; firstCol = bfont->pfont->info.firstCol; numCols = bfont->pfont->info.lastCol - firstCol + 1; c = bfont->pfont->info.defaultCh; fsfont->pDefault = 0; if (bfont->pfont->info.lastRow) { r = c >> 8; r -= bfont->pfont->info.firstRow; c &= 0xff; c -= firstCol; if (r < bfont->pfont->info.lastRow-bfont->pfont->info.firstRow+1 && c < numCols) fsfont->pDefault = &pCI[r * numCols + c]; } else { c -= firstCol; if (c < numCols) fsfont->pDefault = &pCI[c]; } } bfont->state = FS_GLYPHS_REPLY; if (bfont->flags & FontLoadBitmaps) { fs_send_query_bitmaps(fpe, blockrec); return StillWorking; } return Successful;}/* * XXX should probably continue to read here if we can, but must be sure * it's our packet waiting, rather than another interspersed */static intfs_do_open_font(fpe, blockrec, readheader) FontPathElementPtr fpe; FSBlockDataPtr blockrec; Bool readheader;{ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; FSFpePtr conn = (FSFpePtr) fpe->private; int err; switch (bfont->state) { case FS_OPEN_REPLY: if (readheader) { /* get the next header */ if (_fs_read(conn, (char *) &blockrec->header, SIZEOF(fsGenericReply)) == -1) { fs_free_font(bfont); err = StillWorking; break; } } bfont->errcode = fs_read_open_font(fpe, blockrec); if (bfont->errcode != StillWorking) { /* already loaded, or error */ /* if font's already loaded, massage error code */ switch (bfont->state) { case FS_DONE_REPLY: bfont->errcode = Successful; break; case FS_DEPENDING: bfont->errcode = StillWorking; break; } err = bfont->errcode; break; } /* if more data to read or Sync, fall thru, else return */ if (!(bfont->flags & FontOpenSync)) { err = bfont->errcode; break; } else { if (_fs_read(conn, (char *) &blockrec->header, SIZEOF(fsGenericReply)) == -1) { fs_free_font(bfont); err = StillWorking; break; } } /* fall through */ case FS_INFO_REPLY: bfont->errcode = fs_read_query_info(fpe, blockrec); if (bfont->errcode != StillWorking) { err = bfont->errcode; break; } if (!(bfont->flags & FontOpenSync)) { err = bfont->errcode; break; /* if more data to read, fall thru, else return */ } else { if (_fs_read(conn, (char *) &blockrec->header, SIZEOF(fsGenericReply))) { fs_free_font(bfont); err = StillWorking; break; } } /* fall through */ case FS_EXTENT_REPLY: bfont->errcode = fs_read_extent_info(fpe, blockrec); if (bfont->errcode != StillWorking) { err = bfont->errcode; break; } if (!(bfont->flags & FontOpenSync)) { err = bfont->errcode; break; } else if (bfont->flags & FontLoadBitmaps) { if (_fs_read(conn, (char *) &blockrec->header, SIZEOF(fsGenericReply))) { fs_free_font(bfont); err = StillWorking; break; } } /* fall through */ case FS_GLYPHS_REPLY: if (bfont->flags & FontLoadBitmaps) { bfont->errcode = fs_read_glyphs(fpe, blockrec); } err = bfont->errcode; break; case FS_DEPENDING: /* can't happen */ err = bfont->errcode; default: err = bfont->errcode; break; } if (err != StillWorking) { bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ while (blockrec = blockrec->depending) { bfont = (FSBlockedFontPtr) blockrec->data; bfont->errcode = err; bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ } } return err;}/* ARGSUSED */static voidfs_block_handler(data, wt, LastSelectMask) pointer data; struct timeval **wt; fd_set* LastSelectMask;{ static struct timeval recon_timeout; Time_t now, soonest; FSFpePtr recon; XFD_ORSET(LastSelectMask, LastSelectMask, &_fs_fd_mask); if (recon = awaiting_reconnect) { now = time((Time_t *) 0); soonest = recon->time_to_try; while (recon = recon->next_reconnect) { if (recon->time_to_try < soonest) soonest = recon->time_to_try; } if (soonest < now) soonest = now; soonest = soonest - now; recon_timeout.tv_sec = soonest; recon_timeout.tv_usec = 0; if (*wt == (struct timeval *) 0) { *wt = &recon_timeout; } else if ((*wt)->tv_sec > soonest) { **wt = recon_timeout; } }}static voidfs_handle_unexpected(conn, rep) FSFpePtr conn; fsGenericReply *rep;{ if (rep->type == FS_Event && rep->data1 == KeepAlive) { fsNoopReq req; /* ping it back */ req.reqType = FS_Noop; req.length = SIZEOF(fsNoopReq) >> 2; _fs_add_req_log(conn, FS_Noop); _fs_write(conn, (char *) &req, SIZEOF(fsNoopReq)); } /* this should suck up unexpected replies and events */ _fs_eat_rest_of_error(conn, (fsError *) rep);}static intfs_wakeup(fpe, LastSelectMask) FontPathElementPtr fpe; fd_set* LastSelectMask;{ FSBlockDataPtr blockrec, br; FSFpePtr conn = (FSFpePtr) fpe->private; int err; fsGenericReply rep; if (awaiting_reconnect) { _fs_try_reconnect(); } /* see if there's any data to be read */ /* * Don't continue if the fd is -1 (which will be true when the * font server terminates */ if (conn->fs_fd == -1) return FALSE; if (FD_ISSET(conn->fs_fd, LastSelectMask)) {#if defined(NOTDEF) || defined(__EMX__) /* bogus - doesn't deal with EOF very well, * now does it ... */ /* * make sure it isn't spurious - mouse events seem to trigger extra * problems. Under OS/2, this is especially true ... */ if (_fs_data_ready(conn) <= 0) { return FALSE; }#endif /* get the header */ if (_fs_read(conn, (char *) &rep, SIZEOF(fsGenericReply)) == -1) return FALSE; /* find the matching block record */ for (br = (FSBlockDataPtr) conn->blocked_requests; br; br = br->next) { if ((CARD16)(br->sequence_number & 0xffff) == (CARD16)(rep.sequenceNumber - 1)) break; } if (!br) { fs_handle_unexpected(conn, &rep); return FALSE; } blockrec = br; memcpy(&blockrec->header, &rep, SIZEOF(fsGenericReply)); /* go read it, and if we're done, wake up the appropriate client */ switch (blockrec->type) { case FS_OPEN_FONT: err = fs_do_open_font(fpe, blockrec, FALSE); break; case FS_LOAD_GLYPHS: err = fs_read_glyphs(fpe, blockrec); break; case FS_LIST_FONTS: err = fs_read_list(fpe, blockrec); break; case FS_LIST_WITH_INFO: err = fs_read_list_info(fpe, blockrec); break; default: break; } if (err != StillWorking) { while (blockrec) { ClientSignal(blockrec->client); blockrec = blockrec->depending; } } /* * Xx we could loop here and eat any additional replies, but it should * feel more responsive for other clients if we come back later */ } else if (awaiting_reconnect) { _fs_try_reconnect(); } return FALSE;}/* * Reconnection code */void_fs_connection_died(conn) FSFpePtr conn;{ if (!conn->attemptReconnect) return; conn->attemptReconnect = FALSE; fs_close_conn(conn); conn->time_to_try = time((Time_t *) 0) + FS_RECONNECT_WAIT; conn->reconnect_delay = FS_RECONNECT_WAIT; conn->fs_fd = -1; conn->trans_conn = NULL; conn->next_reconnect = awaiting_reconnect; awaiting_reconnect = conn;}static int_fs_restart_connection(conn) FSFpePtr conn;{ FSBlockDataPtr block; conn->current_seq = 0; FD_SET(conn->fs_fd, &_fs_fd_mask); if (!fs_send_init_packets(conn)) return FALSE; while (block = (FSBlockDataPtr) conn->blocked_requests) { ClientSignal(block->client); fs_abort_blockrec(conn, block); } return TRUE;}static void_fs_try_reconnect(){ FSFpePtr conn, *prev; Time_t now; prev = &awaiting_reconnect; now = time((Time_t *) 0); while (conn = *prev) { if (now - conn->time_to_try > 0) { if (_fs_reopen_server(conn) && _fs_restart_connection(conn)) { conn->attemptReconnect = TRUE; *prev = conn->next_reconnect; if (prev == &awaiting_reconnect) continue; } else { if (conn->reconnect_delay < FS_MAX_RECONNECT_WAIT) conn->reconnect_delay *= 2; now = time((Time_t *) 0); conn->time_to_try = now + conn->reconnect_delay; } } prev = &conn->next_reconnect; }}/* * sends the actual request out *//* ARGSUSED */static intfs_send_open_font(client, fpe, flags, name, namelen, format, fmask, id, ppfont) pointer client; FontPathElementPtr fpe; Mask flags; char *name; int namelen; fsBitmapFormat format; fsBitmapFormatMask fmask; XID id; FontPtr *ppfont;{ FontPtr newfont; FSBlockDataPtr blockrec = NULL; FSBlockedFontPtr blockedfont; FSFontDataPtr fsd; FSFontPtr fsfont; FSFpePtr conn; fsOpenBitmapFontReq openreq; int err = Suspended; XID newid; unsigned char buf[1024]; char *fontname; if (flags & FontReopen) { Atom nameatom, fn = None; int i; newfont = *ppfont; fsd = (FSFontDataPtr)newfont->fpePrivate; fsfont = (FSFontPtr)newfont->fontPrivate; fpe = newfont->fpe; format = fsd->format; fmask = fsd->fmask; newid = fsd->fontid; /* This is an attempt to reopen a font. Did the font have a NAME property? */ if ((nameatom = MakeAtom("FONT", 4, 0)) != None) { for (i = 0; i < newfont->info.nprops; i++) if (newfont->info.props[i].name == nameatom && newfont->info.isStringProp[i]) { fn = newfont->info.props[i].value; break; } } if (fn == None || !(name = NameForAtom(fn))) { name = fsd->name; namelen = fsd->namelen; } else namelen = strlen(name); } conn = (FSFpePtr) fpe->private; if (namelen > sizeof (buf) - 1) return BadFontName; _fs_client_access (conn, client, (flags & FontOpenSync) != 0); _fs_client_resolution(conn); if (!(flags & FontReopen)) { newid = GetNewFontClientID();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -