From 438cd73fffcaf7370fbf0ed6d4a9759fe3f0de98 Mon Sep 17 00:00:00 2001 From: Krunal Patel Date: Wed, 16 Nov 2022 14:03:07 +0530 Subject: [PATCH] Added|Changed: Fill `.ws_xpixel` and `.ws_ypixel` in `winsize` This allows to get terminal size in pixel using `TIOCGWINSZ` ioctl. Set `.ws_xpixel` using `columns * cell_width` and set `.ws_ypixel` using `rows * cell_height`. Cell width and height is font width and line spacing, respectively. --- .../src/main/java/com/termux/terminal/JNI.java | 4 ++-- .../com/termux/terminal/TerminalSession.java | 14 +++++++------- terminal-emulator/src/main/jni/termux.c | 16 ++++++++++------ .../main/java/com/termux/view/TerminalView.java | 2 +- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/terminal-emulator/src/main/java/com/termux/terminal/JNI.java b/terminal-emulator/src/main/java/com/termux/terminal/JNI.java index 99229a6528..e2fc477b91 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/JNI.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/JNI.java @@ -23,10 +23,10 @@ final class JNI { * @return the file descriptor resulting from opening /dev/ptmx master device. The sub process will have opened the * slave device counterpart (/dev/pts/$N) and have it as stdint, stdout and stderr. */ - public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId, int rows, int columns); + public static native int createSubprocess(String cmd, String cwd, String[] args, String[] envVars, int[] processId, int rows, int columns, int cellWidth, int cellHeight); /** Set the window size for a given pty, which allows connected programs to learn how large their screen is. */ - public static native void setPtyWindowSize(int fd, int rows, int cols); + public static native void setPtyWindowSize(int fd, int rows, int cols, int cellWidth, int cellHeight); /** * Causes the calling thread to wait for the process associated with the receiver to finish executing. diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java index c081108d8f..33f1b355b4 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalSession.java @@ -21,7 +21,7 @@ * A terminal session, consisting of a process coupled to a terminal interface. *

* The subprocess will be executed by the constructor, and when the size is made known by a call to - * {@link #updateSize(int, int)} terminal emulation will begin and threads will be spawned to handle the subprocess I/O. + * {@link #updateSize(int, int, int, int)} terminal emulation will begin and threads will be spawned to handle the subprocess I/O. * All terminal emulation and callback methods will be performed on the main thread. *

* The child process may be exited forcefully by using the {@link #finishIfRunning()} method. @@ -61,7 +61,7 @@ public final class TerminalSession extends TerminalOutput { /** * The file descriptor referencing the master half of a pseudo-terminal pair, resulting from calling - * {@link JNI#createSubprocess(String, String, String[], String[], int[], int, int)}. + * {@link JNI#createSubprocess(String, String, String[], String[], int[], int, int, int, int)}. */ private int mTerminalFileDescriptor; @@ -100,11 +100,11 @@ public void updateTerminalSessionClient(TerminalSessionClient client) { } /** Inform the attached pty of the new size and reflow or initialize the emulator. */ - public void updateSize(int columns, int rows) { + public void updateSize(int columns, int rows, int fontWidth, int fontHeight) { if (mEmulator == null) { - initializeEmulator(columns, rows); + initializeEmulator(columns, rows, fontWidth, fontHeight); } else { - JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns); + JNI.setPtyWindowSize(mTerminalFileDescriptor, rows, columns, fontWidth, fontHeight); mEmulator.resize(columns, rows); } } @@ -120,11 +120,11 @@ public String getTitle() { * @param columns The number of columns in the terminal window. * @param rows The number of rows in the terminal window. */ - public void initializeEmulator(int columns, int rows) { + public void initializeEmulator(int columns, int rows, int cellWidth, int cellHeight) { mEmulator = new TerminalEmulator(this, columns, rows, mTranscriptRows, mClient); int[] processId = new int[1]; - mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns); + mTerminalFileDescriptor = JNI.createSubprocess(mShellPath, mCwd, mArgs, mEnv, processId, rows, columns, cellWidth, cellHeight); mShellPid = processId[0]; mClient.setTerminalShellPid(this, mShellPid); diff --git a/terminal-emulator/src/main/jni/termux.c b/terminal-emulator/src/main/jni/termux.c index 22f1d507d1..8cd5e7891d 100644 --- a/terminal-emulator/src/main/jni/termux.c +++ b/terminal-emulator/src/main/jni/termux.c @@ -29,7 +29,9 @@ static int create_subprocess(JNIEnv* env, char** envp, int* pProcessId, jint rows, - jint columns) + jint columns, + jint cell_width, + jint cell_height) { int ptm = open("/dev/ptmx", O_RDWR | O_CLOEXEC); if (ptm < 0) return throw_runtime_exception(env, "Cannot open /dev/ptmx"); @@ -57,7 +59,7 @@ static int create_subprocess(JNIEnv* env, tcsetattr(ptm, TCSANOW, &tios); /** Set initial winsize. */ - struct winsize sz = { .ws_row = (unsigned short) rows, .ws_col = (unsigned short) columns }; + struct winsize sz = { .ws_row = (unsigned short) rows, .ws_col = (unsigned short) columns, .ws_xpixel = (unsigned short) (columns * cell_width), .ws_ypixel = (unsigned short) (rows * cell_height)}; ioctl(ptm, TIOCSWINSZ, &sz); pid_t pid = fork(); @@ -121,7 +123,9 @@ JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess( jobjectArray envVars, jintArray processIdArray, jint rows, - jint columns) + jint columns, + jint cell_width, + jint cell_height) { jsize size = args ? (*env)->GetArrayLength(env, args) : 0; char** argv = NULL; @@ -156,7 +160,7 @@ JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess( int procId = 0; char const* cmd_cwd = (*env)->GetStringUTFChars(env, cwd, NULL); char const* cmd_utf8 = (*env)->GetStringUTFChars(env, cmd, NULL); - int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId, rows, columns); + int ptm = create_subprocess(env, cmd_utf8, cmd_cwd, argv, envp, &procId, rows, columns, cell_width, cell_height); (*env)->ReleaseStringUTFChars(env, cmd, cmd_utf8); (*env)->ReleaseStringUTFChars(env, cmd, cmd_cwd); @@ -178,9 +182,9 @@ JNIEXPORT jint JNICALL Java_com_termux_terminal_JNI_createSubprocess( return ptm; } -JNIEXPORT void JNICALL Java_com_termux_terminal_JNI_setPtyWindowSize(JNIEnv* TERMUX_UNUSED(env), jclass TERMUX_UNUSED(clazz), jint fd, jint rows, jint cols) +JNIEXPORT void JNICALL Java_com_termux_terminal_JNI_setPtyWindowSize(JNIEnv* TERMUX_UNUSED(env), jclass TERMUX_UNUSED(clazz), jint fd, jint rows, jint cols, jint cell_width, jint cell_height) { - struct winsize sz = { .ws_row = (unsigned short) rows, .ws_col = (unsigned short) cols }; + struct winsize sz = { .ws_row = (unsigned short) rows, .ws_col = (unsigned short) cols, .ws_xpixel = (unsigned short) (cols * cell_width), .ws_ypixel = (unsigned short) (rows * cell_height) }; ioctl(fd, TIOCSWINSZ, &sz); } diff --git a/terminal-view/src/main/java/com/termux/view/TerminalView.java b/terminal-view/src/main/java/com/termux/view/TerminalView.java index b00d3aa06b..ab0bca0920 100644 --- a/terminal-view/src/main/java/com/termux/view/TerminalView.java +++ b/terminal-view/src/main/java/com/termux/view/TerminalView.java @@ -975,7 +975,7 @@ public void updateSize() { int newRows = Math.max(4, (viewHeight - mRenderer.mFontLineSpacingAndAscent) / mRenderer.mFontLineSpacing); if (mEmulator == null || (newColumns != mEmulator.mColumns || newRows != mEmulator.mRows)) { - mTermSession.updateSize(newColumns, newRows); + mTermSession.updateSize(newColumns, newRows, (int) mRenderer.getFontWidth(), mRenderer.getFontLineSpacing()); mEmulator = mTermSession.getEmulator(); mClient.onEmulatorSet();