DSMPy

Dynamic Screen Manager for iSeries Python

 

Index

 

 

What is DSMPy

 

It is an adaptation to Python of Thomas Raddatz's DSM RPG service program based on the Dynamic Screen Manager APIs.

The Dynamic Screen Manager (DSM) APIs are a set of screen I/O interfaces that provide a dynamic way to create and manage screens. The DSM APIs provide an alternative to the existing way of defining screen appearance outside a program by coding in DDS or UIM, for example.

Instead, programmers can use a series of calls to DSM within their programs to dynamically specify and control screen appearance from their applications. Unlike static definition methods, the DSM interfaces provide the flexibility needed for those applications requiring more dynamic screen control. The DSM support provided varies from low-level interfaces for direct screen manipulation to windowing support.

The main building objects provided are: screen, window, constant text field, alphanumeric field, numeric field and messages.

See the usage section for more details.

 

Requirements

 

 

Download

 

Current version: 2.2.1

Download DSM.zip file to your PC. Unzip in a temp directory.You should have the following files:

 

Installation

 

In your PC (Windows)

 

In order to install DSMPy we need to transfer the files to the iSeries.

We have included upload.bat to help you with that task, just invoke it as follows:

upload hostname user password library

 

In your iSeries

 

Download and install Craig Rutledge's XMLpreview.

Execute the following statements, press F10 in each case to install and reply negatively (with NO or XD_NO) to all questions posted:

XMLPREVIEW UPLOADMBR(BASICS1) UPLOADSRCF(DSMPY/QXML)

XMLPREVIEW UPLOADMBR(RTVFLDL) UPLOADSRCF(DSMPY/QXML)

XMLPREVIEW UPLOADMBR(LSTOBJ) UPLOADSRCF(DSMPY/QXML)

XMLPREVIEW UPLOADMBR(DSM) UPLOADSRCF(DSMPY/QXML)

 

If all goes well your DSMPY library should contain (WRKOBJ DSMPY/*ALL)::

Object      Type        Attribute   Text
BASICS1     *SRVPGM     RPGLE       SrvPgm: Basic Routines
DSM *SRVPGM RPGLE SrvPgm: Dynamic Screen Manager
DSMPYT *SRVPGM RPGLE SrvPgm: DSM Python Interface
LSTOBJ *SRVPGM RPGLE List Object service program
RTVFLDL *SRVPGM RPGLE SrvPgm : Retrieve Field List
DSM *MSGF DSM: Dynamic Screen Manager - message
QBASICS1 *FILE PF-SRC
QDSM *FILE PF-SRC QLSTOBJ *FILE PF-SRC
QRTVFLDL *FILE PF-SRC
QXML *FILE PF-SRC XML packages

 

Library DSMPY has to be added to the library list when running Python scripts that use DSM code.

 

iSeries Python settings

 

If you don't already have a home directory for your Python scripts you can set one up with the following two commands, they are not mandatory and they modify you environment settings for the whole system:

MKDIR DIR('/home/python/scripts')

ADDENVVAR ENVVAR(PYTHONPATH) VALUE('/home/python/scripts') LEVEL(*SYS)

Note 1: the command is case sensitive and you must have *JOBCTL special authority to use it. If in doubt consult with your system administrator.

 

Now copy the DSM Python module to the Python default library and the test scripts (see note 2 below) to your scripts directory, substituting with your machine's CCSID and choice of CODPAG (we used *PCASCII to make scripts editable from both the PC and iSeries side):

CPYTOSTMF FROMMBR('/QSYS.LIB/DSMPY.LIB/QDSM.FILE/DSMSUP.MBR') TOSTMF('/usr/python2.3/lib/dsmsup.py') DBFCCSID(37) STMFCODPAG(*PCASCII)

CPYTOSTMF FROMMBR('/QSYS.LIB/DSMPY.LIB/QDSM.FILE/TEST_PY.MBR') TOSTMF('/home/python/scripts/test_py.py') DBFCCSID(37) STMFCODPAG(*PCASCII)

CPYTOSTMF FROMMBR('/QSYS.LIB/DSMPY.LIB/QDSM.FILE/TEST_PYW.MBR') TOSTMF('/home/python/scripts/test_pyw.py') DBFCCSID(37) STMFCODPAG(*PCASCII)

Note 2: you don't have to copy the test scripts, since they can be executed directly from where they are in file QDSM, but they will not be so easily accessible from a PC if they are not in the IFS. The sample commands use the suggested path mentioned at the beginning of this section.

 

 

 

Using DSMPy

 

Quick reference

 

Main containers
Parameters
Screen  
mode="*", msgQ=MsgQ() 
Window  
toprow,leftcol,rows,cols,msgQ=MsgQ() 

 

Function     
Allowed in
Parameters  
Screen
Window
addFieldA row, col, len
addFieldN row, col, digits, decPos=0, editCode="L"
addMsg msgtxt
addText row, col, txt, len=0
border   topleft+top+topright+left+right+bottomleft+bottom+bottomright
capture  
clear    
close  
hide    
rmvMsg  
open  
show  
title   titletxt
titleColor   color
 
Attributes / functions 
 
Applies to
Parameters
Text
FieldA
FieldN
color color
get    
nonDisplay   True/False
reverseImage True/False
set   value
setCursor  
underlined     True/False
upperCase     True/False

 

Details

Screen: think of it as a borderless window that occupies the whole display. It is one of the main containers for the other objects, so it is the first thing you would define to use DSM. Its size is controlled by the mode parameter.

Mode
rows
columns
MODE_SAME
same as current
same as current
MODE_DS3
24
80
MODE_DS4
27
132

The msgQ parameter is the fully qualified call stack entry name of the call stack entry whose messages are displayed in the message subfile of the screen.

Window: this is the other container, it is an area of the display with the following layout:

 

Border: defines 8 characters to be used as window borders as shown:.

12222223                              .------.
4      5      so border ".-.||'-'"    |      |
4      5         will appear as       |      |
4      5                              |      |
67777778                              '------'

 

FieldA (Alphanumeric field): input/output field that can contain alphanumeric characters. Creation parameters are: row, column and length.

FieldN (Numeric only field): this input/output field can only contain numbers. Creation parameters are: row, column, total number of digits, number of decimal digits and an optional edit code, which is explained in the table below:

Edit Codes Positive Number- Two Decimal Positions Positive Number- No Decimal Positions Negative Number- Three Decimal Positions1 Negative Number- No Decimal Positions1 Zero Balance- Two Decimal Positions1 Zero Balance- No Decimal Positions1
Unedited 1234567 1234567 xxxx.125- 125- xxxxxx xxxxxx
1 12,345.67 1,234,567 .125 125 .00 0
2 12,345.67 1,234,567 .125 125

3 12345.67 1234567 .125 125 .00 0
4 12345.67 1234567 .125 125

A 12,345.67 1,234,567 .125CR 125CR .00 0
B 12,345.67 1,234,567 .125CR 125CR

C 12345.67 1234567 .125CR 125CR .00 0
D 12345.67 1234567 .125CR 125CR

J 12,345.67 1,234,567 .125- 125- .00 0
K 12,345.67 1,234,567 .125- 125-

L 12345.67 1234567 .125- 125- .00 0
M 12345.67 1234567 .125- 125-

N 12,345.67 1,234,567 -.125 -125 .00 0
O 12,345.67 1,234,567 -.125 -125

P 12345.67 1234567 -.125 -125 .00 0
Q 12345.67 1234567 -.125 -125

W2 1234/567 1234/567 0/125 0/125 0/000 0/000
Y3 123/45/67 123/45/67 0/01/25 0/01/25 0/00/00 0/00/00
Z4 1234567 1234567 125 125

Notes:

  1. The x represents a blank.

  2. The W edit code suppresses the farthest left zero of a date field that is five digits long. It also suppresses the three farthest left zeros of a field that is six to eight digits long. The W edit code also inserts slashes (/) between the month, day, and year according to the following pattern:
              nn/nnn 
              nnnn/nn
              nnnn/nnn
              nnnn/nn/nn
  3. The Y edit code suppresses the farthest left zero of a date field that is three to six digits long or eight digits long. It also suppresses the two farthest left zeros of a field that is seven positions long. The Y edit code also inserts slashes (/) between the month, day, and year according to the following pattern:
              nn/n 
              nn/nn 
              nn/nn/n 
              nn/nn/nn 
              nnn/nn/nn 
              nn/nn/nnnn 
    If the DATE keyword is specified with EDTCDE(Y), the separator character used is the job attribute, DATSEP at run time. The slash (/) is the default DATSEP.

  4. The Z edit code removes the sign (plus or minus) and suppresses leading zeros.

Note: the maximum length of a field is set to 132 characters by default, but this can be changed by applying the following modifications and recompiling the programs when required:

Library DSMPY file QXML member DSM

RPGLE program D_DSM

D cDSM_MAX_FLD_LENGTH_A...
D C const(132)

D dsm_dataA_t S 132A based(pDummy)

RPGLE program D_DSMPYT

D python_dtaA_t...
D S 132A based(pDummy)

Python script DSMSUP:

self._dsmCrtText = _DSM_srvPgm.proc('DSMPYT_f_dsmCrtText',('c', 1),(('i', 4),('i', 4),('i', 4),('c', 132),('i', 4),('c', 20),))

self._dsmSetFldDtaA = _DSM_srvPgm.proc('DSMPYT_f_dsmSetFldDtaA',('c', 1),(('i', 4),('c', 20),('c', 132),))

self._dsmGetFldDtaA = _DSM_srvPgm.proc('DSMPYT_f_dsmGetFldDtaA',('c', 1),(('i', 4),('c', 20),('c', 132),))

 

Text (Label): output only field that contains a constant alphanumeric text. Creation parameters are: row, column, text string and optional length. If not specified, then the right hand trimmed length of the text string is used.

Msg (Message): the last line of a screen or window is reserved for messages which can be added (append one) or removed (delete all) at will. Use PAGEUP or PAGEDOWN to scroll through the messages.

Color: BLUE, GREEN, PINK, RED, TURQUOISE, WHITE or YELLOW. Most 5250 emulators can remap the colors so no specific RGB values apply.

nonDisplay: this attribute is useful to define hidden fields, like password inputs.

show: displays the object and waits for user input, it returns the command key pressed.

Command keys:
CMDKEY_F1 thru CMDKEY_F24, CMDKEY_LIGHT_PEN, CMDKEY_AUTO_ENTER, CMDKEY_AUTO_ENTER, CMDKEY_PA1, CMDKEY_PA2, CMDKEY_PA3, CMDKEY_CLEAR, CMDKEY_ENTER, CMDKEY_HELP, CMDKEY_PAGEUP, CMDKEY_PAGEDOWN, CMDKEY_PRINT, CMDKEY_BACKSPACE, CMDKEY_UNKNOWN

Command keys F1 to F24, depending on the 5250 emulation being used, can generate hot spots or mouse clickable events that return the value of the corresponding key as if it had been pressed.

 

Other attributes and actions are self explanatory but you can see them in more detail following the example given below.

 

Example: test_py.py commented


import dsmsup as dsm # import the DSM module
# =============================================
#  Create a password dialog
# =============================================
p = dsm.Screen() # p is now a screen object

p.addText(10, 10, 'Enter password:') # constant string at row 10 col 10
pwd = p.addFieldA(10, 26, 10) # alpha in/output field at 10,26 length=10 chars
pwd.nonDisplay(dsm.TRUE) # make the pwd field invisible

# view how this first screen looks down below, at the end of the code

# =============================================
#  Create another screen object
# =============================================
s = dsm.Screen() # s is another screen

# ---------------------------------------------
#  Add some text and fields to the screen
# ---------------------------------------------

#  Add the headline
headline  = s.addText(2, 27, ' - Python & DSM - Demo - ', 25) # heading text at 2,27
headline.color(dsm.WHITE) # change the heading color to white
headline.reverseImage(dsm.TRUE) # white background, black text

# Add subtitle
subTitle  = s.addText(5, 4, 'Type input, press ENTER:') # more static text
subTitle.color(dsm.BLUE)
# Add some input fields
titleText = s.addText(7,  4, 'Title      :')
titleInp  = s.addFieldA(7, 17, 25) # another alpha field
titleInp.color(dsm.YELLOW)
titleInp.set('We are the champions') # set the field contents

interText = s.addText(8,  4, 'Interpreter:')
interInp  = s.addFieldA(8, 17, 25)
interInp.color(dsm.RED)
interInp.upperCase(dsm.TRUE) # whatever is typed is shown in uppercase
interInp.set('Queen')

totalText = s.addText(10,  4, 'Total      :')
# numeric only field at 10,17 in screen s, format= 99999.99
totalInp  = s.addFieldN(10, 17, 7, 2, 'L')
totalInp.reverseImage(dsm.TRUE)
totalInp.set(12.3) # set value of numeric field, will appear as 12.30
currency  = s.addText(10, 27, 'US-$')

#  Add command keys
line = s.addText(22, 3, ' ', 76)
line.underlined(dsm.TRUE) # add a line in row 22
line.color(dsm.BLUE) # and make it blue
F3 = s.addText(23,  4, 'F3=Exit') # hint the use of the PF keys
F3.color(dsm.BLUE)
F8 = s.addText(23, 14, 'F8=Position Cursor') 
F8.color(dsm.BLUE)
F9 = s.addText(23, 35, 'F9=Send message')
F9.color(dsm.BLUE)
F10= s.addText(23, 53, 'F10=Capture Screen')
F10.color(dsm.BLUE)

# ---------------------------------------------
#  Send a message to the screen
# ---------------------------------------------
s.addMsg('mailto:thomas.raddatz@tools400.de') # message appears in the last screen line

# ---------------------------------------------
#  Request password
# ---------------------------------------------
cmdKey = ''

cmdKey = p.show() # show screen p and wait for user input

if cmdKey == dsm.CMDKEY_ENTER and pwd.get() == 'DSM': 

# ---------------------------------------------
#  Show the screen and wait for a command key
# ---------------------------------------------

   while cmdKey != dsm.CMDKEY_F3: # loop until F3 is pressed
      cmdKey = s.show()
      s.rmvMsg()

      if cmdKey == dsm.CMDKEY_F9: # did the user press F9?
         s.addMsg('Just just pressed F9')
      elif cmdKey == dsm.CMDKEY_F8: # or was it F8?
         # rc = dsmPosCsr(hScreen, 'INP_3')
         totalInp.setCursor() # move the cursor to the totalInp field
         s.addMsg('Cursor set to TOTAL field')
      elif cmdKey == dsm.CMDKEY_F10: # F10 ?
         c=s.capture() # capture the whole screen
         print '*** Captured ***'
         for r in range(c.rows):
             print r, ":", c.row[r]
         print '*** Captured ***'
         s.addMsg('Screen captured')
      else:
         s.addMsg('Press F3 to exit the program')

# ---------------------------------------------
#  Get user input
# ---------------------------------------------
   inp1 = titleInp.get() # get the value of the in/out fields
   inp2 = interInp.get()
   inp3 = totalInp.get()

# ---------------------------------------------
#  Show, what the user entered
# ---------------------------------------------
   print 'The key pressed was    : ', cmdKey
   print 'Input of field INP_1 is: ', inp1
   print 'Input of field INP_2 is: ', inp2
   print 'Input of field INP_3 is: ', inp3
else:
# =============================================
#  Create an error dialog
# =============================================
   e = dsm.Screen() # yet another screen

   t = e.addText(10, 10, ' Sorry, wrong password. Try password: DSM (must be upper case)', 63)
   t.color(dsm.RED)
   t.reverseImage(dsm.TRUE)

   e.show()

   e.close()

# ---------------------------------------------
#  Close screen objects, free ressources
# ---------------------------------------------
s.close() # destroy the screen objects
p.close()

# Note that screen colors might be different, they depend on your emulation software
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
         Enter password:                                                         
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
 mailto:thomas.raddatz@tools400.de                                              
                                                                                 
                           - Python & DSM - Demo -                              
                                                                                
                                                                                
   Type input, press ENTER:                                                     
                                                                                
   Title      : We are the champions                                            
   Interpreter: Queen                                                           
                                                                                
   Total      :    12.30  US-$                                                  
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
                                                                                
   F3=Exit   F8=Position Cursor   F9=Send message   F10=Capture Screen          
 mailto:thomas.raddatz@tools400.de                                              
 

 

History

 

Back in March 2004, I (Denes Lengyel) came across iSeries Python while searching for tools that could be used to bring the iSeries and the Windows PC worlds closer together. I noticed the lack of interactive screen I/O on this port of Python and tried to get people involved in creating one based on DSM, which I knew about, through the iSeriesPython forum.

Well, that seed did not fall in fertile soil and due to my lack of knowledge of the C language I had to abandon it. Continuing my search I visited Euphoria, Rebol, MI and many other interesting alternatives which did not quite fill the Python void I had. Later I stumbled on to Thomas Raddatz' site and in March 2005 I contacted him with the idea of using his DSM expertise to give Python on the iSeries a much needed interface. Obviously he was very enthusiastic about it, otherwise you would not be reading these lines.

After sorting out some interfacing obstacles between the C based Python and the RPG based DSM, many hours of testing and e-mailing back and forth, Thomas was able to modify his program to work with Python on the iSeries. We hope you will enjoy using it, we certainly enjoyed bringing it to life. First public release was 221 in April 2005.

 

Denes Lengyel and Thomas Raddatz.

 

License

 

DSMPy is available under the GNU GPL license.