home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / progjour / 1990 / 05 / wserver.asm < prev    next >
Assembly Source File  |  1990-08-03  |  14KB  |  474 lines

  1.         title   window server
  2.         include window.inc
  3.         include asm.inc
  4.  
  5. ; (c) 1990 Soft Advances, all rights reserved.
  6.  
  7. ; server window structure
  8. ;
  9. window_str struc
  10.   w_origin_x    db      ?
  11.   w_origin_y    db      ?
  12.   w_corner_x    db      ?
  13.   w_corner_y    db      ?
  14.   w_parent      dw      ?
  15.   w_sibling     dw      ?
  16.   w_child       dw      ?
  17. window_str ends
  18. ;
  19. w_origin  equ   word ptr w_origin_x
  20. w_corner  equ   word ptr w_corner_x
  21.  
  22.  
  23. ; local variables for WDrawText and clipping procedures
  24. ;
  25. ct_locals struc
  26.   ct_offset             dw      ?       ; text pointer offset
  27.   ct_segment            dw      ?       ;              segment
  28.   ct_windowId           dw      ?       ; active window handle
  29.   ct_attribute          dw      ?
  30. ct_locals ends
  31.  
  32.  
  33.         .data?
  34.  
  35. w_pointers      dd      WINDOW_MAX dup(?)
  36. w_count         dw      ?               ; number of open windows
  37.  
  38. root_child      dw      ?               ; first child for root window
  39.  
  40.  
  41. WRep_s          _WRep   <>
  42. WReq_s          _WReq   <>
  43.  
  44.  
  45.         .code
  46.  extn   save_most,calloc_read,receive_window_request,transmit_window_reply
  47.  extn   write_video_memory
  48.  public poll_server
  49.  
  50.  
  51. ;;      alloc window struct
  52. ;
  53. ;       exit    AX      windowId
  54. ;               DS:SI   window structure
  55. ;               Cf      if no memory or too many windows
  56. ;
  57. alloc_window_struct proc
  58.         mov     ax,w_count[bp]          ; check window count
  59.         cmp     ax,WINDOW_MAX
  60.         jae     aws2                    ;  if too many windows
  61.  
  62.         inc     ax                      ; update window count
  63.         pushm   ax,cx,di
  64.         mov     di,ax
  65.         mov     w_count[bp],ax
  66.  
  67.         mov     cx,size window_str      ; allocate window structure
  68.         call    calloc_read
  69.         jc      aws1                    ;  if no memory
  70.  
  71.         add     di,di                   ; put structure address in table
  72.         add     di,di
  73.         mov     wptr w_pointers[bp+di],si
  74.         mov     wptr w_pointers[bp+di+2],ds
  75. aws1:   popm    di,cx,ax
  76.         ret
  77.  
  78. aws2:   stc
  79.         ret
  80. alloc_window_struct endp
  81.  
  82.  
  83. ;;      clip aunt text
  84. ;
  85. ;       entry   BX      windowId (most distant grandparent)
  86. ;               CX      byte count
  87. ;               DL      column
  88. ;               DH      row
  89. ;               DS:SI   window structure for BX
  90. ;               BP+DI   local variables
  91. ;       uses    AX,BX,CX,DX,SI,DS,DI
  92. ;
  93. clip_aunt_text proc
  94. cat1:   mov     bx,w_sibling[si]        ; process overlapping siblings of most
  95.         cmp     bx,NULL_SIBLING         ;  distant grandparent
  96.         je      cat4                    ;  (if no more siblings)
  97.         call    read_window_struct
  98.  
  99.         cmp     dh,w_origin_y[si]       ; check for overlapping window
  100.         jb      cat1                    ;  if no overlap
  101.         cmp     dh,w_corner_y[si]
  102.         jae     cat1                    ;  if no overlap
  103.         cmp     dl,w_corner_x[si]
  104.         jae     cat1                    ;  if no overlap
  105.  
  106.         mov     ax,cx
  107.         add     al,dl
  108.         cmp     al,w_origin_x[si]
  109.         jb      cat1                    ;  if no overlap
  110.         cmp     dl,w_origin_x[si]
  111.         jae     cat3                    ;  if left overlap
  112.         cmp     al,w_corner_x[si]
  113.         jbe     cat2                    ;  if right overlap
  114.  
  115.         pushm   ax,bx,cx,dx,di,si,ds    ;  else middle overlap
  116.         push    ct_offset[bp+di]        ;   save current state and process
  117.         call    cat3                    ;    exposed right side line fragment,
  118.         popm    ct_offset[bp+di]        ;    then restore and process exposed
  119.         popm    ds,si,di,dx,cx,bx,ax    ;    left side line fragment
  120.  
  121. cat2:   sub     al,w_origin_x[si]       ; here for right overlap
  122.         sub     cx,ax
  123.         jmp     cat1
  124.  
  125. cat3:   mov     al,w_corner_x[si]       ; here for left overlap
  126.         sub     al,dl
  127.         jbe     cat5                    ;  if complete overlap
  128.         add     dl,al                   ;  set new X coordinate (DL=corner_x)
  129.         sub     cx,ax                   ;  adjust byte count and text offset
  130.         add     ct_offset[bp+di],ax
  131.         jmp     cat1
  132.  
  133. cat4:   mov     ax,ct_attribute[bp+di]  ; write text to display memory
  134.         lds     si,dptr ct_offset[bp+di]
  135.         jmp     write_video_memory
  136.  
  137. cat5:   ret
  138. clip_aunt_text endp
  139.  
  140.  
  141. ;;      clip parent text
  142. ;
  143. ;       entry   CX      byte count
  144. ;               DL      column
  145. ;               DH      row
  146. ;               BP+DI   local variables
  147. ;       uses    AX,BX,CX,DX,SI,DS,DI
  148. ;
  149. clip_parent_text proc
  150.         mov     bx,ct_windowId[bp+di]
  151.         call    read_window_struct
  152.  
  153. cpt1:   mov     ax,w_parent[si]
  154.         cmp     ax,NULL_PARENT
  155.         je      clip_aunt_text          ;  if no more ancestors
  156.         mov     bx,ax
  157.         call    read_window_struct
  158.  
  159.         add     dl,w_origin_x[si]
  160.         jc      cpt2                    ;  if outside window limits
  161.         add     dh,w_origin_y[si]
  162.         jc      cpt2                    ;  if outside window limits
  163.  
  164.         cmp     dh,w_corner_y[si]
  165.         jae     cpt2                    ;  if below parent window
  166.         mov     al,w_corner_x[si]
  167.         cmp     dl,al
  168.         jae     cpt2                    ;  if right of parent window
  169.  
  170.         sub     al,dl
  171.         mov     ah,0
  172.         cmp     ax,cx
  173.         jae     cpt1                    ;  if line fits in parent window
  174.         mov     cx,ax                   ;  else clip end of line
  175.         jmp     cpt1
  176.  
  177. cpt2:   ret
  178. clip_parent_text endp
  179.  
  180.  
  181. ;;      clip sibling text
  182. ;
  183. ;       entry   CX      byte count
  184. ;               DL      column
  185. ;               DH      row
  186. ;               DS:SI   active window structure
  187. ;               BP+DI   local variables
  188. ;       uses    AX,BX,CX,DX,SI,DS,DI
  189. ;
  190. clip_sibling_text proc
  191. cbt1:   mov     bx,w_sibling[si]
  192.         cmp     bx,NULL_SIBLING
  193.         je      clip_parent_text        ;  if no more siblings
  194.         call    read_window_struct
  195.  
  196.         cmp     dh,w_origin_y[si]       ; check for overlapping windows
  197.         jb      cbt1                    ;  if no overlap
  198.         cmp     dh,w_corner_y[si]
  199.         jae     cbt1                    ;  if no overlap
  200.         cmp     dl,w_corner_x[si]
  201.         jae     cbt1                    ;  if no overlap
  202.  
  203.         mov     ax,cx
  204.         add     al,dl
  205.         cmp     al,w_origin_x[si]
  206.         jb      cbt1                    ;  if no overlap
  207.         cmp     dl,w_origin_x[si]
  208.         jae     cbt3                    ;  if left overlap
  209.         cmp     al,w_corner_x[si]
  210.         jbe     cbt2                    ;  if right overlap
  211.  
  212.         pushm   ax,bx,cx,dx,di,si,ds    ;  else middle overlap
  213.         push    ct_offset[bp+di]        ;   save current state and process
  214.         call    cbt3                    ;    exposed right side line fragment,
  215.         popm    ct_offset[bp+di]        ;    then restore and process exposed
  216.         popm    ds,si,di,dx,cx,bx,ax    ;    left side line fragment
  217.  
  218. cbt2:   sub     al,w_origin_x[si]       ; here for right overlap
  219.         sub     cx,ax
  220.         jmp     cbt1
  221.  
  222. cbt3:   mov     al,w_corner_x[si]       ; here for left overlap
  223.         sub     al,dl
  224.         jbe     cbt4                    ;  if complete overlap
  225.         add     dl,al                   ;  set new X coordinate (DL=corner_x)
  226.         sub     cx,ax                   ;  adjust byte count and text offset
  227.         add     ct_offset[bp+di],ax
  228.         jmp     cbt1
  229.  
  230. cbt4:   ret
  231. clip_sibling_text endp
  232.  
  233.  
  234. ;;      clip window text
  235. ;
  236. ;       entry   BX      windowId (start with active window)
  237. ;               CX      byte count
  238. ;               DL      column
  239. ;               DH      row
  240. ;               BP+DI   local variables
  241. ;       uses    AX,BX,CX,DX,SI,DS,DI
  242. ;
  243. clip_window_text proc
  244.         call    read_window_struct
  245.         jc      cwt1                    ;  if bad windowId
  246.         add     dl,w_origin_x[si]
  247.         jc      cwt1                    ;  if outside window limits
  248.         add     dh,w_origin_y[si]
  249.         jc      cwt1                    ;  if outside window limits
  250.  
  251.         cmp     dh,w_corner_y[si]
  252.         jae     cwt1                    ;  if below window
  253.         mov     al,w_corner_x[si]
  254.         cmp     dl,al
  255.         jae     cwt1                    ;  if right of window
  256.  
  257.         sub     al,dl
  258.         mov     ah,0
  259.         cmp     ax,cx
  260.         jae     clip_sibling_text       ;  if line fits in parent window
  261.         mov     cx,ax                   ;  else clip end of line
  262.         jmp     clip_sibling_text
  263.  
  264. cwt1:   ret
  265. clip_window_text endp
  266.  
  267.  
  268. ;;      create window
  269. ;
  270. ;       entry   DS:SI   request packet
  271. ;       uses    AX,BX,CX,DX,SI,DS
  272. ;
  273. create_window proc
  274.         mov     bx,WReq_windowId[si]    ;  (get parent window)
  275.         mov     cx,WReq_y_x[si]
  276.         mov     dx,WReq_height_width[si]
  277.         call    create_window_primitive
  278.         jc      cwd1                    ;  if no storage or bad coordinate
  279.  
  280.         call    reply_packet_read
  281.         mov     WRep_code[si],W_Reply
  282.         mov     WRep_windowId[si],ax
  283.         jmp     transmit_window_reply
  284.  
  285. cwd1:   call    reply_packet_read
  286.         mov     WRep_code[si],W_Error
  287.         mov     WRep_error_code[si],ax
  288.         jmp     transmit_window_reply   ;\
  289. create_window endp
  290.  
  291.  
  292. ;;      create window primitive
  293. ;
  294. ;       entry   BX      parent window
  295. ;               CL      left most column (parent relative)
  296. ;               CH      top most row (parent relative)
  297. ;               DL      width
  298. ;               DH      height
  299. ;       exit    AX      windowId or error code
  300. ;               Cf      if no storage or bad coordinate
  301. ;       uses    SI,DS
  302. ;
  303. create_window_primitive proc
  304.         add     dh,ch                   ; window corner is lower right y+1 x+1
  305.         jc      cwp1                    ;  if vertical overflow
  306.         add     dl,cl
  307.         jc      cwp1                    ;  if horizontal overflow
  308.         call    alloc_window_struct
  309.         jc      cwp2                    ;  if no storage
  310.  
  311.         mov     w_parent[si],bx
  312.         mov     w_origin[si],cx
  313.         mov     w_corner[si],dx
  314.         mov     w_child[si],NULL_WINDOW
  315.         mov     w_sibling[si],NULL_WINDOW
  316.         jmp     link_new_sibling
  317.  
  318. cwp1:   mov     ax,BadValue
  319.         ret
  320. cwp2:   mov     ax,BadAlloc
  321.         ret
  322. create_window_primitive endp
  323.  
  324.  
  325. ;;      destroy window
  326. ;
  327. destroy_window proc
  328.         ret
  329. destroy_window endp
  330.  
  331.  
  332. ;;      link new sibling
  333. ;
  334. ;       entry   AX      new windowId
  335. ;               BX      parent windowId
  336. ;       uses    SI,DS
  337. ;
  338. link_new_sibling proc
  339.         push    bx
  340.         cmp     bx,NULL_WINDOW
  341.         je      lns3                    ; if child of root window
  342.  
  343.         call    read_window_struct      ; else child of normal window
  344.         mov     bx,w_child[si]
  345.         cmp     bx,NULL_WINDOW
  346.         je      lns2                    ; if first child of this window
  347. lns1:   call    read_window_struct      ; else find youngest sibling
  348.         mov     bx,w_sibling[si]
  349.         cmp     bx,NULL_WINDOW
  350.         jne     lns1
  351.         mov     w_sibling[si],ax        ; and link new sibling
  352.         jmp     lns4
  353.  
  354. lns2:   mov     w_child[si],ax
  355.         jmp     lns4
  356.  
  357. lns3:   mov     bx,root_child[bp]       ; set first generation child
  358.         cmp     bx,NULL_WINDOW
  359.         jne     lns1                    ;  if not the first child of root
  360.         mov     root_child[bp],ax
  361.  
  362. lns4:   pop     bx
  363.         ret
  364. link_new_sibling endp
  365.  
  366.  
  367. ;;      poll server
  368. ;
  369. ;       uses    AX
  370. ;
  371. poll_server proc
  372.         call    save_most
  373.         mov     cx,SIZEOF_WREQ
  374.         push    ss
  375.         pop     ds
  376.         lea     si,WReq_s[bp]
  377.         call    receive_window_request
  378.         jc      psv1                    ;  if no request pending
  379.         call    process_server_request
  380. psv1:   ret
  381. poll_server endp
  382.  
  383.  
  384. ;;      process server request
  385. ;
  386. ;       entry   DS:SI   request packet
  387. ;       exit
  388. ;       uses    AX
  389. ;
  390. process_server_request proc
  391.         mov     al,WReq_code[si]
  392.         cmp     al,W_CreateWindow
  393.         je      psr1                    ; if window open
  394.         cmp     al,W_DestroyWindow
  395.         je      psr2                    ; if window close
  396.         cmp     al,W_Text
  397.         je      psr3                    ; if text output
  398.         ret                             ; else ignore unknown requests
  399.  
  400. psr1:   jmp     create_window
  401. psr2:   jmp     destroy_window
  402. psr3:   jmp     window_text
  403. process_server_request endp
  404.  
  405.  
  406. ;;      read window struct
  407. ;
  408. ;       entry   BX      windowId
  409. ;       exit    DS:SI   window structure
  410. ;               Cf      if bad windowId
  411. ;
  412. read_window_struct proc
  413.         push    cx
  414.         cmp     bx,WINDOW_MAX
  415.         jae     rws2                    ; if bad windowId
  416.         mov     si,bx
  417.         add     si,si
  418.         add     si,si
  419.         lds     si,w_pointers[bp+si]
  420.         mov     cx,ds
  421.         jcxz    rws2                    ; if bad windowId
  422. rws1:   pop     cx
  423.         ret
  424. rws2:   stc
  425.         jmp     rws1
  426. read_window_struct endp
  427.  
  428.  
  429. ;;      reply packet read
  430. ;
  431. ;       exit    DS:SI   reply packet pointer
  432. ;               CX      byte count
  433. ;
  434. reply_packet_read proc
  435.         push    ss
  436.         pop     ds
  437.         lea     si,WRep_s[bp]
  438.         mov     cx,SIZEOF_WREP
  439.         ret
  440. reply_packet_read endp
  441.  
  442.  
  443. ;;      window text
  444. ;
  445. ;       entry   DS:SI   window request packet
  446. ;       uses    AX,BX,CX,DX,DI,SI,DS,ES
  447. ;
  448. window_text proc
  449.         sub     sp,size ct_locals
  450.         mov     di,sp
  451.         sub     di,bp
  452.  
  453.         mov     ax,WReq_windowId[si]    ; set local variables
  454.         mov     ct_windowId[bp+di],ax
  455.  
  456.         mov     ax,WReq_attribute[si]
  457.         mov     ct_attribute[bp+di],ax
  458.  
  459.         mov     cx,WReq_count[si]       ; receive window text
  460.         lea     si,WReq_text[si]
  461.         call    receive_window_request
  462.         jc      wdt1                    ;  if internal error
  463.  
  464.         mov     ct_offset[bp+di],si     ; set text pointer
  465.         mov     ct_segment[bp+di],ds
  466.  
  467.         call    clip_window_text        ; clip text and write to video memory
  468.  
  469. wdt1:   lea     sp,[bp+di+size ct_locals]
  470.         ret
  471. window_text endp
  472.  
  473.         end
  474.