ncurses disabled showing cursur in bash - linux

I wrote a program that i used ncurses library, i used, keys menu windows and other its facilities.
I run my program without any error.
After quit program, i can't see any input data (certainly same you run passwd command and wanna input new password), for example if you run ls, i can see output of ls(list of current dir) , but i can't see ls word.
How i solve this problem?
piece of my code:
WINDOW *menu_win,*qmenu_win,*amenu_win,*smenu_win;
char *query;
char *fields;
WriteFile *writePtr = new WriteFile();
ReadFile *readPtr = new ReadFile();
int highlight = 1;
int choice = 0;
int c;
initscr();
clear();
noecho();
cbreak(); /* Line buffering disabled. pass on everything */
startx = (80 - WIDTH) / 2;
starty = (24 - HEIGHT) / 2;
menu_win = newwin(HEIGHT, WIDTH, starty, startx);
keypad(menu_win, TRUE);
mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice");
refresh();
print_menu(menu_win, highlight);
while (true)

Make sure your program calls endwin() before exiting. Otherwise, the state of the terminal may not be restored.

When this happens, type reset at your prompt.
Also be aware that problems may be due to your terminal program itself. If it does not properly emulate the terminal it claims to emulate, you will run into problems.
Or it could be a bug with your program: maybe you need to replace noecho with echo?

Related

Moving windows in ncurses

I've read window(3NCURSES) man page, but I can't fully understand what mvwin() function actually does and what happens to its subwindows.
The code below creates a window with a title "Window" and a border, it also creates a subwindow that is used for printing y,x position without corrupting parent window border. It then moves the parent window to a new location, but the result is not what I expected:
After the window is moved, the outline of the windows border + text is not automatically erased at the old location.
After the move, writing text to a subwindow, outputs it at the old and new location.
After the move, parent window has new y,x coordinates, but subwindow still shows old coordinates.
I don't have a lot of experience with ncurses, and maybe I'm missing something, but this behaviour is completely illogical. If I have to manually erase windows at old location and manually move all subwindows, then this negates the benefit of using ncurses in the first place. I was expecting ncurses to automatically handle these low-level details.
My understanding of subwindows was that they are used to partition one large window into smaller non-overlapping areas. So when the parent window is moved or refreshed, all its subwindows should be moved or refreshed automatically. Is this correct?
#include <assert.h>
#include <ncurses.h>
#include <unistd.h>
int main()
{
WINDOW *win, *swin;
int lines, cols, y, x;
initscr();
keypad(stdscr, TRUE);
noecho();
// Create window
lines = 10; cols = 40;
y = 5; x = 5;
win = newwin(lines, cols, y, x);
assert(win != NULL);
// Create window border
box(win, 0, 0);
mvwprintw(win, 0, 2, " Window ");
// Create subwindow
swin = subwin(win, lines-2, cols-2, y+1, x+1);
assert(swin != NULL);
// Print window and subwindow y,x
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
sleep(2);
// Move window
y = 20; x = 40;
mvwin(win, y, x);
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
wgetch(swin);
endwin();
return 0;
}
Apparently not: a quick check with Solaris 10 gives the same behavior. You might find some scenario where ncurses differs unintentionally, but this is not one of those. The FAQ makes this point about compatibility:
extensions (deviations from SVr4 curses) are allowed only if they do not modify the documented/observed behavior of the API.
The Solaris manual page does not make this clear, since the only mention of subwindows is in regard to moving them:
The mvwin() routine moves the window so that the upper left-hand corner is at position (x, y). If the move would cause the window to be off the screen, it is an error and the window is not moved. Moving subwindows is allowed, but should be avoided.
The Solaris source code tells the story for that: it does nothing with subwindows. Some retesting a while back (early 2006) in response to a user's comment about differences pointed out that ncurses was incorrectly attempting to copy subwindows. That part is ifdef'd out (since it's too interesting to just delete). Since there's not much left for mvwin to do, the actual code is fairly similar.
X/Open's description of mvwin is too brief and vague to be of any use.

proper way of catching control+key in ncurses

What is the proper way of catching a control+key in ncurses?
current im doing it defining control like this:
#define ctl(x) ((x) & 0x1f)
it works ok, but the problem is that i cannot catch C-j and ENTER at the same time, and this is because:
j = 106 = 1101010
0x1f = 31 = 0011111
1101010 & 0011111 = 0001010 = 10 = ENTER key..
So.. how shall I catch it?
Thanks!
--
Edit:
If i try the code below,
I am not able to catch the enter key correctly, not even in the numeric keyboard. Enter gets catched as ctrl-j.
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int c = getch();
nonl();
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
getch();
endwin();
return;
}
New code:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int main(void) {
initscr();
int l = -1;
int c = getch();
cbreak();
noecho();
nonl();
keypad(stdscr, TRUE);
switch (c) {
case KEY_ENTER:
printw("key: %c", c);
break;
case ctrl('j'):
printw("key: ctrl j");
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return;
}
Try nonl:
The nl and nonl routines control whether the underlying display device
translates the return key into newline on input, and whether it translates newline into return and line-feed on output (in either case, the
call addch('\n') does the equivalent of return and line feed on the
virtual screen). Initially, these translations do occur. If you disable them using nonl, curses will be able to make better use of the
line-feed capability, resulting in faster cursor motion. Also, curses
will then be able to detect the return key.
Further reading: the Notes section of the getch manual page:
Generally, KEY_ENTER denotes the character(s) sent by the Enter key on
the numeric keypad:
the terminal description lists the most useful keys,
the Enter key on the regular keyboard is already handled by the
standard ASCII characters for carriage-return and line-feed,
depending on whether nl or nonl was called, pressing "Enter" on the
regular keyboard may return either a carriage-return or line-feed,
and finally
"Enter or send" is the standard description for this key.
That addresses the question about newline/carriage-return translation. A followup comment is a reminder to point out that the manual page gives basic advice in the Initialization section:
To get character-at-a-time input without echoing (most interactive,
screen oriented programs want this), the following sequence should be
used:
initscr(); cbreak(); noecho();
and that OP's sample program did not use cbreak (or raw). The manual page for cbreak says
Normally, the tty driver buffers typed characters until a newline or
carriage return is typed. The cbreak routine disables line buffering
and erase/kill character-processing (interrupt and flow control characters are unaffected), making characters typed by the user immediately
available to the program. The nocbreak routine returns the terminal to
normal (cooked) mode.
Initially the terminal may or may not be in cbreak mode, as the mode is
inherited; therefore, a program should call cbreak or nocbreak explicitly. Most interactive programs using curses set the cbreak mode.
Note that cbreak overrides raw. (See curs_getch(3x) for a discussion
of how these routines interact with echo and noecho.)
Also, in curs_getch you may read
If keypad is TRUE, and a function key is pressed, the token for that
function key is returned instead of the raw characters:
The predefined function keys are listed in <curses.h> as macros
with values outside the range of 8-bit characters. Their names begin with KEY_.
That is, curses will only return KEY_ENTER if the program calls keypad:
keypad(stdscr, TRUE);
For the sake of discussion, here is an example fixing some of the problems with your sample program as of May 17:
#include <stdio.h>
#include <ncurses.h>
#define ctrl(x) ((x) & 0x1f)
int
main(void)
{
int c;
initscr();
keypad(stdscr, TRUE);
cbreak();
noecho();
nonl();
c = getch();
switch (c) {
case KEY_ENTER:
printw("\nkey_enter: %d", c);
break;
case ctrl('j'):
printw("\nkey: ctrl j");
break;
default:
printw("\nkeyname: %d = %s\n", c, keyname(c));
break;
}
printw("\nnow press a key to end");
getch();
endwin();
return 0;
}
That is, you have to call keypad before getch, and the value returned for KEY_ENTER is not a character (it cannot be printed with %c).
Running on the Linux console with the usual terminal description, you will see only carriage return for the numeric keypad Enter, because that description does not use application mode. Linux console does support application mode, and a corresponding description could be written. As a quick check (there are differences...) you could set TERM=vt100 to see the KEY_ENTER.

How to set carriage return location or equivalent?

I am looking for a way to set where the carriage return, returns to or an equivalent way to do so.
For example I have a line like this:
^ denotes cursor location
myshell>cat file.txt
^
After carriage return it should look like this.
myshell>cat file.txt
^
You're probably after what's collectively called ANSI escape sequences. Its hard to search for if you really have no idea what you're after.
This tiny example saves/restores cursor position:
#include <stdio.h>
int main(int argc, char**argv)
{
char cmd_buf[100];
cmd_buf[0]=0;
while(strncmp(cmd_buf, "quit", 4))
{
printf("mypromt>\033[s <-Cursor should go there\033[u");
fflush(stdout);
fgets(cmd_buf, sizeof(cmd_buf), stdin);
printf("\nYou entered: %s\n", cmd_buf);
}
}
Note that in terminator, gnome-terminal and xterm on Ubuntu, this "magically" supports CTRL+U as-is, but not CTRL+A or CTRL+E.
There are many, many more sequences available. The wikipedia page is probably the simplest reference to get you started.
Update: Also, unless you're doing this as a learning exercise (which I get the impression Benjamin is), to build an interactive shell, you should probably use one of the two well established libraries for shell-style line editing, namely:
readline (GPLv3, but far more popular)
editline (BSD licensed, closest "second place")
They are the libraries that provide the emacs-style (typical default) and vi-style keybindings and history features we all know and love from bash, python, lua, perl, node, etc, etc.
For positioning on the screen, termios is of limited use (the ioctl's dealing with screensize are not in POSIX), and unless you want to assume a lot about the terminal characteristics, control characters and escape sequences have their limitations.
You can do what's asked in curses using the filter function to tell the library you want to use just the current line of the display. As written, the question is puzzling since it does not mention any output other than the current line. But for example (this is exactly what was asked):
#include <curses.h>
int
main(void)
{
int ch, y, x;
filter();
initscr();
cbreak();
addstr("myshell>");
getyx(stdscr, y, x);
while ((ch = getch()) != ERR) {
if (ch == '\n')
move(y, x);
}
endwin();
return 0;
}
However, a usable program would do more than that. There's an example of the filter() function in ncurses-examples, which you may find useful for reading. A screenshot:

Ncurses: F1-F5 keys

I have a Probclem with functions keys in curses.h.
I have this littel programm seen on different websites/tutorials
#include <ncurses.h>
int main()
{ int ch;
initscr(); /* Start curses mode */
raw(); /* Line buffering disabled */
keypad(stdscr, TRUE); /* We get F1, F2 etc.. */
noecho(); /* Don't echo() while we do getch */
printw("Type any character to see it in bold\n");
ch = getch();
while (ch != KEY_F(1))
{
if(ch == KEY_F(1))
printw("F1 Key pressed: Ending program.\n");
else
{ printw("The pressed key is ");
attron(A_BOLD);
printw("%c\n", ch);
attroff(A_BOLD);
}
refresh();
ch = getch();
}
printw("end\n");
endwin(); /* End curses mode */
return 0;
}
The keys F6-F12 works fine and the code which is returned is also fine (for example: 270 if F6 ist pressed). But if I press F5 not 269 is returned, like it would be supposed to be, instead the following is happening (only by pressing F5 once):
Type any character to see it in bold
The pressed key is ^[
27
The pressed key is [
91
The pressed key is 1
49
The pressed key is 5
53
The pressed key is ~
126
So I think the whole Escape Sequence ist returned. I read on the internet about this problem and two times there was a hint which describes to change the TERM variable to xterm or vt100. So I tried to change TERM to vt 220 and also xterm, but nothing change. When i changed it to vt100 also F6-F12 didn't work.
Can anybody help me how I can recognize if the user presses F1-F5? Keys like enter, Backspace, up, down, etc. are recognized fine.
best regards
Sounds like a disagreement between what terminfo says your terminal sends and what it actually does. May be the result of an incorrect terminfo file on the target machine, or the wrong $TERM setting, or any number of things.
I'd start by comparing what
$ infocmp -L
says on the target machine, as compared what the terminal actually sends when running, say, cat.
If you are running xterm, maybe you have a ~/.Xresources file translating your function keys. VMS users often would remap F1 - F5 keys that way. Also many terminal emulators (like Putty) have options to remap these keys.

In KDE, how can I automatically tell which "Desktop" a Konsole terminal is in?

I have multiple "desktops" that I switch between for different tasks in my KDE Linux environment. How can I automagically determine which desktop my Konsole ( kde console) window is being displayed in?
EDIT:
I'm using KDE 3.4 in a corporate environment
This is programming related. I need to programatically (a.k.a. automagically ) determine which desktop a user is on and then interact with X windows in that desktop from a python script.
Should I go around and nuke all Microsoft IDE questions as not programming related? How about Win32 "programming" questions? Should I try to close those too?
Actually EWMH _NET_CURRENT_DESKTOP gives you which is the current desktop for X, not relative to the application. Here's a C snippet to get the _WM_DESKTOP of an application. If run from the KDE Konsole in question it will give you what desktop it is on, even it is not the active desktop or not in focus.
#include <X11/Xlib.h>
#include <X11/Shell.h>
...
Atom net_wm_desktop = 0;
long desktop;
Status ret;
/* see if we've got a desktop atom */
Atom net_wm_desktop = XInternAtom( display, "_NET_WM_DESKTOP", False);
if( net_wm_desktop == None ) {
return;
}
/* find out what desktop we're currently on */
if ( XGetWindowProperty(display, window, net_wm_desktop, 0, 1,
False, XA_CARDINAL, (Atom *) &type_ret, &fmt_ret,
&nitems_ret, &bytes_after_ret,
(unsigned char**)&data) != Success || data == NULL
) {
fprintf(stderr, "XGetWindowProperty() failed");
if ( data == NULL ) {
fprintf(stderr, "No data returned from XGetWindowProperty()" );
}
return;
}
desktop = *data;
XFree(data);
and desktop should be the index of the virtual desktop the Konsole is currently in. That is not the same which head of a multi-headed display. If you want to determine which head, you need to use XineramaQueryScreens (Xinerama extension, not sure if there is a XRandR equivalent or not. Does not work for nVidia's TwinView.
Here's an excerpt from some code I wrote, that given a x and y, calculate the screen boundaries (sx, sy, and sw with screen width and sh for screen height). You can easily adapt it to simply return which "screen" or head x and y are on. (Screen has a special meaning in X11).
#include <X11/X.h>
#include <X11/extensions/Xinerama.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
Bool xy2bounds(Display* d,int x, int y, int* sx, int* sy, int* sw, int* sh) {
*sx = *sy = *sw = *sh = -1; /* Set to invalid, for error condition */
XineramaScreenInfo *XinInfo;
int xin_screens = -1;
int i;
int x_origin, y_origin, width, height;
Bool found = False;
if ( d == NULL )
return False;
if ( (x < 0) || (y < 0) )
return False;
if ( True == XineramaIsActive(d) ) {
XinInfo = XineramaQueryScreens( d, &xin_screens );
if ( (NULL == XinInfo) || (0 == xin_screens) ) {
return False;
}
} else {
/* Xinerama is not active, so return usual width/height values */
*sx = 0;
*sy = 0;
*sw = DisplayWidth( d, XDefaultScreen(d) );
*sh = DisplayHeight( d, XDefaultScreen(d) );
return True;
}
for ( i = 0; i < xin_screens; i++ ) {
x_origin = XinInfo[i].x_org;
y_origin = XinInfo[i].y_org;
width = XinInfo[i].width;
height = XinInfo[i].height;
printf("Screens: (%d) %dx%d - %dx%d\n", i,
x_origin, y_origin, width, height );
if ( (x >= x_origin) && (y >= y_origin) ) {
if ( (x <= x_origin+width) && (y <= y_origin+height) ) {
printf("Found Screen[%d] %dx%d - %dx%d\n",
i, x_origin, y_origin, width, height );
*sx = x_origin;
*sy = y_origin;
*sw = width;
*sh = height;
found = True;
break;
}
}
}
assert( found == True );
return found;
}
Referring to the accepted answer.... dcop is now out of date; instead of dcop you might want to use dbus (qdbus is a command line tool for dbus).
qdbus org.kde.kwin /KWin currentDesktop
The KDE window manager, as well as GNOME and all WMs that follow the freedesktop standards support the Extended Window Manager Hints (EWMH).
These hints allow developers to access programmatically several window manager functions like maximize, minimize, set window title, virtual desktop e.t.c
I have never worked with KDE but Gnome provides such functionality so I assume that KDE has it too.
It is also possible to access a subset of these hints with pure Xlib functions. This subset are ICCCM hints. If memory serves me correct virtual desktop access is only in EWMH.
Update: Found it! (_NET_CURRENT_DESKTOP)
With dcop, the kde Desktop COmmunication Protocol, you could easily get current desktop executing
dcop kwin KWinInterface currentDesktop
command. If you are working with new kde 4.x dcop is no more used, and you can translate the command to a DBUS call. It should be quite simple to send/get dbous messages with python apis.
Sorry for my bad english,
Emilio
A new answer because MOST of the answers here get the current desktop, not the one the terminal is in (Will break if user changes desktop while script is running).
xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg'
I tested this in a loop while changing desktops, it works ok (test script bellow, you have to check the output manually after the run).
while true
do
xprop -id $WINDOWID | sed -rn -e 's/_NET_WM_DESKTOP\(CARDINAL\) = ([^)]+)/\1/pg'
sleep 1
done
Thanks for the other answers and comments, for getting me half way there.
I was looking for the same thing, but with one more restriction, I don't want to run a shell command to achieve the result. Starting from Kimball Robinson answer, this is what I got.
Tested working in Python3.7, Debian 10.3, KDE Plasma 5.14.5.
import dbus
bus = dbus.SessionBus()
proxy = bus.get_object("org.kde.KWin", "/KWin")
int( proxy.currentDesktop(dbus_interface="org.kde.KWin") )

Resources