DSMPy
Dynamic Screen Manager for iSeries Python
Index
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.
Current version: 2.2.1
Download DSM.zip file to your PC. Unzip in a temp directory.You should have the following files:
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.
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:
|
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
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.
DSMPy is available under the GNU GPL license.