Logo Search packages:      
Sourcecode: hanterm-classic version File versions  Download package

chat.c

/*
  Chat mode processing

  written by Song Jaekyung

  $Id: chat.c,v 1.15 2001/05/30 14:57:06 lenok Exp $
*/

#include "ptyx.h"
#include "data.h"
#include "error.h"
#include "hangul.h"
#include <stdio.h>
#include <X11/keysym.h>

#define MAXCHATBUF 1024
#define CHAT_START_X_BASE (ST_MODE_LEN + 1)

extern void ShowCursor();
extern void HideCursor();

extern int (*converter)();
extern int convert_3_to_johab();
extern int convert_3_to_ks();
#if !defined(NO_PATCH_UTF8) /* by hanmaum 1998.2.5 */
extern int convert_3_to_utf8();
#endif

#ifndef NO_HIST
void init_history();
void using_history();
void add_history();
Char *previous_history ();
Char *next_history ();
#endif

int (*chat_callback)();
int chat_mode;
static int chat_x;
static Char *chat_p, *chat_startp, *chat_buf = NULL, *chat_prompt;

/* chat_buf : 채팅 모드 문자열을 기억하는 버퍼
   chat_p : 문자열의 마지막을 가리킨다.
   chat_startp : 스크롤 됐을 때 처음을 가리킨다.
*/

toggle_chat_mode(str)
    unsigned char *str;
{
    HideCursor();
    if (chat_mode)
      chat_flush(0);
    else
      unparseputc(-2, term->screen.respond);
    chat_mode ^= 1;
    if (chat_mode) {
      chat_x = strlen((char*)str) + CHAT_START_X_BASE;
        if (!(term->screen.showStatus.hideCode))
            chat_x += ST_CODE_LEN;
        if (!(term->screen.showStatus.hideHanLayout))
            chat_x += ST_KBD_LEN;

      if (chat_buf == NULL) {
          chat_buf = (Char *)calloc((unsigned)MAXCHATBUF, sizeof(Char));
          if (chat_buf == NULL) {
            fprintf(stderr, "%s: can't allocate chat buf\n", xterm_name);
            Cleanup(ERROR_SCALLOC);
          }
#ifndef NO_HIST
          init_history();
#endif
      }
#ifndef NO_HIST
      using_history();
#endif

      strcpy((char*)chat_buf, (char*)str);
      chat_startp = chat_buf;
      chat_prompt = chat_p = (Char*)strchr((char*)chat_buf, '\0');
      converter = convert_3_to_johab;
      show_chat_buf();
    } else {
      if (term->screen.code == C_WANSUNG) {
          converter = convert_3_to_ks;
      }
#if !defined(NO_PATCH_UTF8) /* by hanmaum 1998.2.5 */
      else if (term->screen.code == C_UTF8) {
          converter = convert_3_to_utf8;
      }
#endif

    }
    ShowCursor();
}

chat_mode_input(keysym, event, string, nbytes)
    KeySym keysym;
    XKeyEvent *event;
    Char *string;
    int nbytes;
{
    Char *org_p;
    int n;
    int tmp_han;
#ifndef NO_HIST
    Char *hist;
    int hist_len;
#endif

    chat_hide_cursor();
    org_p = chat_p;
    tmp_han = temp_hangul[0];
    if (keysym == -1 || keysym == -2) {
      n = hangul_automata(keysym, chat_p);
      chat_p += n;
    }
#ifndef NO_HIST
    else if ((keysym == XK_Up) || (keysym == XK_Down))
    {
      hist = NULL;
      switch (keysym) {
      case XK_Up :
          hist = previous_history();
          break;
      case XK_Down :
          hist = next_history();
      }

      if ((hist == NULL) || (*hist == 0))
          chat_clear();
      else {
          chat_clear();
          hist_len = strlen((char *)hist);
          strcpy((char *)chat_buf, (char *)hist);
          chat_startp = org_p = chat_buf;
          chat_x = CHAT_START_X_BASE;
            /* variable start point */
            if (!(term->screen.showStatus.hideCode))
                chat_x += ST_CODE_LEN;
            if (!(term->screen.showStatus.hideHanLayout))
                chat_x += ST_KBD_LEN;
          chat_p = chat_buf + hist_len;
      }
    }
#endif
    else if (nbytes > 0) {
      while (nbytes-- > 0) {
          if (chat_p - chat_buf < MAXCHATBUF - 10) {
            n = hangul_automata(*string, chat_p);
            chat_p += n;
          }
          else
            n = 1;
          if (n > 0)
            switch (*string) {
            case 13:    /* return */
                chat_flush(0);
                break;
            case 8:           /* back space */
                chat_backspace();
                break;
            case 0177:  /* delete */
                if (tmp_han)
                  chat_x += 2;
                chat_backspace();
                break;
            case 025:   /* ctrl-u */
                chat_clear();
                break;
            case 027:   /* ctrl-w */
                chat_delete_word();
            case 033:   /* escape */
                chat_flush(1);
                break;
            default:
                if (chat_p - 1 == chat_buf && *string < ' ')
                  chat_control();
                break;
            }
          string++;
      }
    }
    if (chat_p > org_p) {
      if (chat_x + (chat_p - org_p) <= term->screen.max_col)
          draw_chat_buf(org_p, chat_p - org_p);
      chat_x += chat_p - org_p;
      if (chat_x > term->screen.max_col)
          chat_scroll_left();
    }
    if (chat_mode) {          /* chat_flush can make chat_mode = 0 */
      chat_show_cursor();
    }
}

void input_to_chat(str, len)
    Char *str;
    int len;
{
    Char *org_p, *p, *q;
    int n;

    org_p = chat_p;

    if (chat_p < chat_buf + MAXCHATBUF - 10) {
      n = hangul_automata(-2, chat_p);
      chat_p += n;
    }

    if (chat_p + len < chat_buf + MAXCHATBUF - 10) {
      n = len;
    }
    else {
      for (p = chat_p, q = str; p < chat_buf + MAXCHATBUF - 10;) {
          if (*q & 0x80) {
            p += 2;
            q += 2;
          } else {
            p++;
            q++;
          }
          n = q - str;
      }
    }

    if (n <= 0)
      return;

    strncpy((char*)chat_p, (char*)str, n);
    chat_p += n;

    if (chat_p > org_p) {
      if (chat_x + (chat_p - org_p) <= term->screen.max_col)
          draw_chat_buf(org_p, chat_p - org_p);
      chat_x += chat_p - org_p;
      if (chat_x > term->screen.max_col)
          chat_scroll_left();
    }
    chat_show_cursor();
}

chat_control()
{
    unparseputc(*chat_buf, term->screen.respond);
    chat_p--;
    *chat_p = 0;
}

chat_clear()
{
    memset(chat_buf, '\0', chat_p - chat_buf);
    chat_x = CHAT_START_X_BASE;
    if (!(term->screen.showStatus.hideCode))
        chat_x += ST_CODE_LEN;
    if (!(term->screen.showStatus.hideHanLayout))
        chat_x += ST_KBD_LEN;
    chat_startp = chat_p = chat_buf;
    chat_clear_line(chat_x, term->screen.max_col - chat_x + 1);
}

chat_backspace()
{
    int n;

    chat_p--;                 /* bs 를 지움 */
    *chat_p = 0;
    n = 0;
    if (chat_p - 1 >= chat_prompt) {
#if !defined(NO_PATCH_ADJUSTHANGULSTRING) /* by hanmaum 1998.2.4 */
      n = adjust_hangul_string(chat_buf, chat_p - chat_buf - 1, C_JOHAB)
            ? 2 : 1;
#else
      n = adjust_hangul_string(chat_buf, chat_p - chat_buf - 1) ? 2 : 1;
#endif
      chat_p -= n;
      chat_x -= n;
      memset(chat_p, '\0', n);
      chat_scroll_right();
    }
    chat_clear_line(chat_x, n + 1);
}

chat_delete_word()
{
    Char *org_p;

    chat_p--;
    *chat_p = 0;
    org_p = chat_p;
    if (chat_p - 1 >= chat_prompt) {
      while (chat_p > chat_prompt && *(chat_p - 1) == ' ')
          chat_p--;
      while (chat_p > chat_prompt && *(chat_p - 1) != ' ')
          chat_p--;
      chat_x -= org_p - chat_p;
      memset(chat_p, '\0', org_p - chat_p);
      chat_scroll_right();
    }
    chat_clear_line(chat_x, org_p - chat_p + 1);
}

chat_flush(ret)
    int ret;
{
    Char *p;
    int n, f;
    Char buf[MAXCHATBUF * 4];

    n = hangul_automata(-2, chat_p);
    chat_p += n;
    chat_p -= ret;

#ifndef NO_HIST
    if (*(chat_p - 1) == '\r')
      add_history(chat_buf, chat_p - chat_buf - 1);
    else
      add_history(chat_buf, chat_p - chat_buf);
    using_history();
#endif

    if (*(chat_p - 1) == '\r' && (term->flags & LINEFEED))
      *chat_p++ = '\n';
    *chat_p = 0;

    if (term->screen.code == C_WANSUNG) {
      n = convert_johab_to_ks(chat_buf, buf, chat_p - chat_buf);
      p = buf;

#if !defined(NO_PATCH_UTF8) /* by hanmaum 1998.2.5 */
    } else if (term->screen.code == C_UTF8) {
      n = convert_johab_to_utf8(chat_buf, buf, chat_p - chat_buf);
      p = buf;
#endif

    } else {
      n = chat_p - chat_buf;
      p = chat_buf;
    }
    f = (*chat_callback)(term->screen.respond, p, n);
    chat_clear();
    if (f < 0) {
      chat_mode = 0;
      if (term->screen.code == C_WANSUNG) {
          converter = convert_3_to_ks;
      }

#if !defined(NO_PATCH_UTF8) /* by hanmaum 1998.2.5 */
      else if (term->screen.code == C_UTF8) {
          converter = convert_3_to_utf8;
      }
#endif

      ShowCursor();
    }
}

chat_scroll_left()
{
    while (chat_x > term->screen.max_col) {
      if (*chat_startp & 0x80) {
          chat_x -= 2;
          chat_startp += 2;
      } else {
          chat_x--;
          chat_startp++;
      }
    }
    show_chat_buf();
}

chat_scroll_right()
{
    if (chat_startp > chat_buf && chat_x < term->screen.max_col - 1) {
      while (chat_startp > chat_buf && chat_x < term->screen.max_col - 1) {

#if !defined(NO_PATCH_ADJUSTHANGULSTRING) /* by hanmaum 1998.2.4 */
          if (adjust_hangul_string(
            chat_buf, chat_startp - chat_buf - 1, C_JOHAB))
#else
          if (adjust_hangul_string(chat_buf, chat_startp - chat_buf - 1))
#endif
          {
            chat_x += 2;
            chat_startp -= 2;
          } else {
            chat_x++;
            chat_startp--;
          }
      }
      show_chat_buf();
    }
}

chat_clear_line(x, n)
    int x, n;
{
    register TScreen *screen = &term->screen;

    XClearArea(screen->display, TextWindow(screen),
             CursorX(screen, x),
             (screen->max_row + 1) * FontHeight(screen) + screen->border * 2,
             n * FontWidth(screen), FontHeight(screen), FALSE);
}

chat_show_cursor()
{
    TScreen *screen = &term->screen;
    int n;
    Char c[2];
    GC currentGC, currentHGC;

    if (temp_hangul[0]) {
      c[0] = temp_hangul[0];
      c[1] = temp_hangul[1];
      n = 2;
    }
    else {
      c[0] = *chat_p;
      n = 1;
      if (c[0] & 0x80) {
          c[1] = *(chat_p + 1);
          n = 2;
      }
    }
    if (chat_x == screen->max_col && n == 2) {
      if (*chat_startp & 0x80) {
          chat_startp += 2;
          chat_x -= 2;
      } else {
          chat_startp++;
          chat_x--;
      }
      show_chat_buf();
    }
    if( screen->reversecursorGC ) {
      currentGC = screen->reversecursorGC;
      currentHGC = screen->reversecursorHGC;
    }
    else {
      currentGC = screen->reverseGC;
      currentHGC = screen->reverseHGC;
    }

    HDrawImageString(screen->display, TextWindow(screen),
                 currentGC, currentHGC, CursorX(screen, chat_x),
                 (screen->max_row + 1) * FontHeight(screen) + 
                 screen->ascent + screen->border * 2, c, n);
}

chat_hide_cursor()
{
    TScreen *screen = &term->screen;
    int n;
    Char c[2];

    Pixel fg_pix, bg_pix;
    GC currentGC, currentHGC;

    fg_pix = screen->foreground;
    bg_pix = term->core.background_pixel;

    currentGC = screen->normalGC;
    currentHGC = screen->normalHGC;

    XSetForeground(screen->display, currentGC, fg_pix);
    XSetBackground(screen->display, currentGC, bg_pix);
    XSetForeground(screen->display, currentHGC, fg_pix);
    XSetBackground(screen->display, currentHGC, bg_pix);

    c[0] = *chat_p;
    c[1] = ' ';
    n = 2;
    HDrawImageString(screen->display, TextWindow(screen), currentGC,
                 currentHGC, CursorX(screen, chat_x),
                 (screen->max_row + 1) * FontHeight(screen) + 
                 screen->ascent + screen->border * 2, c, n);
}

show_chat_buf()
{
    TScreen *screen = &term->screen;
    Pixel fg_pix, bg_pix;
    GC currentGC, currentHGC;
    int startPos = CHAT_START_X_BASE;

    /* set starting position */
    if (!(screen->showStatus.hideCode))
        startPos += ST_CODE_LEN;
    if (!(screen->showStatus.hideHanLayout))
        startPos += ST_KBD_LEN;

    /* cdpark's patch */
    fg_pix = screen->foreground;
    bg_pix = term->core.background_pixel;

    currentGC = screen->normalGC;
    currentHGC = screen->normalHGC;

    XSetForeground(screen->display, currentGC, fg_pix);
    XSetBackground(screen->display, currentGC, bg_pix);
    XSetForeground(screen->display, currentHGC, fg_pix);
    XSetBackground(screen->display, currentHGC, bg_pix);

    HDrawImageString(screen->display, TextWindow(screen), currentGC,
                 currentHGC,
                 CursorX(screen, startPos),
                 (screen->max_row + 1) * FontHeight(screen) + 
                 screen->ascent + screen->border * 2,
                 chat_startp,
                 chat_p - chat_startp);
}

draw_chat_buf(str, n)
    Char *str;
    int n;
{
    TScreen *screen = &term->screen;
    
    Pixel fg_pix, bg_pix;
    GC currentGC, currentHGC;

    fg_pix = screen->foreground;
    bg_pix = term->core.background_pixel;

    currentGC = screen->normalGC;
    currentHGC = screen->normalHGC;

    XSetForeground(screen->display, currentGC, fg_pix);
    XSetBackground(screen->display, currentGC, bg_pix);
    XSetForeground(screen->display, currentHGC, fg_pix);
    XSetBackground(screen->display, currentHGC, bg_pix);

    HDrawImageString(screen->display, TextWindow(screen), currentGC,
                 currentHGC, CursorX(screen, chat_x),
                 (screen->max_row + 1) * FontHeight(screen) + 
                 screen->ascent + screen->border * 2, str, n);
}

Generated by  Doxygen 1.6.0   Back to index