Menu

Text User Interface: how save and restore a screen

2016-10-17
2023-07-06
1 2 > >> (Page 1 of 2)
  • Eugenio Di Lorenzo

    In my application , while the user is using a screen, I need to show a message on screen (an error message, a help messaqge ...). The user read the message and have to return to the previous screen .See the attached image.

    to restore the screen with the previously displayed I must have saved it before.
    so I need a command to save the full screen (for example, a variable of 25 rows x 80 columns = 4000 characters) and a command to restore the screen from 4000 characters variable.
    Any help ?
    DILO.

     

    Related

    Wish List: #366


    Last edit: Eugenio Di Lorenzo 2016-10-17
    • Mário Matos

      Mário Matos - 2016-10-17

      Hi, Eugenio

      If you don't want to use "panels" (giving much more work), you may always use the "curses" functions:

      putwin()
      putwin() writes all data associated with a window into a file, using an unspecified format. This information can be retrieved later using getwin().

      getwin()
      Reads window-related data previously stored in a file by putwin(). It then creates and initialises a new window using that data.

      scr_dump()
      Writes the current contents of the virtual screen to the file named by filename in an unspecified format.

      scr_restore()
      Sets the virtual screen to the contents of the file named by filename, which must have been written using scr_dump(). The next refresh operation restores the screen to the way it looked in the dump file.

      NOTE:

      Filenames ought to have "random" numbers as you may guess... use 'rand() as a suffix (like "win50000.scr"). "panels" has an advantage though. If you have "lots" of subwindows/panels, you may select any one to be the "main" window (that is, any panel you choose to be on top of the others).

      But this is not part of "screenio" yet. You must use the CALL statement like "CALL [STATIC] "getwin" USING ... END-CALL.

      Cheers,

      MM

      PS: NCURSES manual attached (PDF).

       
      • Eugenio Di Lorenzo

        Hi Mario, thank you very much the suggestion.
        There are many functions in pdcurses that may be useful but unfortunately I can not understand how I can use (call) them. I am a cobol programmer without C knowledge.
        for example the "inch" function that reads one character and its attribute from the screen at position x, y. How should I code the call statement?
        for example :: call static "inch" using wX wY returning wChar-end call.
        where: wX and Wy are the PIC 9 (3) and wChar is a PIC X (01) ? (does'not work !

        Is there anyone that can give working examples on how to code in GnuCOBOL calls to the various functions PDCURSES or at least for main pdcurses functions ?
        It would be very useful to have an example "CALL" in GnuCOBOL for each PDCURSES function or at least a general rule of how to do.

        es
        call "inch" ... ???
        call "scr_dump" ... ???
        call " scr_restore" .... ???
        call "border" ... ???
        call "mouse functions ...

        DILO.

         
        • Mário Matos

          Mário Matos - 2016-10-18

          Hi, Eugenio

          Try to compile the file "GC02BOXMEXDEMO.COB" and see the result. This is the most basic I could do.

          The file is attached.

          Cheers,

          MM

           
          • Eugenio Di Lorenzo

            Thanks al lot Mario! This is exactly what I needed !
            Since I do not know the C language I try to avoid calls to programs or wrappers written in C but I do not see problems to use within a Cobol program call commands to C functions from pdcurses or other library.
            I have the pdcurses library manual. It includes many functions that can be very useful.
            I had already used getch () and call curs_set ().
            now Now, with your help, I figured out how to use scr_dump() and scr_restore ().
            Unfortunately I still have not figured out what is the rule to use, and then I can not use as Cobol program all C pdcurses functions.
            May I ask the courtesy to give an example of use of the inch () function.

            Thanks again for your help.
            DILO.

             
            • Mário Matos

              Mário Matos - 2016-10-19

              Hi, Eugenio

              Any "curses" library uses a type of variable called "chtype".

              GnuCOBOL only "knows" the 32bit version, which corresponds to a BINARY-LONG UNSIGNED (UNSIGNED-INT).

              This type contains the character itself, its attributes (modifiers) and its colors-pairs (foreground/background).

              Definition from "curses.h":


              Function group: inch

              Synopsis:

              chtype inch(void);

              Description:

              The inch() function retrieve the character and attribute from
              the current window position, in the form of a chtype.

              Return Value:

              A 'chtype' with character and attribute.

              The representation of a "chtype" is as follows:

              +--------------------------------------------------------------------+
              |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|..| 2| 1| 0|
              +--------------------------------------------------------------------+
                         color number      |       modifiers       |   character eg 'a'
              

              From right to left:

              The character - Bits 0-15 (16 bits, 2 bytes)
              Is the character itself (e.g. 'A')

              Modifiers - Bits 16-23 (8 bits, 1 byte)
              Non-color attributes:
              BOLD
              UNDERLINE
              INVISIBLE
              RIGHT-LINE
              LEFT-LINE
              PROTECT
              REVERSE
              BLINK

              Some of them are not used with cobol (e.g. BLINK).
              

              Color number - Bits 24-31 (8 bits, 1 byte)
              256 color pairs (foreground + background colors)

              How do we call "pdcurses" "inch" from GnuCOBOL?

              WORKING-STORAGE SECTION.
              
               77 cht_CharAndAttr             BINARY-LONG UNSIGNED.
              
               PROCEDURE DIVISION.
              
              * chtype inch(void);
               CALL STATIC "inch"
                     RETURNING   cht_CharAndAttr      *> chtype (unsigned int)
               END-CALL.
              

              Although, because decomposing "cht_CharAndAttr" is a little bit "tricky", with COBOL, I'll try to explain it later in an "understandable" mode.

              There is the need to use C macros to do it and I need to search within my work to help you with this one (in Cobol).

              Unfortunately, GnuCOBOL "common.h" does not expose to the system (EXPORT) enough information in terms of "screenio" which is the main driver for your beautiful work.

              Stay tune,

              Cheers,

              MM

               

              Last edit: Mário Matos 2016-10-19
              • Vincent (Bryan) Coen

                Hate to contradict you but curses ARE 64bit if you install that version and yes I am running both the primary s well as the devel packages on a Mageia X64 system for which almost all of the infrastructure runs under X64 (excluding small bit of s/w that are only compiled as 32 bit such as Acroread the .pdf reader from Adobe, but there again they have discontinued support for it.

                 

                Last edit: Simon Sobisch 2016-10-25
                • Mário Matos

                  Mário Matos - 2016-10-20

                  Hi, Vincent

                  I didn't fully explain what 32bit is in terms of "curses". I meant 32bit chtypes, not a 32bit OS or machine. I'll attach the "curses.h" from Bill Gray (The PDCurses fork from William McBrine).
                  This PDCurses version have a 64bit 'chtype' version which compiles in x86 and x64 platforms.

                  Go to line 390 and read onwards. until line 440.

                  http://www.projectpluto.com/win32a.htm
                  https://github.com/Bill-Gray/PDCurses

                  Cheers,

                  MM

                   
            • Mário Matos

              Mário Matos - 2016-10-19

              I forgot to answer about the "rules". In fact we cannot stablish "rules" with most of the functions "pdcurses" have. I did some work with it (most by trial and error). One, and the most important thing is, "RTFM" (Read The Fu??ing Manual).

              Cheers,

              MM

               
          • DaveR

            DaveR - 2016-10-20

            I downloaded GC02boxmexdemo.cob saved as gc02boxmexdemo2.cob, downloaded Arnolds latest build for windows, compiled from opencobolide, get error

            GC02BOXMEXDEMO2.COB: 107: attempt to reference unallocated memory (signal SIGSEGV)
            abnormal termination - file contents may be incorrect
            

            when running hitting enter at first ok

            DaveR

             
            • Simon Sobisch

              Simon Sobisch - 2016-10-20

              Arnold used rc1 to build the package, this has the bug with accept omitted. This will be fixed with a newer source (it is fixed in svn shortly after the rc1).

               

              Last edit: Simon Sobisch 2016-10-25
              • Arnold Trembley

                Arnold Trembley - 2016-10-26

                Is there a patch for this accept bug that I could apply to RC1? I already have one patch in RC1 for MinGW path separater characters. If the fix is relatively small I could probably apply it and rebuild RC1 (both BDB and VBISAM2 versions).

                 
                • Simon Sobisch

                  Simon Sobisch - 2016-10-26

                  Have a look in the svn log (look under menu entry Code). You'll see all change messages and when you click on them see the the changes in the files (Edward fixed this one).

                  Expect rc2 either tonight or at Sunday (as always, this is a plan, not a guaranteed time). Check the svn log in any case.

                  Completely off-topic: can you try to compile and use COBJAPI with your mingw environment?

                   
                  • Arnold Trembley

                    Arnold Trembley - 2016-10-26

                    Since I'm not sure how big the patch is, or exactly how to find it, I may wait until RC2, if it will be packaged like RC1.

                    I had to hunt around for the source code to cobjapi, but finally found it. I put the following 3 files in my c:\gc20base-vbisam folder:

                    cobjapi.cob
                    cobjapi.cpy
                    cobjapifn.cpy

                    Then I ran set_env.cmd and used the following command to compile it:

                    cobc -c -free cobjapi.cob -T cobjapi.lst

                    I used the default config file (not MVS for example).
                    I don't have any easy way to capture a console log that big. There were a LOT of warning messages that looked like this:

                    C:\Users\Arnold\AppData\Local\Temp\cob2020_0.c: In function 'J__RANDOM_':
                    C:\Users\Arnold\AppData\Local\Temp\cob2020_0.c:31201:12: warning: implicit decla
                    ration of function 'japi_random' [-Wimplicit-function-declaration]
                       b_1788 = japi_random ();
                                ^
                    

                    But basically it looked like it compiled successfully and created the following files:

                    10/25/2016 11:48 PM 216,602 cobjapi.cob
                    10/25/2016 11:49 PM 6,897 cobjapi.cpy
                    10/26/2016 12:02 AM 407,563 cobjapi.lst
                    10/26/2016 12:02 AM 345,316 cobjapi.o
                    10/26/2016 12:05 AM 341,745 cobjapi.pdf
                    10/25/2016 11:50 PM 6,266 cobjapifn.cpy

                    I edited the cobjapi.lst file using wordpad and printed it to a PDF file, which I will attach. The listing says:

                    358 Warnings in program
                    0 Errors in program

                    I can supply the cobc -info output if you would like me to do so, but it is GnuCOBOL 2.0 Release Candidate 1 built with VBISAM 2.0.

                     
                    • Simon Sobisch

                      Simon Sobisch - 2016-10-26

                      The "implicit declaration warnings" should be fixed with rc2.

                      COBJAPI (including docs and samples) can be found at https://sourceforge.net/p/open-cobol/contrib/HEAD/tree/trunk/tools/cobjapi/

                      To hunt down a commit have a look at svn log via an svn client, if you don't have one you may use the commit browser (but as you cannot search there currently this isn't a good option).
                      This segfault was fixed with [r1074] (I've just opened the log and searched for OMITTED -> fix found). It is a minimal change.

                      rc2 will be available as source tarball and windows source [for using with VC] as the rc1 was. I may create a win dist zip (binaries for use with VC) later.

                       
                  • Arnold Trembley

                    Arnold Trembley - 2016-10-26

                    Sorry, I don't know how to use cobjapi, but I did figure out how to redirect stderr, so you can see all the compile-time diagnostic messages.

                     
  • Simon Sobisch

    Simon Sobisch - 2016-10-17

    There are options for storing a complete window with other compiler - something currently not implemented in GnuCBOBOL.
    A workaround may be to just DISPLAY all the screens you have (looks like you use a SCREEN SECTION).

    If you're OK with leaving the COBOL path: creating a new curses window for the message and destroying it afterwards will help.

     
  • Klaus Schäfer

    Klaus Schäfer - 2016-10-18

    For this i use a second Screen definition with a dummy-accept for one char.
    After displaying the message, the Screen waits for enter and then i display my normal
    screen again. This works fine with Linux. Windows - i don't know but should work too.
    So i can send Errors to the user, if he typed something wrong in the Panel.

     
    • Eugenio Di Lorenzo

      Hi Klaus,
      what you say is correct, but I believe that it is easier to adopt the following technique.
      whatever is displayed on the screen:
      1. save the screen
      2. display the message
      3. the user reads the message and 'press "enter"
      4. Restore the saved screen exactly as it was before
      This very simple using curses commands scr_dump() and scr_restore() as Mario showed us.

       

      Last edit: Eugenio Di Lorenzo 2016-10-25
      • Mário Matos

        Mário Matos - 2016-10-25

        Hi, Eugenio

        Please don't use a fixed file name for "scr_dump" call. If you call this routine (or others, for the matter), you may get into "trouble" when you run the same program in another process simultaneously. Use the GnuCOBOL "RANDOM" intrinsic function (which returns a value between 0 and 1, like 0.123456789) and then get the integer part from that (by multiplying the result by 100000 for example) and getting the INTEGER-PART with 5 digits.

        Example (working with 5 digits):

        WORKING-STORAGE SECTION.

        01 cNumber. > This will be the (string) number
        03 nNumber PIC 9(5).
        > A number of 5 digits USAGE DISPLAY

        01 szFileName PIC X(256). *> Used for a null terminated filename

        PROCEDURE DIVISION:

        *> This will get 5 digits to store in 'nNumber' (cNumber is the string format of 'nNumber')
        COMPUTE nNumber =
        INTEGER-PART( RANDOM( SECONDS-PAST-MIDNIGHT ) * 100000 )
        END-COMPUTE.

        > Build a name (null terminated) for our C function...
        MOVE CONCATENATE ( "SCR", cNumber, ".TMP", X"00") TO szFileName.
        > NULL terminated string

        ...

        The resulting name would be somenting like this "SCRnnnnn.TMP" & X"00".

        And take a look to Gary Cutler's manual about the functions usage (see the header of the forum's site if you didn't already do so).

        Cheers,

        MM

        PS: I'm hopping this logic is correct. I didn't even test it. But the idea is there.

         

        Last edit: Mário Matos 2016-10-25
        • Simon Sobisch

          Simon Sobisch - 2016-10-25

          While it is true that there shouldn't be a fixed name used I wouldn't say Mario's approach is the correct one.

          The correct one is: placing scr_dump into libcob by adding a helper function into libcob/screenio.c (and adding it to libcob/system.def) with an optional parameter to set the filename. If it isn't set: call cob_temp_name to get it, if the filename var is empty (a string with spaces) and is big enough return the used name there.

          This would lead to something like:

          77 scr-dump-name-1   pic x(05).
          77 scr-dump-name-2   pic x(512). *> maximum size from libcob is 4096
          
          CALL 'OC_SCR_DUMP' USING OMITTED *> saves the screen with a temporary name
          ...
          CALL 'OC_SCR_RESTORE' USING OMITTED *> restores the last saved screen
          
          CALL 'OC_SCR_DUMP' USING "dump1" *> saves the screen as "dump1" to current working directory
          ...
          CALL 'OC_SCR_DUMP' USING "dump500" *> saves the screen as "dump500" to current working directory
          ...
          CALL 'OC_SCR_RESTORE' USING "dump1" *> restores the saved screen from "dump1"
          
          CALL 'OC_SCR_DUMP' USING scr-dump-name-1 *> saves the screen with a temporary name, doesn't return it as the size is too small
          ...
          CALL 'OC_SCR_DUMP' USING scr-dump-name-2 *> saves the screen with a temporary name, likely returns it as the size likely is big enough
          ...
          

          Mario, please give this a try. If you need help create a new topic under "contribution".

          @Eugenio: In the meanwhile I'd suggest to not use FUNCTION (RANDOM) but to count the number of saves per session (of necessary) and prefix them with the return from CALL 'C$GETPID'.
          Or stay with calling C functions by doing something like

          CALL STATIC 'cob_temp_name' USING szFileName '.dump' && x'00' RETURNING OMITTED

          If you want multiple files per session add the following CALL before:

          CALL STATIC 'cob_incr_temp_iteration' RETURNING OMITTED

          Simon

           

          Last edit: Simon Sobisch 2016-10-25
          • Mário Matos

            Mário Matos - 2016-10-25

            See? I like when you get "pissed". And you have good ideas. Such so good ideas that they seem "alive" already. So, just because I don't want to "contribute" with anything (except my ideas, which in turn creates good ideas on others (like you), I'm going to invite you to do the JOB (or someone else on your behalf). Please, be my guest... I'm used to use the tools I have at my disposal (others do it too, and sometimes in a simpler way).

            There's more than one way to skin a cat. Make do with what you have.

            I'm not the BEST (nor the WORST), I'm a "mentor"... and It has worked well !!!

            BTW: Why GnuCOBOL system calls are beginning with "OC_" and not "GC_" as it should be ? (Historical reasons?)

            Cheers,

            MM

             

            Last edit: Mário Matos 2016-10-26
            • Brian Tiffin

              Brian Tiffin - 2016-10-26

              BTW: Why GnuCOBOL system calls are beginning with "OC_" and not "GC_" as it should be ? (Historical reasons?)

              Yep. Old names couldn't really be changed, and this keeps any new ones consistent. Heritage is awesome.

              Cheers,
              Brian

               
              • Simon Sobisch

                Simon Sobisch - 2016-10-26

                BTW: Why GnuCOBOL system calls are beginning with "OC_" and not "GC_" as it should be ? (Historical reasons?)

                Yep. Old names couldn't really be changed, and this keeps any new ones consistent.

                There's the alternative of adding aliases for the old ones (it is only a duplicated entry in libcob/system.def leading only to a duplicated entry in cobc --list-system and in the lookup for CALL resolves - not measurable) and only use CBL_GC for the newer ones.

                Thoughts?

                 
                • Mário Matos

                  Mário Matos - 2016-10-26

                  Tha's what I thought ! Give "aliases" to the people.

                  Cheers,

                  MM

                   
1 2 > >> (Page 1 of 2)

Anonymous
Anonymous

Add attachments
Cancel