Annotation of os2sdk/demos/examples/monitors/monitors.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Example of DOSMONOPEN, DOSGETINFOSEG, DOSMONREG,
                      3:  *           DOSMONREAD, DOSMONWRITE, DOSMONCLOSE usage.
                      4:  *
                      5:  * Shows how to:
                      6:  *
                      7:  *     Obtain a keyboard monitor handle, get the handle of the
                      8:  *     current foreground screen group, register a pair of i/o
                      9:  *     buffers for the current screen group, move data through
                     10:  *     the i/o buffers, and finally close connection with the keyboard.
                     11:  *
                     12:  * Notes:
                     13:  *
                     14:  *     This program will issue a popup every time the F10 key is pressed.
                     15:  *     Pressing escape will terminate the program.
                     16:  *     While it is not particularly useful, it does demonstrate a use of
                     17:  *     monitors, and proper use of associated monitor calls and structures.
                     18:  *
                     19:  *     The first 16 bytes of a monitor buffer are devoted to the
                     20:  *     header, as described by the MonBuff structure below.  Prior to
                     21:  *     registering, the first word (bufflen) must be set to the size
                     22:  *     of the entire buffer itself.  The entire buffer includes the
                     23:  *     header (16 bytes) and room for at least one data record (16 bytes
                     24:  *     in the case of the keyboard device driver), so the minimum size
                     25:  *     for this example would be 32 bytes (see MINBUFFSIZE above);
                     26:  *     however, some drivers may have slightly different requirements,
                     27:  *     in which case you should use the method described next, rather than
                     28:  *     assuming some fixed length.
                     29:  *
                     30:  *     If you wish to monitor a device driver whose data record size
                     31:  *     is unknown, pick a convenient size and attempt a call to DOSMONREG.
                     32:  *     If it fails due to ERROR_NOT_ENOUGH_MEMORY, examine the 2nd word
                     33:  *     of your buffer, since it will now contain the size of the driver's
                     34:  *     buffer (ddbufflen in the example).  Allocate buffer(s) which can
                     35:  *     hold a data record of that size (in addition to the 16-byte header)
                     36:  *     and re-register your buffer(s).  If the same error occurs, then
                     37:  *     there is simply insufficient resources to support another monitor.
                     38:  *
                     39:  *     Note the MonBuff header structure does not define the monitor buffer
                     40:  *     beyond the header, because data records (KeyPackets in this example)
                     41:  *     are transferred to and from the buffers by DOSMONREAD and DOSMONWRITE.
                     42:  *     You should not attempt to read or write that area directly, nor should
                     43:  *     you modify any part of the header after a successful DOSMONREG.
                     44:  *
                     45:  *     To maintain a rapid flow of data through any chain of monitors,
                     46:  *     DOSMONREAD and DOSMONWRITE operations should be done without any
                     47:  *     intervening slow operations or system calls. If necessary, dedicate
                     48:  *     a thread to the monitor stream, and raise its priority.
                     49:  *
                     50:  * Makefile:
                     51:  *
                     52:  *     LIB=\lib
                     53:  *     INC=\include
                     54:  *     OPT=-AL -G2 -Zi -Lp -Ox -Zp -I$(INC)
                     55:  *
                     56:  *     monitors.exe:   monitors.c monitors
                     57:  *                  cl $(OPT) monitors.c
                     58:  *
                     59:  *
                     60:  * To Run:
                     61:  *          detach monitors
                     62:  *
                     63:  */
                     64: 
                     65: #include <malloc.h>            /* for malloc() declaration */
                     66: #include <doscalls.h>
                     67: #include <subcalls.h>
                     68: 
                     69: 
                     70: #define CON            0               /* Handle for the console device */
                     71: 
                     72: #define NOPREFERENCE   0               /* DOSMONREG constants - */
                     73: #define FRONT          1                /* where in the monitor chain */
                     74: #define BACK           2                /* do we want to be installed? */
                     75: 
                     76: #define WAIT           0               /* DOSMONREAD and KBDCHARIN constants - */
                     77: #define NOWAIT         1                /* should we wait for a key? */
                     78: 
                     79: #define THISTHREADONLY 0               /* DOSEXIT constants - */
                     80: #define ALLTHREADS     1                /* who gets terminated? */
                     81: 
                     82: #define NOERROR        0               /* More DOSEXIT constants - */
                     83: #define ERROR          1                /* what to return for error code? */
                     84: 
                     85: #define ESCAPE         27              /* ASCII constant */
                     86: #define F10            68              /* SCAN code constant */
                     87: 
                     88: #define RELEASE        0x40            /* bit mask to distinguish */
                     89:                                        /* key press from key release */
                     90: 
                     91: #define MINBUFFSIZE    64              /* size for monitor buffers */
                     92:                                        /* 64 is minimum, 128 recommended */
                     93: 
                     94: struct GDTInfoArea{                    /* structure for global infoseg */
                     95:         unsigned long   time;
                     96:         unsigned long   milliseconds;
                     97:         unsigned char   hours;
                     98:         unsigned char   minutes;
                     99:         unsigned char   seconds;
                    100:         unsigned char   hundreths;
                    101:         unsigned        timezone;
                    102:         unsigned        timer_interval;
                    103:         unsigned char   day;
                    104:         unsigned char   month;
                    105:         unsigned        year;
                    106:         unsigned char   day_of_week;
                    107:         unsigned char   major_version;
                    108:         unsigned char   minor_version;
                    109:         unsigned char   revision_number;
                    110:         unsigned char   current_screen_group;
                    111:         unsigned char   max_num_of_screengrps;  
                    112:         unsigned char   huge_selector_shift_count;
                    113:         unsigned char   protect_mode_indicator;
                    114:        unsigned        foreground_process_id;
                    115:         unsigned char   dynamic_variation_flag;
                    116:         unsigned char   maxwait;
                    117:         unsigned        minimum_timeslice;
                    118:         unsigned        maximum_timeslice;
                    119:        unsigned        boot_drive;
                    120:        unsigned char   reserved[32];
                    121:  };
                    122: 
                    123: struct CharPacket {                    /* substructure of KeyPacket */
                    124:        unsigned char   asc;
                    125:        unsigned char   scan;
                    126:        unsigned char   status;
                    127:        unsigned char   dshift;
                    128:        unsigned        shift;
                    129:        unsigned long   time;
                    130: };
                    131: 
                    132: struct KeyPacket {                     /* KBD monitor data record */
                    133:        unsigned        mnflags;
                    134:        struct CharPacket cp;
                    135:        unsigned        ddflags;
                    136: };
                    137: 
                    138: struct MonBuff {                       /* generic monitor buffer header */
                    139:        unsigned        bufflen;
                    140:        unsigned        ddbufflen;
                    141:        unsigned char   dispatch[12];
                    142: };
                    143: 
                    144: 
                    145: unsigned       KBDHandle;           /* keyboard handle from monitor open */
                    146: 
                    147: struct MonBuff *InBuff, *OutBuff;     /* buffers for monitor read/writes */
                    148: 
                    149: 
                    150:                                        /* message strings */
                    151: char *startMsg[] = {
                    152:            "�������������������������������������������������������Ŀ",
                    153:            "�                                                       �",
                    154:            "�             Example Monitor installed                 �",
                    155:            "�                                                       �",
                    156:            "�               press Esc to terminate                  �",
                    157:            "�                                                       �",
                    158:            "���������������������������������������������������������",
                    159:            0};
                    160: 
                    161: char *intMsg[] = {
                    162:            "�������������������������������������������������������Ŀ",
                    163:            "�                                                       �",
                    164:            "�       <<<  The F10 key has been struck  >>>           �",
                    165:            "�                                                       �",
                    166:            "�             press any key to continue                 �",
                    167:            "�                                                       �",
                    168:            "���������������������������������������������������������",
                    169:            0};
                    170: 
                    171: 
                    172: main()
                    173: {
                    174:        struct KeyPacket  keybuff;
                    175:        struct GDTInfoArea  *gdt;
                    176:        struct KeyData  dummy;
                    177: 
                    178:        unsigned short  count;      /* chars in monitor read/write buffer */
                    179:        unsigned gdt_descriptor, ldt_descriptor;   /* infoseg descriptors */
                    180:        unsigned waitflag = 1;                         /* flag for popups */
                    181:        unsigned short  row, col = 3;          /* where to draw popup box */
                    182:        unsigned short  length;           /* length of lines in popup box */
                    183:        char **msg;                                /* to display messages */
                    184:        char *pc;                                   /* to test characters */
                    185: 
                    186: 
                    187:        /* initialize this value */
                    188:        for ( length = 0, pc = *intMsg; *pc; pc++, length++)
                    189:            ;
                    190: 
                    191:        /* allocate space for monitor read/write buffers */
                    192:        InBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
                    193:        OutBuff = (struct MonBuff *)malloc(MINBUFFSIZE);
                    194: 
                    195:        /* prepare buffer headers for registration process */
                    196:        InBuff->bufflen = MINBUFFSIZE;
                    197:        OutBuff->bufflen = MINBUFFSIZE;
                    198: 
                    199:        /* obtain a handle for registering buffers */
                    200:        DOSMONOPEN ( "KBD$", &KBDHandle );
                    201: 
                    202:        /* get the descriptor of global infoseg */
                    203:        /* and convert to far pointer so we can */
                    204:        /* get ID of current foreground screen group */
                    205:        DOSGETINFOSEG(&gdt_descriptor, &ldt_descriptor);
                    206:        gdt = (struct GDTInfoArea *)((long)gdt_descriptor << 16);
                    207: 
                    208:        /* register the buffers to be used for monitoring */
                    209:        DOSMONREG ( KBDHandle,
                    210:                    (unsigned char *)InBuff,
                    211:                    (unsigned char *)OutBuff, FRONT,
                    212:                     gdt->current_screen_group );
                    213: 
                    214:        /* Print a banner to show we've started */
                    215:        VIOPOPUP(&waitflag, CON);
                    216:        for (row = 2, msg = startMsg; *msg;)
                    217:            VIOWRTCHARSTR(*msg++, length, row++, col, CON);
                    218:        DOSSLEEP((long)3000);
                    219:        VIOENDPOPUP(CON);
                    220: 
                    221: 
                    222:        /* main loop - read into monitor buffer, examine and take */
                    223:        /* action if "interesting" key, pass on to device driver */
                    224:        for (keybuff.cp.asc = 0; keybuff.cp.asc != ESCAPE;) {
                    225:                count = sizeof(keybuff);
                    226:                DOSMONREAD ( (unsigned char *)InBuff, WAIT,
                    227:                             (unsigned char *)&keybuff, (unsigned far *)&count );
                    228:                if ( ( keybuff.cp.asc == 0 ) &&
                    229:                     ( keybuff.cp.scan == F10 ) &&
                    230:                     ( ! ( keybuff.ddflags & RELEASE ) ) )  {
                    231:                        VIOPOPUP(&waitflag, CON);
                    232:                        for (row = 2, msg = intMsg; *msg;)
                    233:                            VIOWRTCHARSTR(*msg++, length, row++, col, CON);
                    234:                        KBDCHARIN( &dummy, WAIT, CON);
                    235:                        VIOENDPOPUP(CON);
                    236:                }
                    237: 
                    238:                DOSMONWRITE ( (unsigned char *)OutBuff,
                    239:                              (unsigned char *)&keybuff, count );
                    240:        }
                    241: 
                    242:        /* close connection with keyboard */
                    243:        DOSMONCLOSE ( KBDHandle );
                    244: 
                    245:        DOSEXIT ( ALLTHREADS, NOERROR );
                    246: 
                    247: 
                    248: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.