Subversion Repositories Kolibri OS

Rev

Rev 556 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                   ;;
  3. ;;    IRC CLIENT for KolibriOS                       ;;
  4. ;;                                                   ;;
  5. ;;    License: GPL / See file COPYING for details    ;;
  6. ;;    Copyright 2004 (c) Ville Turjanmaa             ;;
  7. ;;    Copyright 2009 (c) CleverMouse                 ;;
  8. ;;                                                   ;;
  9. ;;    Compile with FASM for Kolibri                  ;;
  10. ;;                                                   ;;
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12.  
  13. version equ '0.6'
  14.  
  15.  
  16. ;__DEBUG__ equ 1
  17. ;__DEBUG_LEVEL__ equ 1
  18.  
  19. use32
  20.  
  21.                 org     0x0
  22.  
  23.                 db      'MENUET01'              ; 8 byte id
  24.                 dd      0x01                    ; required os
  25.                 dd      START                   ; program start
  26.                 dd      initialized_size        ; program image size
  27.                 dd      0x100000                ; required amount of memory
  28.                 dd      0x100000
  29.                 dd      0,0
  30.  
  31. include "../../../macros.inc"
  32. include "../../../proc32.inc"
  33. include "../../../develop/libraries/network/network.inc"
  34. include "dll.inc"
  35. ;include "fdo.inc"
  36. include "eth.inc"
  37. ;include "lang.inc"
  38.  
  39. ; connection statuses
  40. STATUS_DISCONNECTED = 0 ; disconnected
  41. STATUS_RESOLVING    = 1 ; resolving server name
  42. STATUS_CONNECTING   = 2 ; connecting to server
  43. STATUS_CONNECTED    = 3 ; connected
  44. ; where to display status
  45. STATUS_X = 25 + 22*6
  46. STATUS_Y = 183 + 7*12
  47.  
  48. ; supported encodings
  49. CP866 = 0
  50. CP1251 = 1
  51. UTF8 = 2
  52. ; where to display encoding
  53. ENCODING_X = 25 + 15*6
  54. ENCODING_Y = 183 + 3*12
  55.  
  56. def_server_name db      'kolibrios.org',0                 ; default server name
  57.  
  58. user_nick       dd      12                                ; length
  59.                 db      'kolibri_user           '         ; string
  60. user_nick_max = $ - user_nick - 4
  61.  
  62. user_real_name  dd      14                                ; length
  63.                 db      'KolibriOS User         '         ; string
  64. user_real_name_max = $ - user_real_name - 4
  65.  
  66.  
  67. START:                          ; start of execution
  68.  
  69.     stdcall dll.Load, @IMPORT
  70.     test eax,eax
  71.     jnz  exit
  72.  
  73.     mov  eax,40
  74.     mov  ebx,11000111b
  75.     mcall
  76.     mcall 60, 1, ipcbuf, ipcbuf.size
  77.     mcall 9, 0xe0000, -1
  78.     mov  eax,[ebx+process_information.PID]
  79.     mov  [main_PID],eax
  80.  
  81.         mov     esi, def_server_name
  82.         mov     edi, irc_server_name
  83. @@:
  84.         lodsb
  85.         stosb
  86.         test    al, al
  87.         jnz     @b
  88.  
  89.     mov  edi,I_END
  90.     mov  ecx,60*120
  91.     mov  al,32
  92.     cld
  93.     rep  stosb
  94.  
  95.     mov  eax,[rxs]
  96.     imul eax,11
  97.     mov  [pos],eax
  98.  
  99.     mov  ebp,0
  100.     mov  edx,I_END
  101.  
  102. redraw:                         ; redraw
  103.     call draw_window            ; at first, draw the window
  104.  
  105. still:
  106.  
  107.     mov  eax,10                 ; wait here for event
  108.     mcall
  109.  
  110.     dec  eax                    ; redraw
  111.     je   redraw
  112.     dec  eax                    ; key
  113.     je   main_window_key
  114.     dec  eax                    ; button
  115.     je   button
  116.     cmp  al,4
  117.     jz   ipc
  118.  
  119.     call process_network_event
  120.  
  121.     cmp  [I_END+120*60],byte 1
  122.     jne  no_main_update
  123.     mov  [I_END+120*60],byte 0
  124.     mov  edx,I_END
  125.     call draw_channel_text
  126.   no_main_update:
  127.  
  128.     call print_channel_list
  129.  
  130.     jmp  still
  131.  
  132. button:                         ; button
  133.  
  134.     mov  eax,17                 ; get id
  135.     mcall
  136.  
  137.     cmp  ah,1                   ; close program
  138.     jne  noclose
  139. exit:
  140.     or   eax,-1
  141.     mcall
  142.   noclose:
  143.     cmp  ah,21
  144.     jne  no_change_encoding
  145.     cmp  byte[edx-1],0
  146.     jnz  still
  147.     mov  eax,[encoding]
  148.     inc  eax
  149.     mov  edx,msgbox_struct
  150.     mov  byte[edx],al
  151.     mov  byte[edx-1],1 ; msgbox is running
  152.     push mb_stack
  153.     push edx
  154.     call [mb_create]
  155.     push msgbox_func_array
  156.     call [mb_setfunctions]
  157.     jmp  still
  158.   no_change_encoding:
  159.  
  160.     call socket_commands
  161.  
  162.     jmp  still
  163.  
  164. ipc:
  165.     mov  edx,msgbox_struct
  166.     cmp  byte[edx-1],0
  167.     jz   @f
  168.     mov  byte[edx-1],0
  169.     mov  al,[edx]
  170.     dec  eax
  171.     mov  byte[encoding],al
  172.     call update_encoding
  173.     jmp  ipc_done
  174. @@:
  175.     call process_command
  176. ipc_done:
  177.     mov  dword [ipcbuf+4], 8
  178.     jmp  still
  179.  
  180. main_window_key:
  181.  
  182.     mov  eax,2
  183.     mcall
  184.  
  185.     shr  eax,8
  186.  
  187.     cmp  eax,8
  188.     jne  no_bks2
  189.     cmp  [xpos],0
  190.     je   still
  191.     dec  [xpos]
  192.     call print_entry
  193.     jmp  still
  194.    no_bks2:
  195.  
  196.     cmp  eax,20
  197.     jbe  no_character2
  198.     mov  ebx,[xpos]
  199.     mov  [send_string+ebx],al
  200.     inc  [xpos]
  201.     cmp  [xpos],80
  202.     jb   noxposdec
  203.     mov  [xpos],79
  204.   noxposdec:
  205.     call print_entry
  206.     jmp  still
  207.   no_character2:
  208.  
  209.     cmp  eax,13
  210.     jne  no_send2
  211.     cmp  [xpos],0
  212.     je   no_send2
  213.     cmp  [send_string],byte '/'   ; server command
  214.     jne  no_send2
  215.     call process_command
  216.     jmp  still
  217.   no_send2:
  218.  
  219.     jmp  still
  220.  
  221.  
  222. socket_commands:
  223.  
  224.     cmp  ah,22       ; connect
  225.     jnz  tst3
  226.  
  227. ; ignore if status is not "disconnected"
  228.         cmp     [status], STATUS_DISCONNECTED
  229.         jnz     .nothing
  230.  
  231. ; start name resolving
  232.         inc     [status]        ; was STATUS_DISCONNECTED, now STATUS_RESOLVING
  233.         push    gai_reqdata
  234.         push    ip_list
  235.         push    0
  236.         push    0
  237.         push    irc_server_name
  238.         call    [getaddrinfo_start]
  239.         test    eax, eax
  240.         jns     getaddrinfo_done
  241.         call    update_status
  242. .nothing:
  243.         ret
  244.  
  245.   tst3:
  246.  
  247.  
  248.     cmp  ah,23        ; write userinfo
  249.     jnz  tst4
  250.  
  251. ; ignore if status is not "connected"
  252.         cmp     [status], STATUS_CONNECTED
  253.         jnz     .nothing
  254.  
  255. ; create packet in packetbuf
  256.         mov     edi, packetbuf
  257.         mov     edx, edi
  258.         mov     esi, string0
  259.         mov     ecx, string0l-string0
  260.         rep     movsb
  261.         mov     esi, user_real_name+4
  262.         mov     ecx, [esi-4]
  263.         rep     movsb
  264.         mov     al, 13
  265.         stosb
  266.         mov     al, 10
  267.         stosb
  268.         mov     esi, string1
  269.         mov     ecx, string1l-string1
  270.         rep     movsb
  271.         mov     esi, user_nick+4
  272.         mov     ecx, [esi-4]
  273.         rep     movsb
  274.         mov     al, 13
  275.         stosb
  276.         mov     al, 10
  277.         stosb
  278. ; send packet
  279.         xchg    edx, edi
  280.         sub     edx, edi
  281.         mov     esi, edi
  282.         mcall   53, 7, [socket]
  283.     .nothing:
  284.         ret
  285.  
  286.   tst4:
  287.  
  288.  
  289.     cmp  ah,24     ; close socket
  290.     jz   disconnect
  291.   no_24:
  292.  
  293.  
  294.     ret
  295.  
  296. getaddrinfo_done:
  297. ; The address resolving is done.
  298. ; If eax is zero, address is resolved, otherwise there was some problems.
  299.         test    eax, eax
  300.         jz      .good
  301. .disconnect:
  302. ; Change status to "disconnected" and return.
  303.         and     [status], 0
  304.         call    update_status
  305.         ret
  306. .good:
  307. ; We got a list of IP addresses. Try to connect to first of them.
  308.         mov     eax, [ip_list]
  309.         mov     esi, [eax + addrinfo.ai_addr]
  310.         mov     esi, [esi + sockaddr_in.sin_addr]
  311.         push    eax
  312.         call    [freeaddrinfo]
  313.         mcall   53, 5, 0, 6667, , 1
  314.         cmp     eax, -1
  315.         jz      .disconnect
  316. ; Socket has been opened. Save handle and change status to "connecting".
  317.         mov     [socket], eax
  318.         inc     [status]        ; was STATUS_RESOLVING, now STATUS_CONNECTING
  319.         call    update_status
  320.         ret
  321.  
  322. process_network_event:
  323. ; values for status: 0, 1, 2, 3
  324.         mov     eax, [status]
  325.         dec     eax
  326. ; 0 = STATUS_DISCONNECTED - do nothing
  327. ; (ignore network events if we are disconnected from network)
  328.         js      .nothing
  329. ; 1 = STATUS_RESOLVING
  330.         jz      .resolving
  331. ; 2 = STATUS_CONNECTING
  332.         dec     eax
  333.         jz      .connecting
  334. ; 3 = STATUS_CONNECTED
  335.         jmp     .connected
  336. .resolving:
  337. ; We are inside address resolving. Let the network library work.
  338.         push    ip_list
  339.         push    gai_reqdata
  340.         call    [getaddrinfo_process]
  341. ; Negative returned value means that the resolving is not yet finished,
  342. ; and we continue the loop without status change.
  343. ; Zero and positive values are handled by getaddrinfo_done.
  344.         test    eax, eax
  345.         jns     getaddrinfo_done
  346. .nothing:
  347.         ret
  348. .connecting:
  349. ; We are connecting to the server, and socket status has changed.
  350.         mcall   53, 6, [socket]
  351. ; Possible values for status: SYN_SENT=2, SYN_RECEIVED=3, ESTABLISHED=4, CLOSE_WAIT=7
  352. ; First two mean that we are still connecting, and we must continue wait loop
  353. ; without status change.
  354. ; Last means that server has immediately closed the connection,
  355. ; and status becomes "disconnected".
  356.         cmp     eax, 4
  357.         jb      .nothing
  358.         jz      .established
  359.         and     [status], 0
  360.         call    update_status
  361. ; close socket
  362.         mcall   53, 8
  363.         ret
  364. .established:
  365. ; The connection has been established, change status from "connecting" to "connected".
  366.         inc     [status]
  367.         call    update_status
  368. ; Fall through to .connected, because some data can be already in buffer.
  369. .connected:
  370.         call    read_incoming_data
  371. ; Handle closing socket by the server.
  372.         mcall   53, 6, [socket]
  373.         cmp     eax, 4
  374.         jnz     disconnect
  375.         ret
  376.  
  377. disconnect:
  378. ; Release all allocated resources.
  379. ; Exact actions depend on current status.
  380.         mov     eax, [status]
  381.         dec     eax
  382. ; 0 = STATUS_DISCONNECTED - do nothing
  383.         js      .nothing
  384. ; 1 = STATUS_RESOLVING
  385.         jz      .resolving
  386. ; 2 = STATUS_CONNECTING, 3 = STATUS_CONNECTED
  387. ; In both cases we should close the socket.
  388.         mcall   53, 8, [socket]
  389.         jmp     .disconnected
  390. .resolving:
  391. ; Let the network library handle abort of resolving process.
  392.         push    gai_reqdata
  393.         call    [getaddrinfo_abort]
  394. .disconnected:
  395. ; In all cases, set status to "disconnected".
  396.         and     [status], 0
  397.         call    update_status
  398. .nothing:
  399.         ret
  400.  
  401. msgbox_notify:
  402.         inc     byte [msgbox_running]
  403.         mcall   60,2,[main_PID],0,1
  404.         ret
  405.  
  406. print_channel_list:
  407.  
  408.     pusha
  409.  
  410.     mov  eax,13
  411.     mov  ebx,415*65536+6*13
  412.     mov  ecx,27*65536+12*10
  413.     mov  edx,0xffffff
  414.     mcall
  415.  
  416.     mov  eax,4
  417.     mov  ebx,415*65536+27
  418.     mov  ecx,[index_list_1]
  419.     mov  edx,channel_list+32
  420.   newch:
  421.     movzx esi,byte [edx+31]
  422.     and  esi,0x1f
  423.     mcall
  424.     add  edx,32
  425.     add  ebx,12
  426.     cmp  edx,channel_list+32*10
  427.     jbe  newch
  428.  
  429.   no_channel_list:
  430.  
  431.     popa
  432.  
  433.     ret
  434.  
  435.  
  436. print_user_list:
  437.  
  438.     pusha
  439.  
  440.   newtry:
  441.  
  442.     mov  edx,ebp
  443.     imul edx,120*80
  444.     add  edx,120*60+8+I_END
  445.     cmp  [edx],byte 1
  446.     je   nonp
  447.  
  448.     mov  edx,ebp
  449.     imul edx,120*80
  450.     add  edx,120*70+I_END
  451.     mov  edi,edx
  452.  
  453.     mov  eax,[edx-8]
  454.     mov  ebx,[edx-4]
  455.     add  ebx,edx
  456.     sub  ebx,3
  457.     inc  eax
  458.     dec  edx
  459.   newnss:
  460.     inc  edx
  461.     dec  eax
  462.     jz   startuu
  463.   asdf:
  464.     cmp  [edx],word '  '
  465.     jne  nodouble
  466.     inc  edx
  467.   nodouble:
  468.     cmp  [edx],byte ' '
  469.     je   newnss
  470.     inc  edx
  471.     cmp  edx,ebx
  472.     jbe  asdf
  473.     dec  dword [edi-8]
  474.  
  475.     popa
  476.     ret
  477.  
  478.   startuu:
  479.  
  480.     cmp  [edx],byte ' '
  481.     jne  startpr
  482.     inc  edx
  483.   startpr:
  484.  
  485.     pusha
  486.     mov  eax,13
  487.     mov  ebx,415*65536+6*13
  488.     mov  ecx,27*65536+12*10
  489.     mov  edx,0xffffff
  490.     mcall
  491.     popa
  492.  
  493.     mov  eax,4
  494.     mov  ebx,415*65536+27
  495.  
  496.     mov  ebp,0
  497.   newuser:
  498.  
  499.     mov  esi,0
  500.   newusers:
  501.     cmp  [edx+esi],byte ' '
  502.     je   do_print
  503.     inc  esi
  504.     cmp  esi,20
  505.     jbe  newusers
  506.   do_print:
  507.  
  508.     mov  ecx,[index_list_1]
  509.     cmp  [edx],byte '@'
  510.     jne  no_op
  511.     mov  ecx,[index_list_2]
  512.   no_op:
  513.  
  514.     mcall
  515.  
  516.     inc  ebp
  517.     cmp  ebp,10
  518.     je   nonp
  519.  
  520.     add  ebx,12
  521.  
  522.     add  edx,esi
  523.  
  524.     inc  edx
  525.     cmp  [edx],byte ' '
  526.     jne  newuser
  527.     inc  edx
  528.     jmp  newuser
  529.  
  530.   nonp:
  531.  
  532.     popa
  533.  
  534.     ret
  535.  
  536.  
  537. start_user_list_at dd 0x0
  538.  
  539. recode_to_cp866:
  540.         rep     movsb
  541.         ret
  542.  
  543. recode_to_cp1251:
  544.         xor     eax, eax
  545.         jecxz   .nothing
  546.   .loop:
  547.         lodsb
  548.         cmp     al,0x80
  549.         jb      @f
  550.         mov     al,[cp866_table-0x80+eax]
  551.     @@: stosb
  552.         loop    .loop
  553.   .nothing:
  554.         ret
  555.  
  556. recode_to_utf8:
  557.         jecxz   .nothing
  558.   .loop:
  559.         lodsb
  560.         cmp     al, 0x80
  561.         jb      .single_byte
  562.         and     eax, 0x7F
  563.         mov     ax, [utf8_table+eax*2]
  564.         stosw
  565.         loop    .loop
  566.         ret
  567.   .single_byte:
  568.         stosb
  569.         loop    .loop
  570.   .nothing:
  571.         ret
  572.  
  573. recode:
  574.         mov     eax, [encoding]
  575.         jmp     [recode_proc+eax*4]
  576.  
  577. process_command:
  578.  
  579.     pusha
  580.  
  581.     mov  eax,[xpos]
  582.     mov  [send_string+eax+0],byte 13
  583.     mov  [send_string+eax+1],byte 10
  584.  
  585.     mov  eax,[rxs]
  586.     imul eax,11
  587.     mov  [pos],eax
  588.     mov  eax,[send_to_channel]
  589.     imul eax,120*80
  590.     add  eax,I_END
  591.     mov  [text_start],eax
  592.  
  593.     cmp  [send_string],byte '/'   ; server command
  594.     je   server_command
  595.  
  596. ; Ignore data commands when not connected.
  597.         cmp     [status], STATUS_CONNECTED
  598.         jnz     sdts_ret
  599.  
  600.     mov  bl,13
  601.     call print_character
  602.     mov  bl,10
  603.     call print_character
  604.     mov  bl,'<'
  605.     call print_character
  606.  
  607.     mov  esi,user_nick+4
  608.     mov  ecx,[user_nick]
  609.   newnp:
  610.     mov  bl,[esi]
  611.     call print_character
  612.     inc  esi
  613.     loop newnp
  614.  
  615.     mov  bl,'>'
  616.     call print_character
  617.     mov  bl,' '
  618.     call print_character
  619.  
  620.     mov  ecx,[xpos]
  621.     mov  esi,send_string
  622.   newcw:
  623.     mov  bl,[esi]
  624.     call print_character
  625.     inc  esi
  626.     loop newcw
  627.  
  628.     mov  eax,dword [send_to_channel]
  629.     shl  eax,5
  630.     add  eax,channel_list
  631.     mov  esi,eax
  632.  
  633.     mov  edi,send_string_header+8
  634.     movzx ecx,byte [eax+31]
  635.     cld
  636.     rep  movsb
  637.  
  638.     mov  [edi],word ' :'
  639.  
  640.     mov   esi, send_string_header
  641.     mov   ecx,10
  642.     movzx ebx,byte [eax+31]
  643.     add   ecx,ebx
  644.  
  645.     mov   edi, packetbuf
  646.     rep   movsb
  647.  
  648.     mov  esi,send_string
  649.     mov  ecx,[xpos]
  650.     inc  ecx
  651.  
  652.         call    recode
  653.  
  654.         mov     esi, packetbuf
  655.         mov     edx, edi
  656.         sub     edx, esi
  657.         mcall   53, 7, [socket]
  658.  
  659.         mov     [xpos], 0
  660.     jmp  sdts_ret
  661.  
  662.   server_command:
  663.  
  664.     cmp  [send_string+1],dword 'anic'
  665.     jne  no_set_nick
  666.  
  667.     mov  ecx,[xpos]
  668.     sub  ecx,7
  669.     cmp  ecx,user_nick_max
  670.     jb   @f
  671.     mov  ecx,user_nick_max
  672.   @@:
  673.     mov  [user_nick],ecx
  674.  
  675.     mov  esi,send_string+7
  676.     mov  edi,user_nick+4
  677.     cld
  678.     rep  movsb
  679.  
  680.     pusha
  681.     mov  edi,text+70*1+15
  682.     mov  al,32
  683.     mov  ecx,15
  684.     cld
  685.     rep  stosb
  686.     popa
  687.  
  688.     mov  esi,user_nick+4
  689.     mov  edi,text+70*1+15
  690.     mov  ecx,[esi-4]
  691.     cld
  692.     rep  movsb
  693.  
  694.     mov  [xpos],0
  695.     call draw_window
  696.  
  697.     popa
  698.     ret
  699.  
  700.   no_set_nick:
  701.  
  702.     cmp  [send_string+1],dword 'area'
  703.     jne  no_set_real_name
  704.  
  705.     mov  ecx,[xpos]
  706.     sub  ecx,7
  707.     cmp  ecx,user_real_name_max
  708.     jb   @f
  709.     mov  ecx,user_real_name_max
  710.   @@:
  711.     mov  [user_real_name],ecx
  712.  
  713.     mov  esi,send_string+7
  714.     mov  edi,user_real_name+4
  715.     cld
  716.     rep  movsb
  717.  
  718.     pusha
  719.     mov  edi,text+70*0+15
  720.     mov  al,32
  721.     mov  ecx,15
  722.     cld
  723.     rep  stosb
  724.     popa
  725.  
  726.     mov  esi,user_real_name+4
  727.     mov  edi,text+70*0+15
  728.     mov  ecx,[esi-4]
  729.     rep  movsb
  730.  
  731.     mov  [xpos],0
  732.     call draw_window
  733.  
  734.     popa
  735.     ret
  736.  
  737.   no_set_real_name:
  738.  
  739.     cmp  [send_string+1],dword 'aser'
  740.     jne  no_set_server
  741.  
  742.     mov  ecx,[xpos]
  743.     sub  ecx,7
  744.  
  745.     mov  esi,send_string+7
  746.     mov  edi,irc_server_name
  747.     rep  movsb
  748.     mov  al,0
  749.     stosb
  750.  
  751.     pusha
  752.     mov  edi,text+70*2+15
  753.     mov  al,32
  754.     mov  ecx,15
  755.     cld
  756.     rep  stosb
  757.     popa
  758.  
  759.     mov  ecx,[xpos]
  760.     sub  ecx,7
  761.     mov  esi,send_string+7
  762.     mov  edi,text+70*2+15
  763.     rep  movsb
  764.  
  765.     mov  [xpos],0
  766.     call draw_window
  767.  
  768.     popa
  769.     ret
  770.  
  771.    no_set_server:
  772.  
  773. ; All other commands require a connection to the server.
  774.         cmp     [status], STATUS_CONNECTED
  775.         jnz     sdts_ret
  776.  
  777.  
  778.     cmp  [send_string+1],dword 'quer'
  779.     jne  no_query_create
  780.  
  781.     mov  edi,I_END+120*80
  782.     mov  eax,1 ; create channel window - search for empty slot
  783.    newse2:
  784.     mov  ebx,eax
  785.     shl  ebx,5
  786.     cmp  dword [channel_list+ebx],dword '    '
  787.     je   free_found2
  788.     add  edi,120*80
  789.     inc  eax
  790.     cmp  eax,[max_windows]
  791.     jb   newse2
  792.  
  793.   free_found2:
  794.  
  795.     mov  edx,send_string+7
  796.  
  797.     mov  ecx,[xpos]
  798.     sub  ecx,7
  799.     mov  [channel_list+ebx+31],cl
  800.  
  801.     call create_channel_name
  802.  
  803.     push edi
  804.     push eax
  805.     mov  [edi+120*60+8],byte 1 ; query window
  806.     mov  al,32
  807.     mov  ecx,120*60
  808.     cld
  809.     rep  stosb
  810.     pop  eax
  811.     pop  edi
  812.  
  813.     ; eax has the free position
  814. ;    mov  [thread_screen],edi
  815.     call create_channel_window
  816.  
  817.     mov  [xpos],0
  818.  
  819.     popa
  820.     ret
  821.  
  822.   no_query_create:
  823.  
  824.  
  825.     mov  esi, send_string+1
  826.     mov  ecx, [xpos]
  827.     inc  ecx
  828.     mov  edi, packetbuf
  829.     call recode
  830.     mov  esi, packetbuf
  831.     mov  edx, edi
  832.     sub  edx, esi
  833.  
  834.     mov  eax, 53      ; write server command
  835.     mov  ebx, 7
  836.     mov  ecx, [socket]
  837.     mcall
  838.  
  839.   send_done:
  840.  
  841.     mov  [xpos],0
  842.  
  843.     cmp  [send_string+1],dword 'quit'
  844.     jne  no_quit_server
  845.     mov  eax,5
  846.     mov  ebx,200
  847.     mcall
  848.  
  849.     mov  eax, 53      ; close socket
  850.     mov  ebx, 8
  851.     mov  ecx, [socket]
  852.     mcall
  853.  
  854.     mov  ecx,[max_windows]
  855.     mov  edi,I_END
  856.   newclose:
  857.     mov  [edi+120*60+4],byte  1
  858.     call notify_channel_thread
  859.     add  edi,120*80
  860.     loop newclose
  861.  
  862.     popa
  863.     ret
  864.  
  865.   no_quit_server:
  866.  
  867.   sdts_ret:
  868.  
  869.     popa
  870.     ret
  871.  
  872. get_next_byte:
  873. ; Load next byte from the packet, translating to cp866 if necessary
  874. ; At input esi = pointer to data, edx = limit of data
  875. ; Output is either (translated) byte in al with CF set or CF cleared.
  876.         mov     eax, [encoding]
  877.         jmp     [get_byte_table+eax*4]
  878.  
  879. get_byte_cp866:
  880.         cmp     esi, edx
  881.         jae     .nothing
  882.         lodsb
  883. .nothing:
  884.         ret
  885.  
  886. get_byte_cp1251:
  887.         cmp     esi, edx
  888.         jae     .nothing
  889.         lodsb
  890.         cmp     al, 0x80
  891.         jb      @f
  892.         and     eax, 0x7F
  893.         mov     al, [cp1251_table+eax]
  894. @@:
  895.         stc
  896. .nothing:
  897.         ret
  898.  
  899. get_byte_utf8:
  900. ; UTF8 decoding is slightly complicated.
  901. ; One character can occupy one or more bytes.
  902. ; The boundary in packets theoretically can be anywhere in data,
  903. ; so this procedure keeps internal state between calls and handles
  904. ; one byte at a time, looping until character is read or packet is over.
  905. ; Globally, there are two distinct tasks: decode byte sequence to unicode char
  906. ; and convert this unicode char to our base encoding (that is cp866).
  907. ; 1. Check that there are data.
  908.         cmp     esi, edx
  909.         jae     .nothing
  910. ; 2. Load byte.
  911.         lodsb
  912.         movzx   ecx, al
  913. ; 3. Bytes in an UTF8 sequence can be of any of three types.
  914. ; If most significant bit is cleared, sequence is one byte and usual ASCII char.
  915. ; First byte of a sequence must be 11xxxxxx, other bytes are 10yyyyyy.
  916.         and     al, 0xC0
  917.         jns     .single_byte
  918.         jp      .first_byte
  919. ; 4. This byte is not first in UTF8 sequence.
  920. ; 4a. Check that the sequence was started. If no, it is invalid byte
  921. ; and we simply ignore it.
  922.         cmp     [utf8_bytes_rest], 0
  923.         jz      get_byte_utf8
  924. ; 4b. Otherwise, it is really next byte and it gives some more bits of char.
  925.         mov     eax, [utf8_char]
  926.         shl     eax, 6
  927.         lea     eax, [eax+ecx-0x80]
  928. ; 4c. Decrement number of bytes rest in the sequence.
  929. ; If it goes to zero, character is read, so return it.
  930.         dec     [utf8_bytes_rest]
  931.         jz      .got_char
  932.         mov     [utf8_char], eax
  933.         jmp     get_byte_utf8
  934. ; 5. If the byte is first in UTF8 sequence, calculate the number of leading 1s
  935. ; - it equals total number of bytes in the sequence; some other bits rest for
  936. ; leading bits in the character.
  937. .first_byte:
  938.         mov     eax, -1
  939. @@:
  940.         inc     eax
  941.         add     cl, cl
  942.         js      @b
  943.         mov     [utf8_bytes_rest], eax
  944.         xchg    eax, ecx
  945.         inc     ecx
  946.         shr     al, cl
  947.         mov     [utf8_char], eax
  948.         jmp     get_byte_utf8
  949. ; 6. If the byte is ASCII char, it is the character.
  950. .single_byte:
  951.         xchg    eax, ecx
  952. .got_char:
  953. ; We got the character, now abandon a possible sequence in progress.
  954.         and     [utf8_bytes_rest], 0
  955. ; Now second task. The unicode character is in eax, and now we shall convert it
  956. ; to cp866.
  957.         cmp     eax, 0x80
  958.         jb      .done
  959. ; 0x410-0x43F -> 0x80-0xAF, 0x440-0x44F -> 0xE0-0xEF, 0x401 -> 0xF0, 0x451 -> 0xF1
  960.         cmp     eax, 0x401
  961.         jz      .YO
  962.         cmp     eax, 0x451
  963.         jz      .yo
  964.         cmp     eax, 0x410
  965.         jb      .unrecognized
  966.         cmp     eax, 0x440
  967.         jb      .part1
  968.         cmp     eax, 0x450
  969.         jae     .unrecognized
  970.         sub     al, (0x40-0xE0) and 0xFF
  971.         ret
  972. .part1:
  973.         sub     al, 0x10-0x80
  974. .nothing:
  975. .done:
  976.         ret
  977. .unrecognized:
  978.         mov     al, '?'
  979.         stc
  980.         ret
  981. .YO:
  982.         mov     al, 0xF0
  983.         stc
  984.         ret
  985. .yo:
  986.         mov     al, 0xF1
  987.         stc
  988.         ret
  989.  
  990. read_incoming_data:
  991.         pusha
  992. .packetloop:
  993. .nextpacket:
  994.         mcall   53, 11, [socket], packetbuf, 1024
  995.         test    eax, eax
  996.         jz      .nothing
  997.         mov     esi, edx        ; esi = pointer to data
  998.         add     edx, eax        ; edx = limit of data
  999. .byteloop:
  1000.         call    get_next_byte
  1001.         jnc     .nextpacket
  1002.         cmp     al, 10
  1003.         jne     .no_start_command
  1004.         mov     [cmd], 1
  1005. .no_start_command:
  1006.         cmp     al, 13
  1007.         jne     .no_end_command
  1008.         mov     ebx, [cmd]
  1009.         mov     byte [ebx+command-2], 0
  1010.         call    analyze_command
  1011.         mov     edi, command
  1012.         mov     ecx, 250
  1013.         xor     eax, eax
  1014.         rep     stosb
  1015.         mov     [cmd], eax
  1016.         mov     al, 13
  1017. .no_end_command:
  1018.         mov     ebx, [cmd]
  1019.         cmp     ebx, 512
  1020.         jge     @f
  1021.         mov     [ebx+command-2], al
  1022.         inc     [cmd]
  1023. @@:
  1024.         jmp     .byteloop
  1025. .nothing:
  1026.         popa
  1027.         ret
  1028.  
  1029.  
  1030. create_channel_name:
  1031.  
  1032.     pusha
  1033.  
  1034.   search_first_letter:
  1035.     cmp  [edx],byte ' '
  1036.     jne  first_letter_found
  1037.     inc  edx
  1038.     jmp  search_first_letter
  1039.   first_letter_found:
  1040.  
  1041.     mov  esi,edx
  1042.     mov  edi,channel_list
  1043.     add  edi,ebx
  1044.     mov  ecx,30
  1045.     xor  eax,eax
  1046.   newcase:
  1047.     mov  al,[esi]
  1048.     cmp  eax,'a'
  1049.     jb   nocdec
  1050.     cmp  eax,'z'
  1051.     jg   nocdec
  1052.     sub  al,97-65
  1053.   nocdec:
  1054.     mov  [edi],al
  1055.     inc  esi
  1056.     inc  edi
  1057.     loop newcase
  1058.  
  1059.     popa
  1060.  
  1061.     ret
  1062.  
  1063.  
  1064. create_channel_window:
  1065.  
  1066.     pusha
  1067.  
  1068.     mov  [cursor_on_off],0
  1069.  
  1070. ;    mov  [thread_nro],eax
  1071.  
  1072.     mov  edx,[thread_stack]
  1073.     sub  edx,8
  1074.     mov  [edx],eax
  1075.     mov  [edx+4],edi
  1076.     mov  eax,51
  1077.     mov  ebx,1
  1078.     mov  ecx,channel_thread
  1079.     mcall
  1080.     mov  [edi+120*60+12], eax
  1081.  
  1082.     add  [thread_stack],0x4000
  1083. ;    add  [thread_screen],120*80
  1084.  
  1085.     popa
  1086.  
  1087.     ret
  1088.  
  1089.  
  1090. print_entry:
  1091.  
  1092.     pusha
  1093.  
  1094.     mov  eax,13
  1095.     mov  ebx,8*65536+6*80
  1096.     mov  ecx,151*65536+13
  1097.     mov  edx,0xffffff
  1098.     mcall
  1099.  
  1100.     mov  eax,4
  1101.     mov  ebx,8*65536+154
  1102.     mov  ecx,0x000000
  1103.     mov  edx,send_string
  1104.     mov  esi,[xpos]
  1105.     mcall
  1106.  
  1107.     popa
  1108.  
  1109. ; Fall through to draw_cursor.
  1110. ;    ret
  1111.  
  1112. draw_cursor:
  1113.  
  1114.     pusha
  1115.  
  1116.     mov  eax,9
  1117.     mov  ebx,0xe0000
  1118.     mov  ecx,-1
  1119.     mcall
  1120.  
  1121.     cmp  ax,word [0xe0000+4]
  1122.     setnz dl
  1123.     movzx edx,dl
  1124.     neg edx
  1125.     and edx,0xffffff
  1126. ;    jne  no_blink
  1127.  
  1128. ;    call print_entry
  1129.  
  1130.     mov  ebx,[xpos]
  1131.     imul ebx,6
  1132.     add  ebx,8
  1133.     mov  cx,bx
  1134.     shl  ebx,16
  1135.     mov  bx,cx
  1136.     mov  ecx,151*65536+163
  1137.     mov  eax,38
  1138.     mcall
  1139.  
  1140.     popa
  1141.  
  1142.     ret
  1143.  
  1144. ;  no_blink:
  1145. ;
  1146. ;    mov  eax,13
  1147. ;    mov  ebx,8*65536+6*60
  1148. ;    mov  ecx,151*65536+13
  1149. ;    mov  edx,0xffffff
  1150. ;    mcall
  1151.  
  1152.     popa
  1153.  
  1154.     ret
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160. set_channel:
  1161.  
  1162.     pusha
  1163.  
  1164.     ; UPPER / LOWER CASE CHECK
  1165.  
  1166.     mov  esi,eax
  1167.     mov  edi,channel_temp
  1168.     mov  ecx,40
  1169.     xor  eax,eax
  1170.   newcase2:
  1171.     mov  al,[esi]
  1172.     cmp  eax,'#'
  1173.     jb   newcase_over2
  1174.     cmp  eax,'a'
  1175.     jb   nocdec2
  1176.     cmp  eax,'z'
  1177.     jg   nocdec2
  1178.     sub  al,97-65
  1179.   nocdec2:
  1180.     mov  [edi],al
  1181.     inc  esi
  1182.     inc  edi
  1183.     loop newcase2
  1184.   newcase_over2:
  1185.     sub  edi,channel_temp
  1186.     mov  [channel_temp_length],edi
  1187.  
  1188.     mov  eax,channel_temp
  1189.  
  1190.     mov  [text_start],I_END+120*80
  1191.     mov  ebx,channel_list+32
  1192.     mov  eax,[eax]
  1193.  
  1194.     mov  edx,[channel_temp_length]
  1195.  
  1196.   stcl1:
  1197.     cmp  dl,[ebx+31]
  1198.     jne  notfound
  1199.  
  1200.     pusha
  1201.     xor  eax,eax
  1202.     xor  edx,edx
  1203.     mov  ecx,0
  1204.   stc4:
  1205.     mov  dl,[ebx+ecx]
  1206.     mov  al,[channel_temp+ecx]
  1207.     cmp  eax,edx
  1208.     jne  notfound2
  1209.     inc  ecx
  1210.     cmp  ecx,[channel_temp_length]
  1211.     jb   stc4
  1212.     popa
  1213.  
  1214.     jmp  found
  1215.  
  1216.   notfound2:
  1217.     popa
  1218.  
  1219.   notfound:
  1220.     add  [text_start],120*80
  1221.     add  ebx,32
  1222.     cmp  ebx,channel_list+19*32
  1223.     jb   stcl1
  1224.  
  1225.     mov  [text_start],I_END
  1226.  
  1227.   found:
  1228.  
  1229.     popa
  1230.  
  1231.     ret
  1232.  
  1233.  
  1234. channel_temp:         times   100   db   0
  1235. channel_temp_length   dd      0x0
  1236.  
  1237.  
  1238.  
  1239. print_nick:
  1240.  
  1241.     pusha
  1242.  
  1243.     mov  eax,command+1
  1244.     mov  dl,'!'
  1245.     call print_text
  1246.  
  1247.     popa
  1248.     ret
  1249.  
  1250.  
  1251. analyze_command:
  1252.  
  1253.     pusha
  1254.  
  1255.     mov  [text_start],I_END
  1256.     mov  ecx,[rxs]
  1257.     imul ecx,11
  1258.     mov  [pos],ecx
  1259.  
  1260. ;    mov  bl,13
  1261. ;  call print_character
  1262. ;    mov  bl,10
  1263. ;  call print_character
  1264.  
  1265. ;    mov  ecx,[cmd]
  1266. ;    sub  ecx,2
  1267. ;    mov  esi,command+0
  1268. ;  newcmdc:
  1269. ;    mov  bl,[esi]
  1270. ;  call print_character
  1271. ;    inc  esi
  1272. ;    loop newcmdc
  1273.  
  1274.     mov   edx,I_END
  1275. ;  call  draw_channel_text
  1276.  
  1277. ;    cmp  [cmd],20
  1278. ;    jge  cmd_len_ok
  1279. ;
  1280. ;    mov  [cmd],0
  1281. ;
  1282. ;    popa
  1283. ;    ret
  1284.  
  1285.  
  1286.   cmd_len_ok:
  1287.  
  1288.     cmp  [command],dword 'PING'  ; ping response
  1289.     jne  no_ping_responce
  1290.  
  1291.     call print_command_to_main
  1292.  
  1293.     mov  [command],dword 'PONG'
  1294.  
  1295.     call print_command_to_main
  1296.  
  1297.     mov  eax,4
  1298.     mov  ebx,100*65536+3
  1299.     mov  ecx,0xffffff
  1300.     mov  edx,command
  1301.     mov  esi,[cmd]
  1302.     mov  [command+esi-1],word '**'
  1303. ;    mcall
  1304.  
  1305.     mov  eax,53
  1306.     mov  ebx,7
  1307.     mov  ecx,[socket]
  1308.     mov  edx,[cmd]
  1309.     mov  esi,command
  1310.     mov  word [esi+edx-2], 0x0a0d
  1311.     mcall
  1312.  
  1313.     popa
  1314.     ret
  1315.  
  1316.   no_ping_responce:
  1317.  
  1318.     mov  eax,[rxs]
  1319.     imul eax,11
  1320.     mov  [pos],eax
  1321.  
  1322.     mov  [command],byte '<'
  1323.  
  1324.     mov  eax,command
  1325.     mov  ecx,100
  1326.    new_blank:
  1327.     cmp  [eax],byte ' '
  1328.     je   bl_found
  1329.     inc  eax
  1330.     loop new_blank
  1331.     mov  eax,50
  1332.   bl_found:
  1333.  
  1334.     inc  eax
  1335.     mov  [command_position],eax
  1336.  
  1337.     mov  esi,eax
  1338.     mov  edi,irc_command
  1339.     mov  ecx,8
  1340.     cld
  1341.     rep  movsb
  1342.  
  1343.  
  1344.     cmp  [irc_command],'PRIV'  ; message to channel
  1345.     jne  no_privmsg
  1346.  
  1347.     ; compare nick
  1348.  
  1349.     mov  eax,[command_position]
  1350.     add  eax,8
  1351.     call compare_to_nick
  1352.     cmp  [cresult],0
  1353.     jne  no_query_msg
  1354.     mov  eax,command+1
  1355.   no_query_msg:
  1356.     call set_channel
  1357.  
  1358.     mov  ecx,100 ; [cmd]
  1359.     mov  eax,command+10
  1360.   acl3:
  1361.     cmp  [eax],byte ':'
  1362.     je   acl4
  1363.     inc  eax
  1364.     loop acl3
  1365.     mov  eax,10
  1366.   acl4:
  1367.     inc  eax
  1368.  
  1369.     cmp  [eax+1],dword 'ACTI'
  1370.     jne  no_action
  1371.     push eax
  1372.     mov  eax,action_header_short
  1373.     mov  dl,0
  1374.     call print_text
  1375.     mov  eax,command+1
  1376.     mov  dl,'!'
  1377.     call print_text
  1378.     mov  bl,' '
  1379.     call print_character
  1380.     pop  eax
  1381.     add  eax,8
  1382.     mov  dl,0
  1383.     call print_text
  1384.     call notify_channel_thread
  1385.     popa
  1386.     ret
  1387.  
  1388.   no_action:
  1389.  
  1390.     push eax
  1391.     mov  bl,10
  1392.     call print_character
  1393.     mov  eax,command
  1394.     mov  dl,'!'
  1395.     call print_text
  1396.     mov  bl,'>'
  1397.     call print_character
  1398.     mov  bl,' '
  1399.     call print_character
  1400.     pop  eax
  1401.  
  1402.     mov  dl,0
  1403.     call print_text
  1404.     call notify_channel_thread
  1405.  
  1406.     popa
  1407.     ret
  1408.  
  1409.   no_privmsg:
  1410.  
  1411.  
  1412.     cmp  [irc_command],'PART'    ; channel leave
  1413.     jne  no_part
  1414.  
  1415.     ; compare nick
  1416.  
  1417.     mov  eax,command+1
  1418.     call compare_to_nick
  1419.     cmp  [cresult],0
  1420.     jne  no_close_window
  1421.  
  1422.     mov  eax,[command_position]
  1423.     add  eax,5
  1424.     call set_channel
  1425.  
  1426.     mov  edi,[text_start]
  1427.     mov  [edi+120*60+4],byte 1
  1428.     call notify_channel_thread
  1429.  
  1430.     popa
  1431.     ret
  1432.  
  1433.   no_close_window:
  1434.  
  1435.     mov  eax,[command_position]
  1436.     add  eax,5
  1437.     call set_channel
  1438.  
  1439.     mov  eax,action_header_red
  1440.     mov  dl,0
  1441.     call print_text
  1442.     mov  eax,command+1
  1443.     mov  dl,'!'
  1444.     mov  cl,' '
  1445.     call print_text
  1446.     mov  eax,has_left_channel
  1447.     mov  dl,0
  1448.     call print_text
  1449.     mov  eax,[command_position]
  1450.     add  eax,5
  1451.     mov  dl,' '
  1452.     call print_text
  1453.     call notify_channel_thread
  1454.  
  1455.     popa
  1456.     ret
  1457.  
  1458.   no_part:
  1459.  
  1460.  
  1461.     cmp  [irc_command],'JOIN'    ; channel join
  1462.     jne  no_join
  1463.  
  1464.     ; compare nick
  1465.  
  1466.     mov  eax,command+1
  1467.     call compare_to_nick
  1468.     cmp  [cresult],0
  1469.     jne  no_new_window
  1470.  
  1471.     mov  edi,I_END+120*80
  1472.     mov  eax,1 ; create channel window - search for empty slot
  1473.    newse:
  1474.     mov  ebx,eax
  1475.     shl  ebx,5
  1476.     cmp  dword [channel_list+ebx],dword '    '
  1477.     je   free_found
  1478.     add  edi,120*80
  1479.     inc  eax
  1480.     cmp  eax,[max_windows]
  1481.     jb   newse
  1482.  
  1483.   free_found:
  1484.  
  1485.     mov  edx,[command_position]
  1486.     add  edx,6
  1487.  
  1488.     push eax
  1489.     push edx
  1490.     mov  ecx,0
  1491.    finde:
  1492.     inc  ecx
  1493.     inc  edx
  1494.     movzx eax,byte [edx]
  1495.     cmp  eax,'#'
  1496.     jge  finde
  1497.     mov  [channel_list+ebx+31],cl
  1498.     pop  edx
  1499.     pop  eax
  1500.  
  1501.     call create_channel_name
  1502.  
  1503.     push edi
  1504.     push eax
  1505.     mov  [edi+120*60+8],byte 0 ; channel window
  1506.     mov  al,32
  1507.     mov  ecx,120*60
  1508.     cld
  1509.     rep  stosb
  1510.     pop  eax
  1511.     pop  edi
  1512.  
  1513.     ; eax has the free position
  1514. ;    mov  [thread_screen],edi
  1515.     call create_channel_window
  1516.  
  1517.   no_new_window:
  1518.  
  1519.     mov  eax,[command_position]
  1520.     add  eax,6
  1521.     call set_channel
  1522.  
  1523.     mov  eax,action_header_blue
  1524.     mov  dl,0
  1525.     call print_text
  1526.     mov  eax,command+1
  1527.     mov  dl,'!'
  1528.     mov  cl,' '
  1529.     call print_text
  1530.  
  1531.     mov  eax,joins_channel
  1532.     mov  dl,0
  1533.     call print_text
  1534.  
  1535.     mov  eax,[command_position]
  1536.     add  eax,6
  1537.     mov  dl,0
  1538.     call print_text
  1539.     call notify_channel_thread
  1540.  
  1541.     popa
  1542.     ret
  1543.  
  1544.   no_join:
  1545.  
  1546.  
  1547.     cmp  [irc_command],'NICK'      ; nick change
  1548.     jne  no_nick_change
  1549.  
  1550.     mov  [text_start],I_END
  1551.     add  [text_start],120*80
  1552.  
  1553.  new_all_channels3:
  1554.  
  1555.     mov  eax,action_header_short
  1556.     mov  dl,0
  1557.     call print_text
  1558.     mov  eax,command+1
  1559.     mov  dl,'!'
  1560.     call print_text
  1561.     mov  eax,is_now_known_as
  1562.     mov  dl,0
  1563.     call print_text
  1564.     mov  eax,[command_position]
  1565.     add  eax,6
  1566.     mov  dl,0
  1567.     call print_text
  1568.     call notify_channel_thread
  1569.  
  1570.     add  [text_start],120*80
  1571.     cmp  [text_start],I_END+120*80*20
  1572.     jb   new_all_channels3
  1573.  
  1574.     popa
  1575.     ret
  1576.  
  1577.   no_nick_change:
  1578.  
  1579.  
  1580.      cmp  [irc_command],'KICK'      ; kick
  1581.      jne  no_kick
  1582.  
  1583.     mov  [text_start],I_END
  1584.     add  [text_start],120*80
  1585.  
  1586.     mov  eax,[command_position]
  1587.     add  eax,5
  1588.     call set_channel
  1589.  
  1590. ; new_all_channels4:
  1591.  
  1592.     mov  eax,action_header_short
  1593.     mov  dl,0
  1594.     call print_text
  1595.     mov  eax,command+1
  1596.     mov  dl,'!'
  1597.     call print_text
  1598.      mov  eax,kicked
  1599.      mov  dl,0
  1600.     call print_text
  1601.     mov  eax,[command_position]
  1602.     add  eax,5
  1603.     mov  dl,0
  1604.     call print_text
  1605.     call notify_channel_thread
  1606.  
  1607. ;    add  [text_start],120*80
  1608. ;    cmp  [text_start],I_END+120*80*20
  1609. ;    jb   new_all_channels4
  1610.  
  1611.     popa
  1612.     ret
  1613.  
  1614.   no_kick:
  1615.  
  1616.  
  1617.  
  1618.  
  1619.     cmp  [irc_command],'QUIT'    ; irc quit
  1620.     jne  no_quit
  1621.  
  1622.     mov  [text_start],I_END
  1623.     add  [text_start],120*80
  1624.  
  1625.  new_all_channels2:
  1626.  
  1627.     mov  eax,action_header_red
  1628.     mov  dl,0
  1629.     call print_text
  1630.     mov  eax,command+1
  1631.     mov  dl,'!'
  1632.     call print_text
  1633.     mov  eax,has_quit_irc
  1634.     mov  dl,0
  1635.     call print_text
  1636.     call notify_channel_thread
  1637.  
  1638.     add  [text_start],120*80
  1639.     cmp  [text_start],I_END+120*80*20
  1640.     jb   new_all_channels2
  1641.  
  1642.     popa
  1643.     ret
  1644.  
  1645.   no_quit:
  1646.  
  1647.  
  1648.     cmp  [irc_command],dword 'MODE'  ; channel mode change
  1649.     jne  no_mode
  1650.  
  1651.     mov  [text_start],I_END
  1652.     add  [text_start],120*80
  1653.  
  1654.     mov  eax,[command_position]
  1655.     add  eax,5
  1656.     call set_channel
  1657.  
  1658.  new_all_channels:
  1659.  
  1660.     mov  eax,action_header_short
  1661.     mov  dl,0
  1662.     call print_text
  1663.  
  1664.     call print_nick
  1665.  
  1666.     mov  eax,sets_mode
  1667.     mov  dl,0
  1668.     call print_text
  1669.  
  1670.     mov  eax,[command_position]
  1671.     add  eax,5
  1672.     mov  dl,0
  1673.     call print_text
  1674.     call notify_channel_thread
  1675.  
  1676. ;    add  [text_start],120*80
  1677. ;    cmp  [text_start],I_END+120*80*20
  1678. ;    jb   new_all_channels
  1679.  
  1680.     popa
  1681.     ret
  1682.  
  1683.   no_mode:
  1684.  
  1685.  
  1686.     cmp  [irc_command],dword '353 '  ; channel user names
  1687.     jne  no_user_list
  1688.  
  1689.     mov  eax,[command_position]
  1690.    finde2:
  1691.     inc  eax
  1692.     cmp  [eax],byte '#'
  1693.     jne  finde2
  1694.     call set_channel
  1695.  
  1696.    finde3:
  1697.     inc  eax
  1698.     cmp  [eax],byte ':'
  1699.     jne  finde3
  1700.  
  1701.     pusha
  1702.     cmp  [user_list_pos],0
  1703.     jne  no_clear_user_list
  1704.     mov  edi,[text_start]
  1705.     add  edi,120*70
  1706.     mov  [edi-8],dword 0
  1707.     mov  [edi-4],dword 0
  1708.     mov  al,32
  1709.     mov  ecx,1200
  1710.     cld
  1711.     rep  stosb
  1712.   no_clear_user_list:
  1713.     popa
  1714.  
  1715.     push eax
  1716.  
  1717.     mov  esi,eax
  1718.     inc  esi
  1719.     mov  edi,[text_start]
  1720.     add  edi,120*70
  1721.     add  edi,[user_list_pos]
  1722.     mov  edx,edi
  1723.     mov  ecx,command
  1724.     add  ecx,[cmd]
  1725.     sub  ecx,[esp]
  1726.     sub  ecx,3
  1727.     and  ecx,0xfff
  1728.     cld
  1729.     rep  movsb
  1730.  
  1731.     pop  eax
  1732.     mov  ebx,command
  1733.     add  ebx,[cmd]
  1734.     sub  ebx,eax
  1735.     sub  ebx,2
  1736.     mov  [edx+ebx-1],dword '    '
  1737.  
  1738.     add  [user_list_pos],ebx
  1739.  
  1740.     mov  eax,[user_list_pos]
  1741.     mov  ebx,[text_start]
  1742.     add  ebx,120*70
  1743.     mov  [ebx-4],eax
  1744.     call notify_channel_thread
  1745.  
  1746.     popa
  1747.     ret
  1748.  
  1749.   user_list_pos dd 0x0
  1750.  
  1751.   no_user_list:
  1752.  
  1753.  
  1754.     cmp  [irc_command],dword '366 '  ; channel user names end
  1755.     jne  no_user_list_end
  1756.  
  1757.     mov  [user_list_pos],0
  1758.  
  1759.     popa
  1760.     ret
  1761.  
  1762.   no_user_list_end:
  1763.  
  1764.     mov  [command],byte '-'
  1765.     call print_command_to_main
  1766.  
  1767.     popa
  1768.  
  1769.     ret
  1770.  
  1771.  
  1772. cresult db 0
  1773.  
  1774. compare_to_nick:
  1775.  
  1776. ; input  : eax = start of compare
  1777. ; output : [cresult] = 0 if match, [cresult]=1 if no match
  1778.  
  1779.  
  1780.     pusha
  1781.  
  1782.     mov  esi,eax
  1783.     mov  edi,0
  1784.  
  1785.   new_nick_compare:
  1786.  
  1787.     mov  bl,byte [esi]
  1788.     mov  cl,byte [user_nick+4+edi]
  1789.  
  1790.     cmp  bl,cl
  1791.     jne  nonickm
  1792.  
  1793.     add  esi,1
  1794.     add  edi,1
  1795.  
  1796.     cmp  edi,[user_nick]
  1797.     jb   new_nick_compare
  1798.  
  1799.     movzx eax,byte [esi]
  1800.     cmp  eax,40
  1801.     jge  nonickm
  1802.  
  1803.     popa
  1804.     mov  [cresult],0
  1805.     ret
  1806.  
  1807.   nonickm:
  1808.  
  1809.     popa
  1810.     mov  [cresult],1
  1811.     ret
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817. print_command_to_main:
  1818.  
  1819.     pusha
  1820.  
  1821.     mov  [text_start],I_END
  1822.     mov  ecx,[rxs]
  1823.     imul ecx,11
  1824.     mov  [pos],ecx
  1825.  
  1826.     mov  bl,13
  1827.     call print_character
  1828.     mov  bl,10
  1829.     call print_character
  1830.  
  1831.     mov  ecx,[cmd]
  1832.     sub  ecx,2
  1833.     mov  esi,command
  1834.    newcmdc2:
  1835.     mov  bl,[esi]
  1836.     call print_character
  1837.     inc  esi
  1838.     loop newcmdc2
  1839.  
  1840.     mov   edx,I_END
  1841.     call  draw_channel_text
  1842.  
  1843.     popa
  1844.  
  1845.     ret
  1846.  
  1847.  
  1848.  
  1849.  
  1850. print_text:
  1851.  
  1852.     pusha
  1853.  
  1854.     mov  ecx,command-2
  1855.     add  ecx,[cmd]
  1856.  
  1857.   ptr2:
  1858.     mov  bl,[eax]
  1859.     cmp  bl,dl
  1860.     je   ptr_ret
  1861.     cmp  bl,0
  1862.     je   ptr_ret
  1863.     call print_character
  1864.     inc  eax
  1865.     cmp  eax,ecx
  1866.     jbe  ptr2
  1867.  
  1868.   ptr_ret:
  1869.  
  1870.     mov  eax,[text_start]
  1871.     mov  [eax+120*60],byte 1
  1872.  
  1873.     popa
  1874.     ret
  1875.  
  1876.  
  1877. cp1251_table:
  1878.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; 8
  1879.   db '?','?','?','?','?',$F9,'?','?' , '?','?','?','?','?','?','?','?' ; 9
  1880.   db '?',$F6,$F7,'?',$FD,'?','?','?' , $F0,'?',$F2,'?','?','?','?',$F4 ; A
  1881.   db $F8,'?','?','?','?','?','?',$FA , $F1,$FC,$F3,'?','?','?','?',$F5 ; B
  1882.   db $80,$81,$82,$83,$84,$85,$86,$87 , $88,$89,$8A,$8B,$8C,$8D,$8E,$8F ; C
  1883.   db $90,$91,$92,$93,$94,$95,$96,$97 , $98,$99,$9A,$9B,$9C,$9D,$9E,$9F ; D
  1884.   db $A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7 , $A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF ; E
  1885.   db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; F
  1886.  
  1887. ;    0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F
  1888.  
  1889. utf8_table:
  1890.         times 80h dw 0x98C3     ; default placeholder
  1891. ; 0x80-0xAF -> 0x90D0-0xBFD0
  1892. repeat 0x30
  1893. store byte 0xD0 at utf8_table+2*(%-1)
  1894. store byte 0x90+%-1 at utf8_table+2*%-1
  1895. end repeat
  1896. ; 0xE0-0xEF -> 0x80D1-0x8FD1
  1897. repeat 0x10
  1898. store byte 0xD1 at utf8_table+2*(0xE0-0x80+%-1)
  1899. store byte 0x80+%-1 at utf8_table+2*(0xE0-0x80+%)-1
  1900. end repeat
  1901. ; 0xF0 -> 0x81D0, 0xF1 -> 0x91D1
  1902. store dword 0x91D181D0 at utf8_table+2*(0xF0-0x80)
  1903.  
  1904. cp866_table:
  1905.   db $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7 , $C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ; 8
  1906.   db $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7 , $D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF ; 9
  1907.   db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; A
  1908.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; B
  1909.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; C
  1910.   db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; D
  1911.   db $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7 , $F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF ; E
  1912.   db $A8,$B8,$AA,$BA,$AF,$BF,$A1,$A2 , $B0,$95,$B7,'?',$B9,$A4,'?','?' ; F
  1913.  
  1914. ;    0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F
  1915.  
  1916. print_character:
  1917.  
  1918.     pusha
  1919.  
  1920.     cmp  bl,13     ; line beginning
  1921.     jne  nobol
  1922.     mov  ecx,[pos]
  1923.     add  ecx,1
  1924.   boll1:
  1925.     sub  ecx,1
  1926.     mov  eax,ecx
  1927.     xor  edx,edx
  1928.     mov  ebx,[rxs]
  1929.     div  ebx
  1930.     cmp  edx,0
  1931.     jne  boll1
  1932.     mov  [pos],ecx
  1933.     jmp  newdata
  1934.   nobol:
  1935.  
  1936.     cmp  bl,10     ; line down
  1937.     jne  nolf
  1938.    addx1:
  1939.     add  [pos],dword 1
  1940.     mov  eax,[pos]
  1941.     xor  edx,edx
  1942.     mov  ecx,[rxs]
  1943.     div  ecx
  1944.     cmp  edx,0
  1945.     jnz  addx1
  1946.     mov  eax,[pos]
  1947.     jmp  cm1
  1948.   nolf:
  1949.   no_lf_ret:
  1950.  
  1951.  
  1952.     cmp  bl,15    ; character
  1953.     jbe  newdata
  1954.  
  1955.     mov  eax,[irc_data]
  1956.     shl  eax,8
  1957.     mov  al,bl
  1958.     mov  [irc_data],eax
  1959.  
  1960.     mov  eax,[pos]
  1961.     call draw_data
  1962.  
  1963.     mov  eax,[pos]
  1964.     add  eax,1
  1965.   cm1:
  1966.     mov  ebx,[scroll+4]
  1967.     imul ebx,[rxs]
  1968.     cmp  eax,ebx
  1969.     jb   noeaxz
  1970.  
  1971.     mov  esi,[text_start]
  1972.     add  esi,[rxs]
  1973.  
  1974.     mov  edi,[text_start]
  1975.     mov  ecx,ebx
  1976.     cld
  1977.     rep  movsb
  1978.  
  1979.     mov  esi,[text_start]
  1980.     mov  ecx,[rxs]
  1981.     imul ecx,61
  1982.     add  esi,ecx
  1983.  
  1984.     mov  edi,[text_start]
  1985.     mov  ecx,[rxs]
  1986.     imul ecx,60
  1987.     add  edi,ecx
  1988.     mov  ecx,ebx
  1989.     cld
  1990.     rep  movsb
  1991.  
  1992.     mov  eax,ebx
  1993.     sub  eax,[rxs]
  1994.   noeaxz:
  1995.     mov  [pos],eax
  1996.  
  1997.   newdata:
  1998.  
  1999.     mov  eax,[text_start]
  2000.     mov  [eax+120*60],byte 1
  2001.  
  2002.     popa
  2003.     ret
  2004.  
  2005. notify_channel_thread:
  2006.         pusha
  2007.         mov     eax, [text_start]
  2008.         mov     ecx, [eax+120*60+12]
  2009.         mcall   60, 2, , 0, 1
  2010.         popa
  2011.         ret
  2012.  
  2013.  
  2014. draw_data:
  2015.  
  2016.     pusha
  2017.  
  2018.     and  ebx,0xff
  2019.     add  eax,[text_start]
  2020.     mov  [eax],bl
  2021.  
  2022.     popa
  2023.     ret
  2024.  
  2025.  
  2026.  
  2027. draw_window:
  2028.  
  2029.     pusha
  2030.  
  2031.     mov  eax,12
  2032.     mov  ebx,1
  2033.     mcall
  2034.  
  2035.     xor  eax,eax                   ; draw window
  2036.     mov  ebx,5*65536+499
  2037.     mov  ecx,5*65536+381
  2038.     mov  edx,[wcolor]
  2039.     add  edx,0x14ffffff
  2040.     mov  edi,title
  2041.     mcall
  2042.  
  2043.     mov  eax,8                     ; button: change encoding
  2044.     mov  ebx,(ENCODING_X-2)*65536+38
  2045.     mov  ecx,(ENCODING_Y-2)*65536+12
  2046.     mov  edx,21
  2047.     mov  esi,[main_button]
  2048.     mcall
  2049.  
  2050. ;    mov  eax,8                    ; button: open socket
  2051.     mov  ebx,43*65536+22
  2052.     mov  ecx,241*65536+10
  2053. ;    mov  edx,22
  2054.     inc  edx
  2055.     mcall
  2056.  
  2057.     ;mov  eax,8                    ; button: send userinfo
  2058.     mov  ebx,180*65536+22
  2059.     mov  ecx,241*65536+10
  2060. ;    mov  edx,23
  2061.     inc  edx
  2062.     mcall
  2063.  
  2064.     ;mov  eax,8                    ; button: close socket
  2065.     mov  ebx,317*65536+22
  2066.     mov  ecx,241*65536+10
  2067. ;    mov  edx,24
  2068.     inc  edx
  2069.     mcall
  2070.  
  2071.     mov  eax,38                    ; line
  2072.     mov  ebx,5*65536+494
  2073.     mov  ecx,148*65536+148
  2074.     mov  edx,[main_line]
  2075.     mcall
  2076.     add  ecx,1*65536+1
  2077.  
  2078.     mov  eax,38                    ; line
  2079.     mov  ebx,5*65536+494
  2080.     mov  ecx,166*65536+166
  2081.     mcall
  2082.     add  ecx,1*65536+1
  2083.  
  2084.     mov  eax,38                    ; line
  2085.     mov  ebx,410*65536+410
  2086.     mov  ecx,22*65536+148
  2087.     mcall
  2088.     add  ebx,1*65536+1
  2089.  
  2090.     mov  ebx,25*65536+183          ; info text
  2091.     mov  ecx,0x000000
  2092.     mov  edx,text
  2093.     mov  esi,70
  2094.   newline:
  2095.     mov  eax,4
  2096.     mcall
  2097.     add  ebx,12
  2098.     add  edx,70
  2099.     cmp  [edx],byte 'x'
  2100.     jne  newline
  2101.  
  2102.     mov  edx,I_END                ; text from server
  2103.     call draw_channel_text
  2104.  
  2105.     call print_entry
  2106.  
  2107.     mov  eax,12
  2108.     mov  ebx,2
  2109.     mcall
  2110.  
  2111.     popa
  2112.  
  2113.     ret
  2114.  
  2115. update_status:
  2116.         pusha
  2117.         mov     esi, [status]
  2118.         mov     edi, text + 7*70 + 22
  2119.         mov     ecx, status_text_len
  2120.         push    ecx
  2121.         imul    esi, ecx
  2122.         add     esi, status_text
  2123.         mov     edx, edi
  2124.         rep     movsb
  2125.         pop     esi
  2126.         mcall   4, STATUS_X*65536+STATUS_Y, 0x40000000, , , 0xFFFFFF
  2127.         popa
  2128.         ret
  2129.  
  2130. update_encoding:
  2131.         pusha
  2132.         mov     edx, 21
  2133.         mcall   8       ; delete button
  2134.         mov     esi, [main_button]
  2135.         mcall   , <(ENCODING_X-2),38>, <(ENCODING_Y-2),12>      ; recreate it
  2136.         mov     esi, [encoding]
  2137.         mov     edi, text + 3*70 + 15
  2138.         mov     ecx, encoding_text_len
  2139.         push    ecx
  2140.         imul    esi, ecx
  2141.         add     esi, encoding_text
  2142.         mov     edx, edi
  2143.         rep     movsb
  2144.         pop     esi
  2145.         mcall   4, ENCODING_X*65536+ENCODING_Y, 0
  2146.         popa
  2147.         ret
  2148.  
  2149. main_line    dd 0x000000
  2150. main_button  dd 0x6565cc
  2151.  
  2152.  
  2153. text:
  2154.  
  2155. db '   Real name : KolibriOS User  - change with eg /areal Jill User      '
  2156. db '   Nick      : kolibri_user    - change with eg /anick Jill           '
  2157. db '   Server    : kolibrios.org   - change with eg /aserv irc.by         '
  2158. db '   Encoding  : UTF-8                                                  '
  2159. db '                                                                      '
  2160. db '        1) Connect             2) Send userinfo       3) Disconnect   '
  2161. db '                                                                      '
  2162. db '   Connection status: disconnected                                    '
  2163. db '                                                                      '
  2164. db '   Commands after established connection:                             '
  2165. db '                                                                      '
  2166. db '   /join #ChannelName         - eg /join #general                     '
  2167. db '   /part #ChannelName         - eg /part #windows                     '
  2168. db '   /query Nickname            - eg /query Mary                        '
  2169. db '   /quit                      - Quit server and Close socket          '
  2170. db 'x' ; <- END MARKER, DONT DELETE
  2171.  
  2172. status_text:
  2173. db      'disconnected            '
  2174. db      'resolving server name...'
  2175. db      'connecting...           '
  2176. db      'connected               '
  2177. status_text_len = 24
  2178.  
  2179. encoding_text:
  2180. db      'CP866 '
  2181. db      'CP1251'
  2182. db      'UTF-8 '
  2183. encoding_text_len = 6
  2184.  
  2185. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2186. ;
  2187. ;                        CHANNEL THREADS
  2188. ;
  2189. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2190.  
  2191.  
  2192.  
  2193. channel_thread:
  2194.  
  2195. ;    mov   ebp,[thread_nro]
  2196.     pop   ebp
  2197.     pop   edx
  2198.  
  2199.     mov   eax,ebp
  2200.     shl   eax,14
  2201.     add   eax,0x80000
  2202.     mov   esp,eax
  2203.  
  2204. ;    mov   edi,ebp       ; clear thread memory
  2205. ;    imul  edi,120*80
  2206. ;    add   edi,I_END
  2207. ;    mov   ecx,120*80
  2208. ;    mov   al,32
  2209. ;    cld
  2210. ;    rep   stosb
  2211.  
  2212. ; Create IPC buffer in the stack.
  2213.         push    eax
  2214.         push    eax
  2215.         push    eax
  2216.         push    8
  2217.         push    0
  2218.         mov     ecx, esp
  2219.         push    edx
  2220.         mcall   60, 1, , 20
  2221.         pop     edx
  2222.         mcall   40, 1100111b
  2223.  
  2224. ;    mov   edx,[thread_screen]
  2225.  
  2226.   thread_redraw:
  2227.     call  thread_draw_window
  2228.     call  draw_channel_text
  2229.     call  print_user_list
  2230.     call  print_entry
  2231.  
  2232.   w_t:
  2233.  
  2234.     mov  esi,ebp
  2235.     imul esi,120*80
  2236.     add  esi,I_END
  2237.     cmp  [esi+120*60+4],byte 1
  2238.     jne  no_channel_leave
  2239.     mov  [esi+120*60+4],byte 0
  2240.     mov  edi,ebp
  2241.     shl  edi,5
  2242.     mov  dword [channel_list+edi],dword '    '
  2243.     mov  byte  [channel_list+edi+31],byte 1
  2244.     mov  eax,-1
  2245.     mcall
  2246.   no_channel_leave:
  2247.  
  2248.     mcall 10
  2249.     dec   eax
  2250.     jz    thread_redraw
  2251.     dec   eax
  2252.     jz    thread_key
  2253.     dec   eax
  2254.     jz    thread_end
  2255.     cmp   al,4
  2256.     jz    thread_ipc
  2257.     call  check_mouse
  2258.     jmp   w_t
  2259.   thread_end:
  2260.     mov   eax,17
  2261.     mcall
  2262.     mov   eax,ebp
  2263.     imul  eax,120*80
  2264.     add   eax,I_END
  2265.     cmp   [eax+120*60+8],byte 0 ; channel window
  2266.     je    not_close
  2267.     mov   eax,ebp
  2268.     shl   eax,5
  2269.     add   eax,channel_list
  2270.     mov   [eax],dword '    '
  2271.     mov   [eax+31],byte 1
  2272.     mov   eax,-1
  2273.     mcall
  2274.   not_close:
  2275.     mov   [text_start],eax
  2276.     mov   eax,nocl
  2277.   newcc:
  2278.     mov   bl,[eax]
  2279.     call  print_character
  2280.     inc   eax
  2281.     cmp   [eax],byte 0
  2282.     jne   newcc
  2283.     call  draw_channel_text
  2284.     jmp   w_t
  2285.    nocl:   db  13,10,'To exit channel, use PART or QUIT command.',0
  2286.   thread_ipc:
  2287.     mov   byte [esp+4], 8 ; erase message from IPC buffer
  2288.    no_end:
  2289.  
  2290.     cmp   [edx+120*60],byte 1
  2291.     jne   no_update
  2292.     mov   [edx+120*60],byte 0
  2293.     call  draw_channel_text
  2294.   no_update:
  2295.  
  2296.     call  print_user_list
  2297.  
  2298.   nopri2:
  2299.  
  2300.     jmp   w_t
  2301.  
  2302.  
  2303.  
  2304. check_mouse:
  2305.  
  2306.     pusha
  2307.  
  2308.     mov  eax,37
  2309.     mov  ebx,1
  2310.     mcall
  2311.  
  2312.     mov  ebx,eax
  2313.     shr  eax,16
  2314.     and  ebx,0xffff
  2315.  
  2316.     cmp  eax,420
  2317.     jb   no_mouse
  2318.     cmp  eax,494
  2319.     jg   no_mouse
  2320.  
  2321.     cmp  ebx,145
  2322.     jg   no_mouse
  2323.     cmp  ebx,23
  2324.     jb   no_mouse
  2325.  
  2326.  
  2327.     cmp  ebx,100
  2328.     jb   no_plus
  2329.     mov  eax,ebp
  2330.     imul eax,120*80
  2331.     add  eax,120*70+I_END
  2332.     inc  dword [eax-8]
  2333.     call print_user_list
  2334.     mov  eax,5
  2335.     mov  ebx,8
  2336.     mcall
  2337.     jmp  no_mouse
  2338.   no_plus:
  2339.  
  2340.     cmp  ebx,80
  2341.     jg   no_mouse
  2342.     mov  eax,ebp
  2343.     imul eax,120*80
  2344.     add  eax,120*70+I_END
  2345.     cmp  dword [eax-8],dword 0
  2346.     je   no_mouse
  2347.     dec  dword [eax-8]
  2348.     call print_user_list
  2349.     mov  eax,5
  2350.     mov  ebx,8
  2351.     mcall
  2352.  
  2353.   no_minus:
  2354.  
  2355.   no_mouse:
  2356.  
  2357.     popa
  2358.  
  2359.     ret
  2360.  
  2361.  
  2362.  
  2363.  
  2364. thread_key:
  2365.  
  2366.     mov  eax,2
  2367.     mcall
  2368.  
  2369.     shr  eax,8
  2370.  
  2371.     cmp  eax,8
  2372.     jne  no_bks
  2373.     cmp  [xpos],0
  2374.     je   w_t
  2375.     dec  [xpos]
  2376.     call print_entry
  2377.     jmp  w_t
  2378.    no_bks:
  2379.  
  2380.     cmp  eax,20
  2381.     jbe  no_character
  2382.     mov  ebx,[xpos]
  2383.     mov  [send_string+ebx],al
  2384.     inc  [xpos]
  2385.     cmp  [xpos],80
  2386.     jb   xpok
  2387.     mov  [xpos],79
  2388.   xpok:
  2389.     call print_entry
  2390.     jmp  w_t
  2391.   no_character:
  2392.  
  2393.     cmp  eax,13
  2394.     jne  no_send
  2395.     cmp  [xpos],0
  2396.     je   no_send
  2397.     mov  dword [send_to_channel],ebp
  2398.     pusha
  2399.     mcall 60,2,[main_PID],0,1
  2400.   wait_for_sending:
  2401.     mov  eax,5
  2402.     mov  ebx,1
  2403.     mcall
  2404.     cmp  dword [ipcbuf+4],8
  2405.     jne  wait_for_sending
  2406.     popa
  2407.     call draw_channel_text
  2408.     call print_entry
  2409.     jmp  w_t
  2410.   no_send:
  2411.  
  2412.     jmp  w_t
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419. draw_channel_text:
  2420.  
  2421.     pusha
  2422.  
  2423.     mov   eax,4
  2424.     mov   ebx,10*65536+26
  2425.     mov   ecx,12
  2426.     mov   esi,[rxs]
  2427.   dct:
  2428.     pusha
  2429.     mov   cx,bx
  2430.     shl   ecx,16
  2431.     mov   cx,9
  2432.     mov   eax,13
  2433.     mov   ebx,10*65536
  2434.     mov   bx,word [rxs]
  2435.     imul  bx,6
  2436.     mov   edx,0xffffff
  2437.     mcall
  2438.     popa
  2439.     push  ecx
  2440.     mov   eax,4
  2441.     mov   ecx,0
  2442.     cmp   [edx],word '* '
  2443.     jne   no_red
  2444.     mov   ecx,0x0000ff
  2445.    no_red:
  2446.     cmp   [edx],word '**'
  2447.     jne   no_light_blue
  2448.     cmp   [edx+2],byte '*'
  2449.     jne   no_light_blue
  2450.     mov   ecx,0x0000ff
  2451.   no_light_blue:
  2452.     cmp   [edx],byte '#'
  2453.     jne   no_blue
  2454.     mov   ecx,0x0000ff
  2455.   no_blue:
  2456.     mcall
  2457.     add   edx,[rxs]
  2458.     add   ebx,10
  2459.     pop   ecx
  2460.     loop  dct
  2461.  
  2462.     popa
  2463.     ret
  2464.  
  2465.  
  2466.  
  2467.  
  2468.  
  2469. thread_draw_window:
  2470.  
  2471.     pusha
  2472.  
  2473.     mov  eax,12
  2474.     mov  ebx,1
  2475.     mcall
  2476.  
  2477.     mov  ebx,ebp                   ; draw window
  2478.     shl  ebx,16+4
  2479.     xor  eax,eax
  2480.     mov  ecx,ebx
  2481.     mov  bx,499
  2482.     mov  cx,170
  2483.  
  2484.     mov  edx,[wcolor]
  2485.     add  edx,0x03ffffff
  2486.     mov  esi,0x80555599
  2487.     mov  edi,0x00ffffff
  2488.  
  2489.     mcall
  2490.  
  2491.     mov  eax,ebp                   ; label
  2492.     add  eax,48
  2493.     mov  [labelc+14],al
  2494.     mov  eax,ebp
  2495.     shl  eax,5
  2496.     add  eax,channel_list
  2497.     mov  esi,eax
  2498.     mov  edi,labelc+17
  2499.     movzx ecx,byte [eax+31]
  2500.     cld
  2501.     rep   movsb
  2502.  
  2503.     mov  esi,17                    ; print label
  2504.     movzx ebx,byte [eax+31]
  2505.     add  esi,ebx
  2506.     mov  eax,4
  2507.     mov  ebx,9*65536+8
  2508.     mov  ecx,0x00ffffff
  2509.     mov  edx,labelc
  2510.     mcall
  2511.  
  2512.     mov  eax,38                    ; line
  2513.     mov  ebx,5*65536+494
  2514.     mov  ecx,148*65536+148
  2515.     mov  edx,[channel_line_sun]
  2516.     mcall
  2517.     add  ecx,1*65536+1
  2518.     mov  edx,[channel_line_shadow]
  2519.     mcall
  2520.  
  2521.  
  2522.     ;mov  eax,38                   ; line
  2523.     mov  ebx,410*65536+410
  2524.     mov  ecx,22*65536+148
  2525.     mov  edx,[channel_line_sun]
  2526.     mcall
  2527.     add  ebx,1*65536+1
  2528.     mov  edx,[channel_line_shadow]
  2529.     mcall
  2530.  
  2531.     mov  eax,12
  2532.     mov  ebx,2
  2533.     mcall
  2534.  
  2535.     popa
  2536.  
  2537.     ret
  2538.  
  2539.  
  2540. ; DATA AREA
  2541.  
  2542. socket  dd  0x0
  2543.  
  2544. bgc  dd  0x000000
  2545.      dd  0x000000
  2546.      dd  0x00ff00
  2547.      dd  0x0000ff
  2548.      dd  0x005500
  2549.      dd  0xff00ff
  2550.      dd  0x00ffff
  2551.      dd  0x770077
  2552.  
  2553. tc   dd  0xffffff
  2554.      dd  0xff00ff
  2555.      dd  0xffffff
  2556.      dd  0xffffff
  2557.      dd  0xffffff
  2558.      dd  0xffffff
  2559.      dd  0xffffff
  2560.      dd  0xffffff
  2561.  
  2562. channel_line_sun    dd 0x9999ff
  2563. channel_line_shadow dd 0x666699
  2564.  
  2565. cursor_on_off  dd  0x0
  2566.  
  2567. max_windows    dd  20
  2568.  
  2569. thread_stack   dd  0x9fff0
  2570. ;thread_nro     dd 1
  2571. ;thread_screen  dd I_END+120*80*1
  2572.  
  2573. action_header_blue  db  10,'*** ',0
  2574. action_header_red   db  10,'*** ',0
  2575.  
  2576. action_header_short db  10,'* ',0
  2577.  
  2578. has_left_channel db  ' has left ',0
  2579. joins_channel    db  ' has joined ',0
  2580. is_now_known_as  db  ' is now known as ',0
  2581. has_quit_irc     db  ' has quit IRC',0
  2582. sets_mode        db  ' sets mode ',0
  2583. kicked           db  ' kicked from ',0
  2584.  
  2585. index_list_1     dd  0x0000bb
  2586. index_list_2     dd  0x0000ff
  2587.  
  2588. posx             dd  0x0
  2589. incoming_pos     dd  0x0
  2590. incoming_string: times 128 db 0
  2591.  
  2592. pos          dd  0x0
  2593.  
  2594. text_start   dd  I_END
  2595. irc_data     dd  0x0
  2596. print        db  0x0
  2597. cmd          dd  0x0
  2598. rxs          dd  66
  2599.  
  2600. res:         db  0,0
  2601. command:     times  600  db 0x0
  2602.  
  2603. nick         dd  0,0,0
  2604. irc_command  dd  0,0
  2605.  
  2606. command_position  dd 0x0
  2607. counter           dd  0
  2608. send_to_server    db 0
  2609.  
  2610. channel_list:     times 32*20 db 32
  2611. send_to_channel   dd 0x0
  2612.  
  2613. send_string_header:  db     'privmsg #eax :'
  2614.                      times  100  db  0x0
  2615.  
  2616. send_string:         times  100  db  0x0
  2617. xpos         dd  0
  2618.  
  2619. string0:     db  'USER guest ser1 ser2 :'
  2620. string0l:
  2621. string1:     db  'nick '
  2622. string1l:
  2623.  
  2624. attribute   dd  0
  2625. scroll      dd  1
  2626.             dd  12
  2627.  
  2628. numtext     db  '                     '
  2629.  
  2630. wcolor      dd  0x000000
  2631.  
  2632. labelc      db  'AIRC - WINDOW X: #xxx                 '
  2633. title       db  'IRC client ',version,0
  2634.  
  2635. ipcbuf:
  2636.         dd      0
  2637.         dd      8
  2638.         dd      ?
  2639.         dd      ?
  2640.         db      ?
  2641. .size = $
  2642.  
  2643. align 4
  2644. @IMPORT:
  2645.  
  2646. library network, 'network.obj', msgbox, 'msgbox.obj'
  2647. import  network, \
  2648.         getaddrinfo_start,      'getaddrinfo_start',    \
  2649.         getaddrinfo_process,    'getaddrinfo_process',  \
  2650.         getaddrinfo_abort,      'getaddrinfo_abort',    \
  2651.         freeaddrinfo,           'freeaddrinfo'
  2652. import  msgbox, mb_create, 'mb_create', mb_setfunctions, 'mb_setfunctions'
  2653.  
  2654. msgbox_running  db      ?       ; must be the byte before msgbox_struct
  2655.                                 ; look to the handler of button 21
  2656. msgbox_struct:
  2657. .default:
  2658.         dw      ?       ; default button, will be filled with current encoding
  2659.         db      'Encoding',0
  2660.         db      'Select encoding for all messages:',0
  2661.         db      'CP866',0
  2662.         db      'CP1251',0
  2663.         db      'UTF-8',0
  2664.         db      0
  2665.  
  2666. align 4
  2667. status          dd      STATUS_DISCONNECTED
  2668. encoding        dd      UTF8
  2669. recode_proc     dd      recode_to_cp866, recode_to_cp1251, recode_to_utf8
  2670. get_byte_table  dd      get_byte_cp866, get_byte_cp1251, get_byte_utf8
  2671. msgbox_func_array:
  2672. times 3         dd      msgbox_notify
  2673. initialized_size:
  2674.  
  2675. main_PID        dd      ?       ; identifier of main thread
  2676. utf8_bytes_rest dd      ?       ; bytes rest in current UTF8 sequence
  2677. utf8_char       dd      ?       ; first bits of current UTF8 character
  2678. gai_reqdata     rb      32      ; buffer for getaddrinfo_start/process
  2679. ip_list         dd      ?       ; will be filled as pointer to addrinfo list
  2680. irc_server_name rb      256     ; buffer for irc_server_name
  2681. packetbuf       rb      1024    ; buffer for packets to server
  2682. mb_stack        rb      1024    ; stack for messagebox thread
  2683.  
  2684. ;;
  2685. ;;   Channel data at I_END
  2686. ;;
  2687. ;;   120*80 * channel window (1+)
  2688. ;;
  2689. ;;      At         Size
  2690. ;;
  2691. ;;      00      ,  120*60   window text 120 characters per row
  2692. ;;  120*60      ,  1        text is updated
  2693. ;;  120*60+4    ,  1        close yourself
  2694. ;;  120*60+8    ,  1        0 = channel window  :  1 = private chat
  2695. ;;  120*60+12    , 4        identifier of the thread
  2696. ;;  120*61      ,  256      channel name
  2697. ;;  120*61+254  ,  254      channel entry text from user
  2698. ;;  120*61+255  ,  1        length of entry text
  2699. ;;  120*69+248  ,  4        display names from n:th name
  2700. ;;  120*69+252  ,  4        length of names string
  2701. ;;  120*70      ,  1200     names separated with space
  2702. ;;
  2703. I_END:
  2704.