wgetch is not detecting KEY_UP etc - ncurses

I have enabled keypad for my_win and yet when I press KEY_UP after running the program, nothing happens. The stranger thing is that it works completely fine with stdscr. It appears to only be an issue with my_win.
/* Selects different elements of the list */
while ((ch = wgetch(my_win)) != 'q')
{
sprintf(item, "%-12s", list[i]);
mvwprintw(my_win, i + 1, 2, "%s", item);
switch(ch)
{
case KEY_LEFT:
destroy_win(my_win);
my_win = create_newwin(height, width, starty,--startx);
wprintw(my_win, "This is some text");
wrefresh(my_win);
break;
case 'd':
destroy_win(my_win);
my_win = create_newwin(height, width, starty,++startx);
wprintw(my_win, "This is some text");
wrefresh(my_win);
break;
case 'w':
destroy_win(my_win);
my_win = create_newwin(height, width, --starty,startx);
wprintw(my_win, "This is some text");
wrefresh(my_win);
break;
case 's':
destroy_win(my_win);
my_win = create_newwin(height, width, ++starty,startx);
wprintw(my_win, "This is some text");
wrefresh(my_win);
break;
case KEY_UP:
i--;
i = (i < 0) ? 4 : i;
break;
case KEY_DOWN:
i++;
i = (i < 0) ? 4 : i;
break;
}

The keypad function applies only to the window given as its parameter. When you use newwin, etc., those return a window where the keypad mode is not set.
The newwin documentation points out
Regardless of the function used for creating a new window (e.g.,
newwin, subwin, derwin, newpad), rather than a duplicate (with dupwin),
all of the window modes are initialized to the default values. These
functions set window modes after a window is created:
idcok, idlok, immedok, keypad, leaveok, nodelay, scrollok,
setscrreg, syncok, wbkgdset, wbkgrndset, and wtimeout

Related

How do i create an option in switch case?

I've recently tried to make some switch case function. Now, I'm currently trying to make an option but it seems it always skips the if part in case 1. The input just doesn't go in the if - else part.
#include <stdio.h>
int main(){
int option;
char choice;
int celcius;
menu:
printf("Welcome to program.\n");
printf("1. Input celcius\n");
printf("2. Convert To Kelvin\n");
printf("3. Convert To Fahrenheit\n");
printf("4. Convert To Reamur\n");
scanf("%d", &option);
switch(option){
case 1:
scanf("%d", &celcius);
printf("The value is : %d\n", celcius);
printf("Continue? : (y/n)\n"); scanf("%c", &choice);getchar();
if(choice == 'y' || choice == 'Y'){
goto menu;
}else if(choice == 'n' || choice == 'N');
break;
}
case 2:
printf("Please input the value: "); scanf("%d", &celcius);
int kelvin = celcius + 273;
printf("Converted Value is : %d\n", kelvin);
break;
case 3:
printf("Please input the value: "); scanf("%d", &celcius);
int fahrenheit = celcius + 32;
printf("Converted Value is : %d\n", fahrenheit);
break;
case 4:
printf("Please input the value: "); scanf("%d", &celcius);
int reamur = 5/4 * celcius;
printf("Converted Value is : %d\n", reamur);
break;
default:
printf("Wrong input.\n");
}
return 0;
}
(incomplete code because currently trying to make the case 1 works.)
Any solutions will help : )
You have a getchar() after the scanf() for choice. This is reading the newline character that is left in the input buffer after the scanf() for option.
You need to remove the getchar() and change the scanf() for choice to:
scanf(" %c", &choice);
The space before the %c will skip any whitespace characters in the input buffer.

In C gets function is not working in iteration

At first do while iteration in my code, the gets() function works fine, but from the next iteration it skips the gets() function and moves on to the following statement.
So please anyone sort out the problem with a solution. The problem part will be highlighted in bold. The code is as follows:
void main()
{
char string[150], cont[5];
int total = 0, alpha = 0, digit = 0, spl_char = 0, upp = 0, low = 0;
int i, vowels = 0,consonants = 0;
int choice;
do
{
system("cls");
printf("\t\t\t\tSTRING OPERATIONS\n");
printf("\t\t\t\t~~~~~~ ~~~~~~~~~~\n");
printf("\nEnter the String: ");
***gets(string);*** // the problem part
printf("\nEnter your choice: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("1");
break;
case 2:
printf("2);
break;
default:
printf("\nSorry! The Entered Choice is Not Available. Try Again!");
break;
}
do
{
printf("\nDo you want to Continue (yes/no): ");
scanf("%s", cont);
if (stricmp(cont, "yes") == 0 || stricmp(cont, "no") == 0)
break;
printf("\nError!!! Please type only yes or no.\n");
} while(stricmp(cont, "yes") != 0 || stricmp(cont, "no") != 0);
} while(stricmp(cont, "yes") == 0);
}
The first iteration it asks & waits for the input:
for eg:
Enter the String: bat
and the process continues....
And in second iteration it just asks and skips to following statement:
for eg:
Enter the String:
Enter your choice:

Simple ncurses app not reacting to arrow keys

I compiled this simple ncurses program and the up down keys are unresponsive.
Any idea why this does not work?
I am using Fedora Linux 5.7.16-200.fc32.x86_64 the default terminal emulator is XTerm(351). I got no errors or warning building ncurses or making the app.
cc -o test test.c -lncurses
/* test.c */
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
int main(void) {
WINDOW * mainwin, * childwin;
int ch;
/* Set the dimensions and initial
position for our child window */
int width = 23, height = 7;
int rows = 25, cols = 80;
int x = (cols - width) / 2;
int y = (rows - height) / 2;
/* Initialize ncurses */
if ( (mainwin = initscr()) == NULL ) {
fprintf(stderr, "Error initialising ncurses.\n");
exit(EXIT_FAILURE);
}
/* Switch of echoing and enable keypad (for arrow keys) */
noecho();
keypad(mainwin, TRUE);
/* Make our child window, and add
a border and some text to it. */
childwin = subwin(mainwin, height, width, y, x);
box(childwin, 0, 0);
mvwaddstr(childwin, 1, 4, "Move the window");
mvwaddstr(childwin, 2, 2, "with the arrow keys");
mvwaddstr(childwin, 3, 6, "or HOME/END");
mvwaddstr(childwin, 5, 3, "Press 'q' to quit");
refresh();
/* Loop until user hits 'q' to quit */
while ( (ch = getch()) != 'q' ) {
switch ( ch ) {
case KEY_UP:
if ( y > 0 )
--y;
break;
case KEY_DOWN:
if ( y < (rows - height) )
++y;
break;
case KEY_LEFT:
if ( x > 0 )
--x;
break;
case KEY_RIGHT:
if ( x < (cols - width) )
++x;
break;
case KEY_HOME:
x = 0;
y = 0;
break;
case KEY_END:
x = (cols - width);
y = (rows - height);
break;
}
mvwin(childwin, y, x);
}
/* Clean up after ourselves */
delwin(childwin);
delwin(mainwin);
endwin();
refresh();
return EXIT_SUCCESS;
}
The example doesn't repaint the child-window (so nothing seems to happen), and doesn't use cbreak (so nothing happens until you press Return (i.e., newline).
I did this change to see what it does:
> diff -u foo.c.orig foo.c
--- foo.c.orig 2020-08-30 06:00:47.000000000 -0400
+++ foo.c 2020-08-30 06:02:50.583242935 -0400
## -29,6 +29,7 ##
/* Switch of echoing and enable keypad (for arrow keys) */
+ cbreak();
noecho();
keypad(mainwin, TRUE);
## -85,6 +86,7 ##
}
mvwin(childwin, y, x);
+ wrefresh(childwin);
}
Some terminal descriptions may use the same character ControlJ for cursor-down (and get mapped into KEY_ENTER rather than KEY_DOWN—see source code). After allowing for the other two problems, you may be seeing that.

How to move a FIELD which is inside a WINDOW

I'm new to stackoverflow.com so I'll do my best to explain my problem :)
I'm currently working on an "arcade game" project for my school and I have made a menu using ncurses where I can choose games / graphical library to use. I have made this menu resizeable so when the terminal shrunk, I move the windows and resize them (layout-like). Now I have to incorporate a text field to enter your name and I want that to be resizeable as well.
I have a FIELD inside a FORM inside a WINDOW in my program and no matter what I do, the window moves but the field stay in place...
I have made a test-program where I try to move a text field using arrow keys. As expected the little box (the window) moves but not the field.
#include <curses.h>
#include <form.h>
void move_window(WINDOW *window, int y, int x)
{
//clear();
wclear(window); // DON'T KNOW WHY IT DOESN'T CLEAR SCREEN
mvprintw(0, 0, "Y[%d] : X[%d]", y, x);
mvwin(window, y - 1, x - 1);
box(window, 0, 0);
wrefresh(window);
//refresh();
}
int main()
{
WINDOW *window;
FIELD *fields[2];
FORM *form;
int x = 20;
int y = 20;
int ch;
initscr();
keypad(stdscr, TRUE);
noecho();
cbreak();
fields[0] = new_field(1, 10, y, x, 0, 0);
fields[1] = NULL;
set_field_opts(fields[0], O_VISIBLE | O_PUBLIC | O_EDIT | O_ACTIVE | O_STATIC);
set_field_back(fields[0], A_UNDERLINE);
window = newwin(3, 12, y - 1, x - 1);
form = new_form(fields);
set_form_win(form, window);
post_form(form);
refresh();
move_window(window, y, x);
while ((ch = getch()) != 27) {
switch (ch) {
case KEY_LEFT:
x--;
move_window(window, y, x);
break;
case KEY_RIGHT:
x++;
move_window(window, y, x);
break;
case KEY_UP:
y--;
move_window(window, y, x);
break;
case KEY_DOWN:
y++;
move_window(window, y, x);
break;
case KEY_BACKSPACE:
case 127:
form_driver(form, REQ_DEL_PREV);
break;
default:
form_driver(form, ch);
break;
}
}
unpost_form(form);
free_form(form);
free_field(fields[0]);
endwin();
return 0;
}
I compile using : gcc ncurse.cpp -lncurses -lform && ./a.out
Can you explain to me what I am doing wrong in this ? I didn't found anything to solve this myself :/
PS : Sorry for my rusty english...

create native bitmap library

I am Persian and j2me do not have good support for persian font.
I will create a native font library that get bitmap font and paint my persian text in desplay. But I have a problem.
In english each letter is a set consist shap and uncode. Like (a , U+0061)
But in persian a char may have several shape. for example letter 'ب' in persian alphabet can be:
آب --when it is separate letter in a word
به --when it is start letter in a word
...
How can I get other form of a letter from font file?
I am a persian developer and I had the same problem in about 4 years ago.You have some way to solve this problem:
1-using custom fonts.
2-reshape your text before display it.
A good article in about first,is "MIDP Terminal Emulation, Part 3: Custom Fonts for MIDP ".But for arabic letters I think that is not simple.
In about second way,say you would to replace any character in your text with correct character.This means when you have:
String str = "به";
If get str characters they will be look like:
{1576,1607} that is like "ب ه" instead of "به".So you would to replace incorrect Unicode with correct Unicode codes(in this case correct characters are: {65169, 65258}).You can use "Arabic Reshapers" even reshapers that designed for android!I saw 2 link for this reshapers:1-github 2-Arabic Android(I'm persian developer and so I do not try them,instead I create classes with the same idea as they have).
With using a good reshaper also you may have problem with character arranging from left to right instead of right to left.(some phones draw characters from left to right and other from right to left).I use below class to detect that ordering is true(from right to left) or not:
public class DetectOrdering{
public static boolean hasTrueOrdering()
{
boolean b = false;
try {
char[] chArr = {65169, 65258};
String str = new String(chArr);
System.out.println(str);
int width = f1.charWidth(chArr[1]) / 2;
int height = f1.getHeight();
image1 = Image.createImage(width, height);
image2 = Image.createImage(width, height);
Graphics g1 = image1.getGraphics();
Graphics g2 = image2.getGraphics();
g1.drawString(str, 0, 0, 0);
g2.drawChar(chArr[1], 0, 0, 0);
int[] im1 = new int[width * height];
int[] im2 = new int[width * height];
image1.getRGB(im1, 0, width, 0, 0, width, height);
image2.getRGB(im2, 0, width, 0, 0, width, height);
if (areEqualIntArrrays(im1, im2)) {
b = true;
} else {
b = false;
}
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
private static boolean areEqualIntArrrays(int[] i1, int[] i2) {
if (i1.length != i2.length) {
return false;
} else {
for (int i = 0; i < i1.length; i++) {
if (i1[i] != i2[i]) {
return false;
}
}
}
return true;
}
}
If DetectOrdering.hasTrueOrdering() returns true,sure that phone draw Arabic characters from right to left and display your String.If returns false it draws from left to right.If phone draws Arabic character from left to right you would to reverse string after reshape it and then you can display it.
You can use one alphabet.png for the direct unicode mappings (those where the persian char does not change because of the neighbor chars). If your characters are monospaced, you may start with below class, as seen at http://smallandadaptive.blogspot.com.br/2008/12/custom-monospaced-font.html:
public class MonospacedFont {
private Image image;
private char firstChar;
private int numChars;
private int charWidth;
public MonospacedFont(Image image, char firstChar, int numChars) {
if (image == null) {
throw new IllegalArgumentException("image == null");
}
// the first visible Unicode character is '!' (value 33)
if (firstChar <= 33) {
throw new IllegalArgumentException("firstChar <= 33");
}
// there must be at lease one character on the image
if (numChars <= 0) {
throw new IllegalArgumentException("numChars <= 0");
}
this.image = image;
this.firstChar = firstChar;
this.numChars = numChars;
this.charWidth = image.getWidth() / this.numChars;
}
public void drawString(Graphics g, String text, int x, int y) {
// store current Graphics clip area to restore later
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipWidth = g.getClipWidth();
int clipHeight = g.getClipHeight();
char[] chars = text.toCharArray();
for (int i = 0; i < chars.length; i++) {
int charIndex = chars[i] - this.firstChar;
// current char exists on the image
if (charIndex >= 0 && charIndex <= this.numChars) {
g.setClip(x, y, this.charWidth, this.image.getHeight());
g.drawImage(image, x - (charIndex * this.charWidth), y,
Graphics.TOP | Graphics.LEFT);
x += this.charWidth;
}
}
// restore initial clip area
g.setClip(clipX, clipY, clipWidth, clipHeight);
}
}
And change it to use a different char_uxxxx.png file for each persian char that changes because of the neighbor chars.
When parsing your string, before painting, you must check which png file is appropriate to use. Hope this is a good place to start.

Resources