summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-10-14 10:00:17 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-10-14 10:00:17 (GMT)
commit457456e2e721dd032dfed9ed2a6c851536a24b66 (patch)
treed295c1b0416dcf73a670622da6e346755f54de76 /unix
parent5e9592bc08da2424a5b180e1ee18f0ba564c672f (diff)
downloadtk-457456e2e721dd032dfed9ed2a6c851536a24b66.zip
tk-457456e2e721dd032dfed9ed2a6c851536a24b66.tar.gz
tk-457456e2e721dd032dfed9ed2a6c851536a24b66.tar.bz2
Fix [8ebed330ed]: doing some Tk inside of several threads crashes
Diffstat (limited to 'unix')
-rw-r--r--unix/tkUnixRFont.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c
index 226445c..8eb6f53 100644
--- a/unix/tkUnixRFont.c
+++ b/unix/tkUnixRFont.c
@@ -53,6 +53,10 @@ typedef struct {
Region clipRegion; /* The clipping region, or None. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
+
+TCL_DECLARE_MUTEX(xftMutex);
+#define LOCK Tcl_MutexLock(&xftMutex)
+#define UNLOCK Tcl_MutexUnlock(&xftMutex)
/*
* Package initialization:
@@ -122,7 +126,9 @@ GetFont(
if (angle != 0.0) {
FcPatternAddMatrix(pat, FC_MATRIX, &mat);
}
+ LOCK;
ftFont = XftFontOpenPattern(fontPtr->display, pat);
+ UNLOCK;
if (!ftFont) {
/*
* The previous call to XftFontOpenPattern() should not fail, but
@@ -131,11 +137,13 @@ GetFont(
* fallback:
*/
+ LOCK;
ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
FC_FAMILY, FcTypeString, "sans",
FC_SIZE, FcTypeDouble, 12.0,
FC_MATRIX, FcTypeMatrix, &mat,
NULL);
+ UNLOCK;
}
if (!ftFont) {
/*
@@ -150,7 +158,9 @@ GetFont(
fontPtr->faces[i].ft0Font = ftFont;
} else {
if (fontPtr->faces[i].ftFont) {
+ LOCK;
XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
+ UNLOCK;
}
fontPtr->faces[i].ftFont = ftFont;
fontPtr->faces[i].angle = angle;
@@ -409,10 +419,14 @@ FinishedWithFont(
for (i = 0; i < fontPtr->nfaces; i++) {
if (fontPtr->faces[i].ftFont) {
+ LOCK;
XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
+ UNLOCK;
}
if (fontPtr->faces[i].ft0Font) {
+ LOCK;
XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);
+ UNLOCK;
}
if (fontPtr->faces[i].charset) {
FcCharSetDestroy(fontPtr->faces[i].charset);
@@ -751,7 +765,9 @@ Tk_MeasureChars(
ftFont = GetFont(fontPtr, c, 0.0);
if (!errorFlag) {
+ LOCK;
XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
+ UNLOCK;
} else {
extents.xOff = 0;
errorFlag = 0;
@@ -962,8 +978,10 @@ Tk_DrawChars(
ftFont = GetFont(fontPtr, c, 0.0);
if (ftFont) {
specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
+ LOCK;
XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
&metrics);
+ UNLOCK;
/*
* Draw glyph only when it fits entirely into 16 bit coords.
@@ -976,8 +994,10 @@ Tk_DrawChars(
specs[nspec].x = x;
specs[nspec].y = y;
if (++nspec == NUM_SPEC) {
+ LOCK;
XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
specs, nspec);
+ UNLOCK;
nspec = 0;
}
}
@@ -986,7 +1006,9 @@ Tk_DrawChars(
}
}
if (nspec) {
+ LOCK;
XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
+ UNLOCK;
}
doUnderlineStrikeout:
@@ -1113,8 +1135,11 @@ TkDrawAngledChars(
* this information... but we'll be ready when it does!
*/
+ LOCK;
XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
nglyph, &metrics);
+ UNLOCK;
+
/*
* Draw glyph only when it fits entirely into 16 bit coords.
*/
@@ -1137,8 +1162,10 @@ TkDrawAngledChars(
* a very small barely readable font)
*/
+ LOCK;
XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
originX, originY, glyphs, nglyph);
+ UNLOCK;
}
}
originX = ROUND16(x);
@@ -1148,8 +1175,10 @@ TkDrawAngledChars(
glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
}
if (nglyph) {
+ LOCK;
XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
nglyph, &metrics);
+ UNLOCK;
/*
* Draw glyph only when it fits entirely into 16 bit coords.
@@ -1158,8 +1187,10 @@ TkDrawAngledChars(
if (x >= minCoord && y >= minCoord &&
x <= maxCoord - metrics.width &&
y <= maxCoord - metrics.height) {
+ LOCK;
XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
originX, originY, glyphs, nglyph);
+ UNLOCK;
}
}
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
@@ -1207,8 +1238,10 @@ TkDrawAngledChars(
ft0Font = GetFont(fontPtr, c, 0.0);
if (ftFont && ft0Font) {
specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
+ LOCK;
XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
&metrics);
+ UNLOCK;
/*
* Draw glyph only when it fits entirely into 16 bit coords.
@@ -1221,8 +1254,10 @@ TkDrawAngledChars(
specs[nspec].x = ROUND16(x);
specs[nspec].y = ROUND16(y);
if (++nspec == NUM_SPEC) {
+ LOCK;
XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
specs, nspec);
+ UNLOCK;
nspec = 0;
}
}
@@ -1231,7 +1266,9 @@ TkDrawAngledChars(
}
}
if (nspec) {
+ LOCK;
XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
+ UNLOCK;
}
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */