## Display Device Driver Reference for OS/2

[prev][next][parent][TOC]

### Sharing Cursor Exclusion and Enable/Disable Code

Cursor exclusion or disable code is always required when software cursors are in use. The seamless windows driver must use the PM cursor routines. Even when hardware cursors are used, it is recommended that the PM cursor routines be called by the seamless windows driver. This enables the PM driver to accumulate bounding rectangles of modified areas of the screen to support applications such as remote help-desk screen access.

The example of a PM and Windows shared data/code area given previously for XGA demonstrates how cursor exclusion and enable/disable can be implemented .

That example includes the following entries in the shared structure:

         pCursorStatus        dd  ?       ; Byte ptr: bit 0x80 set if sfw cursor
         pExcludeCursor       dd  ?       ; 16:16 addr of exclude cursor function
         pDisableCursor       dd  ?       ; 16:16 addr of disable cursor function
         pEnableCursor        dd  ?       ; 16:16 addr of enable cursor function

In this example, the seamless windows driver has the option of calling the PM cursor routines, but only when a software cursor is in use (by checking the CursorStatus byte). However, in the current XGA implementation, the seamless windows driver calls the PM routines whenever it requests the video FSRamSemaphore and the destination is the screen. (This enables the XGA PM driver to accumulate bounding rectangles of all screen windows.) The seamless windows driver calls the PM ExcludeCursor routine when a hardware cursor is in use, DisableCursor when a software cursor is in use, and EnableCursor whenever the video FSRamSemaphore is cleared and the destination is the screen. For XGA, the cursor exclusion rectangle coordinates are passed on the stack.

The PM cursor functions are accessed by a 16:16 address (entry point) that is exported by the PM driver. At this address is the PM thunk code and the call to the actual PM 32-bit cursor function. The thunk is not compiled but done by hand in the code itself. Sample code from the XGA PM driver is included in the following code fragment:

      ;-----------------------------------------------------------------------
      ;
      ; SeamlessExcludeCursor is the thunked entry point to eddm_ExcludeCursor.
      ; The exclusion rectangle is passed in the following registers in AI coords
      ; (that is, 0,0 is top left of screen).
      ;
      ;       left    top     right   bottom
      ;       cx      dx      si      di
      ;
      ;-----------------------------------------------------------------------
            align   4
      _SeamlessExcludeCursor   proc far

            ; If we are not using a software cursor, we can go for a
            ; fast exit.  We know that the Windows driver always has
            ; fs set up to be the flat selector, so we use it here to
            ; access our 32-bit data.

            mov     eax, offset FLAT:_cursor_data.cd_cursor_status
            test    byte ptr fs:[eax], CURSOR_SOFTWARE
            jz      short SEC_exit

            ; Save ds and es on the 16-bit stack.

            push    ds
            push    es

            ; Get the FLAT selector into ds and es.

            mov     ax, SEG FLAT:_DATA
            mov     ds, ax
            mov     es, ax

            ; Before we start using esp and eip, we must disable interrupts.
            ; An interrupt can damage the top half of the registers
            ; because it thinks we are 16-bit. Touch all the pages we might
            ; access before disabling interrupts (a page fault is non-maskable
            ; and will re-enable interrupts).

            call    SeamlessTouchPages
            cli

            ; Save ss:sp (that is, 16-bit stack) in ebx.

            mov     bx, ss
            rol     ebx, 16
            mov     bx, sp

            ; Set up the 32-bit stack.

            mov     ax, SEG FLAT:_DATA
            mov     ss, ax
            mov     esp, offset FLAT:_SeamlessStack+SEAMLESS _ STACK _ SIZE

             ;   Now   on   32 - bit   stack ,
             ;   save   the   16 - bit   ss : sp   on   the   32 - bit   stack .

             push      ebx

             ;   Jump   into   the   32 - bit   code ,   which   will   call   the   32 - bit   exclusion   code .

             jmp       far   ptr   FLAT : SeamlessExcludeCursor32

       ret _ from _ exclude32 :
             pop       eax
             mov       dx , ax
             rol       eax , 16
             mov       ss , ax
             movzx     esp , dx

             ;   Now   on   16 - bit   stack

             sti

             pop       es
             pop       ds

       SEC _ exit :
             retf
       _ SeamlessExcludeCursor   endp

Note:

Interrupts must be disabled before setting and using esp and eip. This is done to prevent entering 32-bit interrupt handling code when the current task, the DOS session, is known to be 16-bit. In this case, the ip and sp pointers would be set for a 16-bit environment, not 32-bit.

All code pages that might be required by the execution of the shared seamless functions must be present in memory before disabling interrupts. A page fault cannot be taken while in the seamless shared code.

Care must be taken that an STI instruction is not included in the PM cursor routines when executed by a DOS session. Interrupts must remain disabled ( when executed by a DOS session) until returning through the thunk logic and being enabled.

Care also must be taken not to cause any ring transitions (from Ring 3) within the PM code executed from a DOS session. Therefore, there cannot be any operating system calls, etc. executed.