📄 fserve.c
字号:
switch (type) { case FS_OPEN_FONT: size = sizeof(FSBlockedFontRec); break; case FS_LOAD_GLYPHS: size = sizeof(FSBlockedGlyphRec); break; case FS_LIST_FONTS: size = sizeof(FSBlockedListRec); break; case FS_LIST_WITH_INFO: size = sizeof(FSBlockedListInfoRec); break; default: break; } blockrec->data = (pointer) xalloc(size); if (!blockrec->data) { xfree(blockrec); return (FSBlockDataPtr) 0; } blockrec->client = client; blockrec->sequence_number = fsfpe->current_seq; blockrec->type = type; blockrec->depending = 0; blockrec->next = (FSBlockDataPtr) 0; /* stick it on the end of the list (since its expected last) */ br = (FSBlockDataPtr) fsfpe->blocked_requests; if (!br) { fsfpe->blocked_requests = (pointer) blockrec; } else { while (br->next) br = br->next; br->next = blockrec; } return blockrec;}static void_fs_remove_block_rec(conn, blockrec) FSFpePtr conn; FSBlockDataPtr blockrec;{ FSBlockDataPtr br, last; last = (FSBlockDataPtr) 0; br = (FSBlockDataPtr) conn->blocked_requests; while (br) { if (br == blockrec) { if (last) last->next = br->next; else conn->blocked_requests = (pointer) br->next; if (br->type == FS_LOAD_GLYPHS) { FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)br->data; if (bglyph->num_expected_ranges) xfree(bglyph->expected_ranges); } xfree(br->data); xfree(br); return; } last = br; br = br->next; }}static voidsignal_clients_depending(clients_depending)FSClientsDependingPtr *clients_depending;{ FSClientsDependingPtr p = *clients_depending, p2; *clients_depending = (FSClientsDependingPtr)0; while (p != (FSClientsDependingPtr)0) { p2 = p; ClientSignal(p->client); p = p->next; xfree(p2); }}static intadd_clients_depending(clients_depending, client)FSClientsDependingPtr *clients_depending;pointer client;{ while (*clients_depending != (FSClientsDependingPtr)0) { if ((*clients_depending)->client == client) return Suspended; clients_depending = &(*clients_depending)->next; } *clients_depending = (FSClientsDependingPtr)xalloc( sizeof(FSClientsDependingRec)); if (!*clients_depending) return BadAlloc; (*clients_depending)->client = client; (*clients_depending)->next = 0; return Suspended;}static voidclean_aborted_blockrec(blockrec) FSBlockDataPtr blockrec;{ switch(blockrec->type) { case FS_LOAD_GLYPHS: { FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data; FontPtr pfont = bglyph->pfont; int num_expected_ranges = bglyph->num_expected_ranges; fsRange *expected_ranges = bglyph->expected_ranges; _fs_clean_aborted_loadglyphs(pfont, num_expected_ranges, expected_ranges); signal_clients_depending(&bglyph->clients_depending); break; } case FS_OPEN_FONT: { FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data; signal_clients_depending(&bfont->clients_depending); break; } default: break; }}static voidfs_abort_blockrec(conn, blockrec) FSFpePtr conn; FSBlockDataPtr blockrec;{ clean_aborted_blockrec(blockrec); _fs_remove_block_rec(conn, blockrec);}static voidfs_free_font(bfont) FSBlockedFontPtr bfont;{ FontPtr pfont; FSFontDataRec *fsd; pfont = bfont->pfont; fsd = (FSFontDataRec *) pfont->fpePrivate; /* xfree better be able to handle NULL */ (*pfont->unload_font)(pfont); DeleteFontClientID(fsd->fontid); xfree(fsd->name); xfree(pfont->info.isStringProp); xfree(pfont->info.props); xfree(pfont); xfree(fsd); bfont->pfont = (FontPtr) 0;}static void_fs_cleanup_font(bfont) FSBlockedFontPtr bfont;{ FSFontDataRec *fsd; if (bfont->pfont) { fsd = (FSFontDataRec *) bfont->pfont->fpePrivate; /* make sure the FS knows we choked on it */ fs_send_close_font(fsd->fpe, bfont->fontid); fs_free_font(bfont); } bfont->errcode = AllocError;}static intfs_read_open_font(fpe, blockrec) FontPathElementPtr fpe; FSBlockDataPtr blockrec;{ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; FSFpePtr conn = (FSFpePtr) fpe->private; fsOpenBitmapFontReply rep; FSBlockDataPtr blockOrig; FSBlockedFontPtr origBfont; /* pull out the OpenFont reply */ memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply)); if (rep.type == FS_Error) { _fs_eat_rest_of_error(conn, (fsError *) & rep); return BadFontName; } else { /* get rest of reply */ if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply), SIZEOF(fsOpenBitmapFontReply) - SIZEOF(fsGenericReply)) == -1) { /* If we're not reopening a font, we'll allocate the structures again after connection is reestablished. */ if (!(bfont->flags & FontReopen)) fs_free_font(bfont); return StillWorking; } } /* If we're not reopening a font and FS detected a duplicate font open request, replace our reference to the new font with a reference to an existing font (possibly one not finished opening). If this is a reopen, keep the new font reference... it's got the metrics and extents we read when the font was opened before. This also gives us the freedom to easily close the font if we we decide (in fs_read_query_info()) that we don't like what we got. */ if (rep.otherid && !(bfont->flags & FontReopen)) { (void) fs_send_close_font(fpe, bfont->fontid); /* Find old font if we're completely done getting it from server. */ fs_free_font(bfont); bfont->pfont = find_old_font(rep.otherid); bfont->fontid = rep.otherid; bfont->state = FS_DONE_REPLY; /* * look for a blocked request to open the same font */ for (blockOrig = (FSBlockDataPtr) conn->blocked_requests; blockOrig; blockOrig = blockOrig->next) { if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) { origBfont = (FSBlockedFontPtr) blockOrig->data; if (origBfont->fontid == rep.otherid) { blockrec->depending = blockOrig->depending; blockOrig->depending = blockrec; bfont->state = FS_DEPENDING; bfont->pfont = origBfont->pfont; break; } } } if (bfont->pfont == NULL) { /* XXX - something nasty happened */ return BadFontName; } return AccessDone; } bfont->pfont->info.cachable = rep.cachable != 0; bfont->state = FS_INFO_REPLY; /* ask for the next stage */ (void) fs_send_query_info(fpe, blockrec); return StillWorking;}static intfs_read_query_info(fpe, blockrec) FontPathElementPtr fpe; FSBlockDataPtr blockrec;{ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; FSFpePtr conn = (FSFpePtr) fpe->private; fsQueryXInfoReply rep; fsPropInfo pi; fsPropOffset *po; pointer pd; unsigned long prop_len; FSBlockedFontRec newbfont, *oldbfont; FontRec newpfont, *oldpfont; int err; /* If this is a reopen, accumulate the query info into a dummy font and compare to our original data. */ if (bfont->flags & FontReopen) { newbfont = *(oldbfont = bfont); bfont = &newbfont; newpfont = *(oldpfont = oldbfont->pfont); newpfont.info.isStringProp = NULL; newpfont.info.props = NULL; newbfont.pfont = &newpfont; err = StillWorking; } /* pull out the QueryXInfo reply */ memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply)); if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply), SIZEOF(fsQueryXInfoReply) - SIZEOF(fsGenericReply)) == -1) { if (bfont->flags & FontReopen) goto bail; fs_free_font(bfont); return StillWorking; } /* move the data over */ fsUnpack_XFontInfoHeader(&rep, &bfont->pfont->info); _fs_init_fontinfo(conn, &bfont->pfont->info); if (bfont->pfont->info.terminalFont) { bfont->format = (bfont->format & ~ (BitmapFormatImageRectMask)) | BitmapFormatImageRectMax; } if (_fs_read(conn, (char *) &pi, SIZEOF(fsPropInfo)) == -1) { if (bfont->flags & FontReopen) goto bail; fs_free_font(bfont); return StillWorking; } prop_len = pi.num_offsets * SIZEOF(fsPropOffset); po = (fsPropOffset *) xalloc(prop_len); pd = (pointer) xalloc(pi.data_len); if (!po || !pd) { xfree(pd); xfree(po); /* clear the wire */ (void) _fs_drain_bytes(conn, prop_len + pi.data_len); /* clean up the font */ if (bfont->flags & FontReopen) { err = AllocError ; goto bail; } (void) _fs_cleanup_font(bfont); return AllocError; } if (_fs_read_pad(conn, (char *) po, prop_len) == -1 || _fs_read_pad(conn, (char *) pd, pi.data_len) == -1) { xfree(pd); xfree(po); if (bfont->flags & FontReopen) goto bail; fs_free_font(bfont); return StillWorking; } if (_fs_convert_props(&pi, po, pd, &bfont->pfont->info) == -1) { xfree(po); xfree(pd); if (bfont->flags & FontReopen) { err = AllocError ; goto bail; } (void) _fs_cleanup_font(bfont); return AllocError; } xfree(po); xfree(pd); if (bfont->flags & FontReopen) { int i; err = BadFontName; /* We're reopening a font that we lost because of a downed connection. In the interest of avoiding corruption from opening a different font than the old one (we already have its metrics, extents, and probably some of its glyphs), verify that the metrics and properties all match. */ if (newpfont.info.firstCol != oldpfont->info.firstCol || newpfont.info.lastCol != oldpfont->info.lastCol || newpfont.info.firstRow != oldpfont->info.firstRow || newpfont.info.lastRow != oldpfont->info.lastRow || newpfont.info.defaultCh != oldpfont->info.defaultCh || newpfont.info.noOverlap != oldpfont->info.noOverlap || newpfont.info.terminalFont != oldpfont->info.terminalFont || newpfont.info.constantMetrics != oldpfont->info.constantMetrics || newpfont.info.constantWidth != oldpfont->info.constantWidth || newpfont.info.inkInside != oldpfont->info.inkInside || newpfont.info.inkMetrics != oldpfont->info.inkMetrics || newpfont.info.allExist != oldpfont->info.allExist || newpfont.info.drawDirection != oldpfont->info.drawDirection || newpfont.info.cachable != oldpfont->info.cachable || newpfont.info.anamorphic != oldpfont->info.anamorphic || newpfont.info.maxOverlap != oldpfont->info.maxOverlap || newpfont.info.fontAscent != oldpfont->info.fontAscent || newpfont.info.fontDescent != oldpfont->info.fontDescent || newpfont.info.nprops != oldpfont->info.nprops) goto bail;#define MATCH(xci1, xci2) \ (((xci1).leftSideBearing == (xci2).leftSideBearing) && \ ((xci1).rightSideBearing == (xci2).rightSideBearing) && \ ((xci1).characterWidth == (xci2).characterWidth) && \ ((xci1).ascent == (xci2).ascent) && \ ((xci1).descent == (xci2).descent) && \ ((xci1).attributes == (xci2).attributes)) if (!MATCH(newpfont.info.maxbounds, oldpfont->info.maxbounds) || !MATCH(newpfont.info.minbounds, oldpfont->info.minbounds) || !MATCH(newpfont.info.ink_maxbounds, oldpfont->info.ink_maxbounds) || !MATCH(newpfont.info.ink_minbounds, oldpfont->info.ink_minbounds)) goto bail;#undef MATCH for (i = 0; i < newpfont.info.nprops; i++) if (newpfont.info.isStringProp[i] != oldpfont->info.isStringProp[i] || newpfont.info.props[i].name != oldpfont->info.props[i].name || newpfont.info.props[i].value != oldpfont->info.props[i].value) goto bail; err = Successful; bail: if (err != Successful && err != StillWorking) { /* Failure. Close the font. */ fs_send_close_font(((FSFontDataPtr)oldpfont->fpePrivate)->fpe, bfont->fontid); ((FSFontDataPtr)oldpfont->fpePrivate)->generation = -1; } xfree(newpfont.info.isStringProp); xfree(newpfont.info.props); if (err == Successful) oldbfont->state = FS_DONE_REPLY; return err; } if (glyphCachingMode == CACHING_OFF || glyphCachingMode == CACHE_16_BIT_GLYPHS && !bfont->pfont->info.lastRow) bfont->flags |= FontLoadAll; bfont->state = FS_EXTENT_REPLY; fs_send_query_extents(fpe, blockrec); return StillWorking;}static intfs_read_extent_info(fpe, blockrec) FontPathElementPtr fpe; FSBlockDataPtr blockrec;{ FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; FSFontDataPtr fsd = (FSFontDataPtr) bfont->pfont->fpePrivate; FSFpePtr conn = (FSFpePtr) fpe->private; fsQueryXExtents16Reply rep; int i; int numInfos; Bool haveInk = FALSE; /* need separate ink metrics? */ CharInfoPtr ci, pCI; FSFontPtr fsfont = (FSFontPtr) bfont->pfont->fontPrivate; fsXCharInfo *fsci; fsXCharInfo fscilocal; pointer fscip; /* read the QueryXExtents reply */ memcpy(&rep, &blockrec->header, SIZEOF(fsGenericReply)); if (_fs_read(conn, (char *) &rep + SIZEOF(fsGenericReply), SIZEOF(fsQueryXExtents16Reply) - SIZEOF(fsGenericReply)) == -1) { fs_free_font(bfont); return StillWorking; } /* move the data over */ /* need separate inkMetrics for fixed font server protocol version */ numInfos = rep.num_extents; if (bfont->pfont->info.terminalFont && conn->fsMajorVersion > 1) { numInfos *= 2; haveInk = TRUE; } ci = pCI = (CharInfoPtr) xalloc(sizeof(CharInfoRec) * numInfos);/* XXX this could be done with an ALLOCATE_LOCAL */ fsci = (fsXCharInfo *) xalloc(SIZEOF(fsXCharInfo) * rep.num_extents); if (!pCI || !fsci) { xfree(pCI); xfree(fsci); /* clear the unusable data */ _fs_drain_bytes(conn, SIZEOF(fsXCharInfo) * rep.num_extents); _fs_cleanup_font(bfont); return AllocError; } fsfont->encoding = pCI; if (haveInk) fsfont->inkMetrics = pCI + rep.num_extents;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -