Skip to content

Commit

Permalink
Merge pull request #12313 from iq2luc/fix-xlibi18n-segfault
Browse files Browse the repository at this point in the history
Fix segfault on Linux when typing in a TexBox
  • Loading branch information
kekekeks authored Jul 25, 2023
2 parents f03b9c6 + c834b04 commit fc12649
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 15 deletions.
20 changes: 17 additions & 3 deletions src/Avalonia.X11/X11Info.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ internal unsafe class X11Info
public bool HasXim { get; set; }
public bool HasXSync { get; set; }
public IntPtr DefaultFontSet { get; set; }


[DllImport("libc")]
private static extern void setlocale(int type, string s);

public unsafe X11Info(IntPtr display, IntPtr deferredDisplay, bool useXim)
{
Display = display;
Expand All @@ -48,7 +51,10 @@ public unsafe X11Info(IntPtr display, IntPtr deferredDisplay, bool useXim)

DefaultFontSet = XCreateFontSet(Display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
out var _, out var _, IntPtr.Zero);


// We have problems with text input otherwise
setlocale(0, "");

if (useXim)
{
XSetLocaleModifiers("");
Expand All @@ -59,7 +65,15 @@ public unsafe X11Info(IntPtr display, IntPtr deferredDisplay, bool useXim)

if (Xim == IntPtr.Zero)
{
XSetLocaleModifiers("@im=none");
if (XSetLocaleModifiers("@im=none") == IntPtr.Zero)
{
setlocale(0, "en_US.UTF-8");
if (XSetLocaleModifiers("@im=none") == IntPtr.Zero)
{
setlocale(0, "C.UTF-8");
XSetLocaleModifiers("@im=none");
}
}
Xim = XOpenIM(display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}

Expand Down
10 changes: 3 additions & 7 deletions src/Avalonia.X11/X11Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ internal class AvaloniaX11Platform : IWindowingPlatform
public IntPtr OrphanedWindow { get; private set; }
public X11Globals Globals { get; private set; }
public ManualRawEventGrouperDispatchQueue EventGrouperDispatchQueue { get; } = new();
[DllImport("libc")]
private static extern void setlocale(int type, string s);

public void Initialize(X11PlatformOptions options)
{
Options = options;

bool useXim = false;
if (EnableIme(options))
{
Expand All @@ -50,9 +49,6 @@ public void Initialize(X11PlatformOptions options)
useXim = true;
}

// We have problems with text input otherwise
setlocale(0, "");

XInitThreads();
Display = XOpenDisplay(IntPtr.Zero);
if (Display == IntPtr.Zero)
Expand All @@ -64,7 +60,7 @@ public void Initialize(X11PlatformOptions options)
OrphanedWindow = XCreateSimpleWindow(Display, XDefaultRootWindow(Display), 0, 0, 1, 1, 0, IntPtr.Zero,
IntPtr.Zero);
XError.Init();

Info = new X11Info(Display, DeferredDisplay, useXim);
Globals = new X11Globals(this);
//TODO: log
Expand Down
15 changes: 11 additions & 4 deletions src/Avalonia.X11/X11Window.Ime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,21 @@ private unsafe string TranslateEventToString(ref XEvent ev)
{
if (ImeBuffer == IntPtr.Zero)
ImeBuffer = Marshal.AllocHGlobal(ImeBufferSize);

var len = Xutf8LookupString(_xic, ref ev, ImeBuffer.ToPointer(), ImeBufferSize,
out _, out var istatus);
var status = (XLookupStatus)istatus;

IntPtr istatus;
int len;
if(_xic != IntPtr.Zero)
len = Xutf8LookupString(_xic, ref ev, ImeBuffer.ToPointer(),
ImeBufferSize, out _, out istatus);
else
len = XLookupString(ref ev, ImeBuffer.ToPointer(), ImeBufferSize,
out _, out istatus);

if (len == 0)
return null;

var status = (XLookupStatus)istatus;

string text;
if (status == XLookupStatus.XBufferOverflow)
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.X11/XLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ public enum XLookupStatus : uint
public static extern unsafe int XLookupString(ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);

[DllImport (libX11)]
public static extern unsafe int Xutf8LookupString(IntPtr xic, ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out UIntPtr status);
public static extern unsafe int Xutf8LookupString(IntPtr xic, ref XEvent xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);

[DllImport (libX11)]
public static extern unsafe int Xutf8LookupString(IntPtr xic, XEvent* xevent, void* buffer, int num_bytes, out IntPtr keysym, out IntPtr status);
Expand Down

0 comments on commit fc12649

Please sign in to comment.