1. Backspace doesn't work in 4.1.0 programs?

It's been a long time since I've been here - all those years, all things I needed always worked well. Sorry if this here has been discussed before - if so, I couldn't find it.

I have recently updated from 4.05 to 4.1.0 (64 bit), and now I find that the Backspace key doesn't work anymore with input from the console using gets(0), and thus also not with prompt_string(). Whether this is by design or a bug, it is seriously annoying as users will not expect this behavior, and may not be able to guess that they can use the left arrow key instead.

Thanks for any help! Robert

new topic     » topic index » view message » categorize

2. Re: Backspace doesn't work in 4.1.0 programs?

Hi

Ok, there's a lot of guff in here, and most of it is plagerised from other programs, but this will read every key on the keyboard that you press, and return an integer

global object VOID 
 
--eu only 
--/*          
include graphics.e -- color names 
include dll.e 
include wildcard.e 
include misc.e 
include get.e 
include image.e 
--*/ 
 
without warning 
 
global constant EU_VERSION = 3, 
                PLAT = platform()         
         
 
constant COLORS = 1,  FGND = 1, BKGND = 2,   -- box structure 
         COORDS = 2,  ROW = 1, COL = 2, 
         SIZE   = 3,  HEIGHT = 1, WIDTH = 2, MINH = 4, MINW = 8,     
         STYLE  = 4,       
         SHADOW = 5, 
         HINT   = 6, 
         HINTCOLORS = 7, 
         BUFFER = 8 
 
global integer  SGL, DBL, DHL, DVL, NONE, 
                up, dn, left, right, ENTER, ESC, SP, 
                pgup, pgdn, home, endd, insert, bksp, del, tab, 
                F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12         
          
global sequence Lines, Divider, Shadow 
global integer TL, HL, TR, VL, BL, BR 
global object ENV = "Windows" 
 
ESC = 27 
global constant KEY_UP = {ESC, 91, 65}, 
                KEY_DOWN = {ESC, 91, 66}  
 
 
tab = '\t' 
TL = 1  HL = 2  TR = 3  VL = 4  BL = 5  BR = 6 
 
if platform() = LINUX then                
        SGL = 1 DBL = 2  DHL = 3  DVL = 4  NONE = 5  -- border styles 
        --key defines 
        up = 259  dn = 258  left = 260  right = 261  ENTER = 10  ESC = 27  SP = 32   
        pgup = 339  pgdn = 338  home = 262  endd = 360  insert = 331  bksp = 263 del = 330 
        F1 = 265 F2 = 266 F3 = 267 F4 = 268 F5 = 269 F6 = 270 F7 = 271 F8 = 272 F9 = 273 F10 = 274 F11 = 275 F12 = 276 
         
         
        --these have been changed from the 'graphic' character set 
        Lines = {{'+','-','+','|','+','+'}, -- single line borders 
                        {'+','-','+','|','+','+'}, -- double line borders 
                        {'+','-','+','|','+','+'}, -- double horizontal 
                        {'+','-','+','|','+','+'}, -- double vertical 
                        {' ',' ',' ',' ',' ',' '} } -- none 
                         
        Divider = {{'+','-','+'}, -- single style divider line 
                        {'+','-','+'}, 
                        {'+','-','+'}, -- double horizontal 
                        {'+','-','+'}, 
                        {' ',' ',' '}} 
         
        Shadow = {' ',' ',' '}  -- 3 different shadow backgrounds 
         
        ENV = getenv("TERM") 
        if sequence(ENV) and match(upper(ENV), "XTERM") = -10 then --set to -10 to ignore it for now 
                --xterms seem to work differently - try Windows set 
                Lines = {{218,196,191,179,192,217}, -- single line borders 
                                {201,205,187,186,200,188}, -- double line borders 
                                {213,205,184,179,212,190}, -- double horizontal 
                                {214,196,183,186,211,189}, -- double vertical 
                                {' ',' ',' ',' ',' ',' '}} -- none 
                                 
                Divider = {{195,196,180}, -- single style divider line 
                                {204,205,185}, 
                                {198,205,181}, -- double horizontal 
                                {199,196,182}, 
                                {' ',' ',' '}} 
                 
                Shadow = {176,177,178}  -- 3 different shadow backgrounds 
        end if 
                         
         
else 
        SGL = 1 DBL = 2  DHL = 3  DVL = 4  NONE = 5  -- border styles 
        --key defines wim32 / dos 
        up = 328  dn = 336  left = 331  right = 333  ENTER = 13  ESC = 27  SP = 32  
        pgup = 329  pgdn = 337  home = 327  endd = 335  insert = 338  bksp = 8 del = 339 
        F1 = 315 F12 = 316 F3 = 317 F4 = 318 F5 = 319 F6 = 320 F7 = 321 F8 = 322 F9 = 323 F10 = 324 F11 = 325 F12 = 326 
 
        --redefining for windows version 
        up = 1016400  dn = 1016432  left = 1016384  right = 1016416 
        pgup = 1016320  pgdn = 1016336 
 
        --have to work out codes for lines       
--    Lines = {{'?,'?,'¿','³','?,'?}, -- single line borders 
--                {'?,'?,'»','º','?,'¼'}, -- double line borders 
--                {'?,'?,'¸','³','?,'¾'}, -- double horizontal 
--                {'?,'?,'·','º','?,'½'}, -- double vertical 
--                {' ',' ',' ',' ',' ',' '}} -- none 
--                 
--    Divider = {{'?,'?,'´'}, -- single style divider line 
--                  {'?,'?,'¹'}, 
--                  {'?,'?,'µ'}, -- double horizontal 
--                  {'?,'?,'¶'}, 
--                  {' ',' ',' '}} 
-- 
--    Shadow = {'°','±','²'}  -- 3 different shadow backgrounds 
    Lines = {{218,196,191,179,192,217}, -- single line borders 
                  {201,205,187,186,200,188}, -- double line borders 
                  {213,205,184,179,212,190}, -- double horizontal 
                  {214,196,183,186,211,189}, -- double vertical 
                  {' ',' ',' ',' ',' ',' '}} -- none 
                   
    Divider = {{195,196,180}, -- single style divider line 
                    {204,205,185}, 
                    {198,205,181}, -- double horizontal 
                    {199,196,182}, 
                    {' ',' ',' '}} 
 
    Shadow = {176,177,178}  -- 3 different shadow backgrounds 
 
         
end if 
 
global atom SCREEN_BKGND 
SCREEN_BKGND = BLACK 
 
global atom LIST_KEY  
LIST_KEY = 0 
 
global integer LISTBOXINDEX_INITIAL_FLAG        --flag to set searching for first letter in list 
LISTBOXINDEX_INITIAL_FLAG = 0                   --doesn't always respond to this 
                                                --hence flag 
 
global integer INSERT_MODE                      --can set insert mode on and off from outside FDialogs 
INSERT_MODE = 0 
 
global sequence DefaultBox 
         DefaultBox = {{BRIGHT_WHITE,BLUE},  -- default colors 
                       {1,1},                -- coordinates top left corner 
                       {5,10},               -- box size 
                        SGL,                 -- single line border 
                        1,                   -- light shadow 
                        "Press any key...",  -- hint text 
                        {GREEN,BLACK},       -- hint colors 
                        {}}                  -- buffer for save screen 
 
--to accomodate usage in xterm or konsole that hasn't been set to 25 lines 
--if you know it has, then set it to 25, to appear at bottom of screen 
global integer SCREEN_LINES, SCREEN_COLS 
        SCREEN_LINES = 24 
        SCREEN_COLS = 80 
global sequence vid_conf 
 
integer TRUE = 1, FALSE = 0 
 
sequence HIGHLIGHT_COLORS = {BRIGHT_GREEN, BRIGHT_MAGENTA, BRIGHT_WHITE, BRIGHT_BLUE, BRIGHT_CYAN, BRIGHT_RED, YELLOW} 
sequence LOWLIGHT_COLORS = {GREEN, MAGENTA, WHITE, BLUE, CYAN, RED, BROWN} 
global integer BKGRND_HIGHLIGHT_SWITCH = 1, 
        WITH_SHADOW = FALSE                     --sets whether a box should have a shadow or not 
 
 
 
--------------------------------------------------------------------------------------------------------------------- 
vid_conf = video_config() 
SCREEN_LINES = vid_conf[VC_LINES] 
SCREEN_COLS = vid_conf[VC_COLUMNS] 
 
--------------------------------------------------------------------------------------------------------------------- 
global function resolve_queue(sequence kq) 
--------------------------------------------------------------------------------------------------------------------- 
 
if match(kq, {27,79,70}) then return endd end if 
if match(kq, {27,79,72}) then return home end if 
 
for i = 1 to length(kq) do 
        if kq[1] =  ESC then 
                if kq[2] = -1 then 
                        return ESC 
                elsif kq[2] = 79 then 
                        if kq[3] = 0 then return home 
                        elsif kq[3] = 101 then return endd 
                        elsif kq[3] = 80 then return F1 
                        elsif kq[3] = 81 then return F1 + 1 
                        elsif kq[3] = 82 then return F1 + 2 
                        elsif kq[3] = 83 then return F1 + 3 
                        end if 
                elsif kq[2] = 91 then 
                        if kq[3] >= 65 and kq[3] <= 68 then 
                                if kq[3] = 65 then return up 
                                elsif kq[3] = 66 then return dn 
                                elsif kq[3] = 67 then return right 
                                else return left 
                                end if 
                        elsif kq[3] = 49 then 
                                if kq[4] = 126 then return home end if 
                        elsif kq[3] = 50 then 
                                if kq[4] = 126 then return insert end if 
                        elsif kq[3] = 51 then return del 
                        elsif kq[3] = 52 then return endd 
                        elsif kq[3] = 53 then return pgup 
                        elsif kq[3] = 54 then return pgdn 
                        else  
                                return F1 + kq[3] - 49 
                        end if 
                end if 
        end if 
end for 
 
 
return -1 
end function 
 
--------------------------------------------------------------------------------------------------------------------- 
global function wait_key_nn() 
--new non ncurses wait_key replacement for eu 3 
--returns a single character, like versions previous to eu25t3 
--will also return a single character with versions prior to eu25t3 
--note lot of scrounging from ed.ex, RDS 
 
--------------------------------------------------------------------------------------------------------------------- 
atom key 
sequence kq 
object characters 
 
kq = {}  
 
--wait for the first key - less computing time! 
key = wait_key() 
 
--pre eu 3.0 compatability 
if EU_VERSION < 3 or PLAT = WIN32 then return key end if 
 
kq = {key} 
 
--now get the rest of the keys 
while 1 do 
        key = get_key() 
        if key = -1 then 
                exit 
        end if 
        kq &= key 
end while 
 
--thats filled the sequence, now process it 
 
if length(kq) = 1 then 
        if kq[1] =  127 then kq[1] = bksp end if  
        return kq[1] 
end if  
 
--puts(1, "Key pressed") 
--for i = 1 to length(kq) do 
--        printf(1, "%d,", {kq[i]}) 
--end for 
 
key = resolve_queue(kq) 
 
return key 
end function 
--------------------------------------------------------------------------------------------------------------------- 
global function get_key_nn(object c) 
--replaces original get_key function for n0 ncurses eu version 
--this won't work if there are too many key presses too quickly, better to use a match 
--------------------------------------------------------------------------------------------------------------------- 
atom key 
sequence kq 
 
if EU_VERSION < 3 or PLAT = WIN32 then return c end if 
 
kq = {c}        --the first element 
 
--now get the rest of the keys 
while 1 do 
        key = get_key() 
        if key = -1 then 
                exit 
        end if 
        kq &= key 
end while 
 
--thats filled the sequence, now process it 
 
if length(kq) = 1 then 
        if kq[1] =  127 then kq[1] = bksp end if  
        return kq[1] 
end if  
 
--puts(1, "Key pressed") 
--for i = 1 to length(kq) do 
--        printf(1, "%d,", {kq[i]}) 
--end for 
 
key = resolve_queue(kq) 
 
return key 
end function 
 
 
integer c 
 
/* 

object k 
while 1 do 
    k = wait_key() 
    printf(1, ": %d\n", {k}) 
end while 
*/ 
 
while 1 do 
    c = wait_key_nn() 
    printf(1, " - Returned key : %d\n", {c}) 
end while 
 

It's from a heavily modded dialog.ex, for a menu system, which actually looks quite nice on windows

Cheers

Chris

new topic     » goto parent     » topic index » view message » categorize

3. Re: Backspace doesn't work in 4.1.0 programs?

RobertS said...

It's been a long time since I've been here - all those years, all things I needed always worked well. Sorry if this here has been discussed before - if so, I couldn't find it.

I have recently updated from 4.05 to 4.1.0 (64 bit), and now I find that the Backspace key doesn't work anymore with input from the console using gets(0), and thus also not with prompt_string(). Whether this is by design or a bug, it is seriously annoying as users will not expect this behavior, and may not be able to guess that they can use the left arrow key instead.

Thanks for any help! Robert

It looks like this was fixed somewhere along the way but I'm unable to track down exactly where. I get the same behavior with the 2015-02-02 (57179171dbed) build on Windows, but not Linux.

I've got GitHub running builds when the repo changes (effectively, "nightly" builds) so you can try the binaries available here: https://github.com/OpenEuphoria/euphoria/actions/runs/1884336372

-Greg

new topic     » goto parent     » topic index » view message » categorize

4. Re: Backspace doesn't work in 4.1.0 programs?

Chris: Thank you! I'm afraid I don't understand how to use it, though. I need it for reading single lines from the Windows console:

object line
line = prompt_string("? ")

That is, I need a function that returns a string, and that more or less looks like and works like entering something at the console prompt. Insert/delete as the console command line has it would be nice but isn't necessary, but Backspace is essential for fixing typing errors. If I can use the code you've provided as a replacement for prompt_string(), I haven't found how?

Greg: Thank you - but, I'm not familiar with GitHub, and I'm too stupid to figure it out: I do not find the files that I can download?

Robert

new topic     » goto parent     » topic index » view message » categorize

5. Re: Backspace doesn't work in 4.1.0 programs?

Hi

Sorry, I should have been more specific - prompt_string() doesn't work because of the windows console in modern windows PC and eu. Annoying I know, I had the same problem on linux, so essentially wrote my own. It does mean you have to keep tighter control over what the screen is displaying though.

add this code onto the end (remove the other entry tests)

--------------------------------------------------------------------------------------------------------------------- 
global procedure printat(sequence coords, sequence text) 
--displays text at a position 
--------------------------------------------------------------------------------------------------------------------- 
 position(coords[1],coords[2]) 
 puts(1,text)     
end procedure 
 
--clear_screen() 
position(10,1) puts(1, "Enter string : ") 
sequence str = "" 
while 1 do 
    printat({10, length("Enter string : ")}, str & "  ") 
    position(10, length("Enter string : " & str)) 
    c = wait_key_nn() 
    if c = bksp then 
        if length(str) > 1 then 
            str = str[1..length(str) - 1] 
        end if 
    else 
        str = str & c   --note - no checking for valid keys! 
    end if 
 
    if c = 13 then exit end if 
 
end while 
 
puts(1, "\n" & str & "\n") 
--need to do some tidying up, but thats the principle 
new topic     » goto parent     » topic index » view message » categorize

6. Re: Backspace doesn't work in 4.1.0 programs?

RobertS said...

Greg: Thank you - but, I'm not familiar with GitHub, and I'm too stupid to figure it out: I do not find the files that I can download?

The Artifacts listed at the bottom of the page include output from that run of the build. Clicking on an artifact will give you a zip file of the contents. Inside the zip file you'll find a new copy of each executable like eui.exe, etc. You can use these in place of the executables you currently have installed. So if you're currently using Euphoria 4.1.0 64-bit on Windows, download the euphoria-4.1.0-WINDOWS-x86_64-d8fb2e2 package and then grab the eui.exe from inside and copy it to your C:\Euphoria\bin directory. (I'd recommend renaming the existing one first in case you want to put it back.)

-Greg

new topic     » goto parent     » topic index » view message » categorize

7. Re: Backspace doesn't work in 4.1.0 programs?

Chris: thank you, I'll try that out. But, up to and including 4.05 (I haven't tried 4.06 yet), prompt_string("") has worked well and still does, including Backspace, so, I'm not sure if this really is an unresolvable problem between Euphoria and Windows?

Greg: this is what I had thought, but - I've tried it out with three different browsers now - there is nothing to click in the four "Artifacts" lines. Next to the little cubes are the names and the file sizes, but none of it is clickable, just plain text!?

I can click on "4 jobs completed" or on the "Builds" on the left side of the screen, but they only lead me to a window with missing protocol files, nothing to download.

Thanks for all your help!
Robert

new topic     » goto parent     » topic index » view message » categorize

8. Re: Backspace doesn't work in 4.1.0 programs?

I've just discovered something strange:

In this example, Backspace works with gets(0)

object line
line = gets(0)
puts(1, "\n")
puts(1, "input line: " & line)

After I write anything to the screen, Backspace stops working:

object line
puts(1, "anything\n")
line = gets(0)
puts(1, "\n")
puts(1, "input line: " & line)

Also, in the first example puts(1, "\n") creates an extra blank line, but as soon as something got written to the screen and Backspace stops working, \n is needed to start a new line - as it had been until 4.05.

Maybe this can give a hint where the problem may lie?

Still have to try Chris's code! Thanks, Robert

new topic     » goto parent     » topic index » view message » categorize

9. Re: Backspace doesn't work in 4.1.0 programs?

I think I've found a solution - thank you, Chris, for pointing me to "position". I hope more testing won't bring some unpleasant surprise, but as far as I've tested it (with Euphoria 4.1 and Windows 10), this seems to work as a Backspace-enabled alternative to prompt_string()

I’ve deleted the code, because it was just a proof of concept, flawed and incomplete. I’ll post a proper version below.

I think it won't be too difficult to add cursor left/right, and insert/delete, but the important thing is that Backspace works.

Thanks again!
Robert

new topic     » goto parent     » topic index » view message » categorize

10. Re: Backspace doesn't work in 4.1.0 programs?

You're welcome!

Chris

new topic     » goto parent     » topic index » view message » categorize

11. prompt_string() replacement with basic editing functions

Here is a prompt_string() replacement with some basic editing functions (I've tested it with Phix 1.0.1):

Left, right, home, and end keys move the cursor
Backspace deletes character left of cursor
Delete deletes character at cursor position
Any character typed is appended or inserted at cursor position
Enter returns input string regardless of cursor position

No line wrap, max length of input string = screen width minus 1 minus length of promt string

include graphics.e 
 
global function prompt_string_ed(sequence prompt) 
 
  object scrn                      -- for calling video_config() 
  object pos                       -- for calling get_position 
  object in_string                 -- input string 
  integer s                        -- pressed key 
  integer in_c                     -- cursor position in input string 
  integer pl                       -- prompt length 
  integer in_max                   -- input max length 
  integer in_l                     -- current length of input string 
  integer screen_li                -- screen cursor position line 
 
  scrn = video_config() 
  in_max = scrn[10] - length(prompt) - 1 
 
  puts(1, prompt) 
  pl = length(prompt) 
  in_string = "" 
  in_l = 0 
  in_c = 1 
 
  pos = get_position() 
  screen_li = pos[1] 
 
  while 1 do                               -- loop exited when return key pressed 
    s = wait_key() 
 
    if s < 32 then                         -- ctrl characters 
      if s = 13 then                       -- return 
        exit 
      elsif s = 8 then                     -- backspace 
        if in_l > 0 then 
          if in_l = in_c - 1 then 
            in_string = in_string[1..in_l-1] 
            in_l -= 1 
            in_c -= 1 
            position (screen_li, in_c + pl) 
            puts(1, " ") 
            position (screen_li, in_c + pl) 
          elsif in_c > 1 then 
            in_string = in_string[1..in_c-2] & in_string[in_c..$] 
            in_l -= 1 
            in_c -= 1 
            position (screen_li, in_c + pl) 
            puts(1, in_string[in_c..$] & " ") 
            position (screen_li, in_c + pl) 
          end if 
        end if 
      end if 
 
    elsif s = 339 then                    -- delete 
      if in_l > 0 then 
        if in_c < in_l + 1 then 
          in_string = in_string[1..in_c-1] & in_string[in_c+1..$] 
          in_l -= 1 
          position (screen_li, in_c + pl) 
          puts(1, in_string[in_c..$] & " ") 
          position (screen_li, in_c + pl) 
        end if 
      end if 
 
    elsif s = 327 then                    -- home 
      in_c = 1 
      position (screen_li, in_c + pl) 
    elsif s = 335 then                    -- end 
      in_c = in_l + 1 
      position (screen_li, in_c + pl) 
    elsif s = 331 then                    -- arrow left 
      if in_c > 1 then 
        in_c -= 1 
        position (screen_li, in_c + pl) 
      end if 
    elsif s = 333 then                    -- arrow right 
      if in_c < in_l + 1 then 
        in_c += 1 
        position (screen_li, in_c + pl) 
      end if 
 
    elsif s < 128 then                    -- printable characters, change to 256 to allow 8-bit characters 
      if in_l < in_max then               -- max length of input string not yet reached 
        if in_l = in_c - 1 then           -- cursor at line end 
          puts(1, s) 
          in_string = in_string & s 
        else 
          in_string = in_string[1..in_c-1] & s & in_string[in_c..$] 
          position (screen_li, in_c + pl) 
          puts(1, in_string[in_c..$]) 
          position (screen_li, in_c + pl + 1) 
        end if 
        in_l += 1 
        in_c += 1 
      end if 
    end if 
  end while 
 
  puts(1, "\n") 
  return in_string 
end function 

Comments welcome, should anyone actually be interested in this.
Robert

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu