/[emacs]/emacs/src/term.c
ViewVC logotype

Diff of /emacs/src/term.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.156 by kfstorm, Fri Mar 19 00:42:48 2004 UTC revision 1.157 by handa, Tue Nov 30 08:19:32 2004 UTC
# Line 791  clear_end_of_line (first_unused_hpos) Line 791  clear_end_of_line (first_unused_hpos)
791      }      }
792  }  }
793    
794  /* Encode SRC_LEN glyphs starting at SRC to terminal output codes and  /* Buffer to store the source and result of code conversion for terminal.  */
795     store them at DST.  Do not write more than DST_LEN bytes.  That may  static unsigned char *encode_terminal_buf;
796     require stopping before all SRC_LEN input glyphs have been  /* Allocated size of the above buffer.  */
797     converted.  static int encode_terminal_bufsize;
798    
799    /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
800       Set CODING->produced to the byte-length of the resulting byte
801       sequence, and return a pointer to that byte sequence.  */
802    
803     We store the number of glyphs actually converted in *CONSUMED.  The  static unsigned char *
804     return value is the number of bytes store in DST.  */  encode_terminal_code (src, src_len, coding)
   
 int  
 encode_terminal_code (src, dst, src_len, dst_len, consumed)  
805       struct glyph *src;       struct glyph *src;
806       int src_len;       int src_len;
807       unsigned char *dst;       struct coding_system *coding;
      int dst_len, *consumed;  
808  {  {
809    struct glyph *src_start = src, *src_end = src + src_len;    struct glyph *src_start = src, *src_end = src + src_len;
   unsigned char *dst_start = dst, *dst_end = dst + dst_len;  
810    register GLYPH g;    register GLYPH g;
811    unsigned char workbuf[MAX_MULTIBYTE_LENGTH];    unsigned char *buf;
812    const unsigned char *buf;    int nchars, nbytes, required;
   int len;  
813    register int tlen = GLYPH_TABLE_LENGTH;    register int tlen = GLYPH_TABLE_LENGTH;
814    register Lisp_Object *tbase = GLYPH_TABLE_BASE;    register Lisp_Object *tbase = GLYPH_TABLE_BASE;
   int result;  
   struct coding_system *coding;  
815    
816    /* If terminal_coding does any conversion, use it, otherwise use    /* Allocate sufficient size of buffer to store all characters in
817       safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here       multibyte-form.  But, it may be enlarged on demand if
818       because it always return 1 if the member src_multibyte is 1.  */       Vglyph_table contains a string.  */
819    coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK    required = MAX_MULTIBYTE_LENGTH * src_len;
820              ? &terminal_coding    if (encode_terminal_bufsize < required)
821              : &safe_terminal_coding);      {
822          encode_terminal_bufsize = required;
823          if (encode_terminal_bufsize == 0)
824            encode_terminal_buf = xmalloc (required);
825          else
826            encode_terminal_buf = xrealloc (encode_terminal_buf, required);
827        }
828    
829      buf = encode_terminal_buf;
830      nchars = 0;
831    while (src < src_end)    while (src < src_end)
832      {      {
833        /* We must skip glyphs to be padded for a wide character.  */        /* We must skip glyphs to be padded for a wide character.  */
# Line 834  encode_terminal_code (src, dst, src_len, Line 838  encode_terminal_code (src, dst, src_len,
838            if (g < 0 || g >= tlen)            if (g < 0 || g >= tlen)
839              {              {
840                /* This glyph doesn't has an entry in Vglyph_table.  */                /* This glyph doesn't has an entry in Vglyph_table.  */
841                if (! CHAR_VALID_P (src->u.ch, 0))                if (CHAR_VALID_P (src->u.ch, 0))
842                  {                  buf += CHAR_STRING (src->u.ch, buf);
                   len = 1;  
                   buf = " ";  
                   coding->src_multibyte = 0;  
                 }  
843                else                else
844                  {                  *buf++ = SPACEGLYPH;
845                    len = CHAR_STRING (src->u.ch, workbuf);                nchars++;
                   buf = workbuf;  
                   coding->src_multibyte = 1;  
                 }  
846              }              }
847            else            else
848              {              {
# Line 855  encode_terminal_code (src, dst, src_len, Line 852  encode_terminal_code (src, dst, src_len,
852    
853                if (GLYPH_SIMPLE_P (tbase, tlen, g))                if (GLYPH_SIMPLE_P (tbase, tlen, g))
854                  {                  {
855                    /* We set the multi-byte form of a character in G                    int c = FAST_GLYPH_CHAR (g);
856                       (that should be an ASCII character) at  
857                       WORKBUF.  */                    if (CHAR_VALID_P (c, 0))
858                    workbuf[0] = FAST_GLYPH_CHAR (g);                      buf += CHAR_STRING (c, buf);
859                    len = 1;                    else
860                    buf = workbuf;                      *buf++ = SPACEGLYPH;
861                    coding->src_multibyte = 0;                    nchars++;
862                  }                  }
863                else                else
864                  {                  {
865                    /* We have a string in Vglyph_table.  */                    /* We have a string in Vglyph_table.  */
866                    len = GLYPH_LENGTH (tbase, g);                    Lisp_Object string;
                   buf = GLYPH_STRING (tbase, g);  
                   coding->src_multibyte = STRING_MULTIBYTE (tbase[g]);  
                 }  
             }  
867    
868            result = encode_coding (coding, buf, dst, len, dst_end - dst);                    string = tbase[g];
869            len -= coding->consumed;                    if (! STRING_MULTIBYTE (string))
870            dst += coding->produced;                      string = string_to_multibyte (string);
871            if (result == CODING_FINISH_INSUFFICIENT_DST                    nbytes = buf - encode_terminal_buf;
872                || (result == CODING_FINISH_INSUFFICIENT_SRC                    if (nbytes + SBYTES (string) < encode_terminal_bufsize)
873                    && len > dst_end - dst))                      {
874              /* The remaining output buffer is too short.  We must                        encode_terminal_bufsize = nbytes + SBYTES (string);
875                 break the loop here without increasing SRC so that the                        encode_terminal_buf = xrealloc (encode_terminal_buf,
876                 next call of this function starts from the same glyph.  */                                                        encode_terminal_bufsize);
877              break;                        buf = encode_terminal_buf + nbytes;
878                        }
879            if (len > 0)                    bcopy (SDATA (string), buf, SBYTES (string));
880              {                    buf += SBYTES (string);
881                /* This is the case that a code of the range 0200..0237                    nchars += SCHARS (string);
882                   exists in buf.  We must just write out such a code.  */                  }
               buf += coding->consumed;  
               while (len--)  
                 *dst++ = *buf++;  
883              }              }
884          }          }
885        src++;        src++;
886      }      }
887    
888    *consumed = src - src_start;    nbytes = buf - encode_terminal_buf;
889    return (dst - dst_start);    coding->src_multibyte = 1;
890      coding->dst_multibyte = 0;
891      if (SYMBOLP (coding->pre_write_conversion)
892          && ! NILP (Ffboundp (coding->pre_write_conversion)))
893        {
894          run_pre_write_conversin_on_c_str (&encode_terminal_buf,
895                                            &encode_terminal_bufsize,
896                                            nchars, nbytes, coding);
897          nchars = coding->produced_char;
898          nbytes = coding->produced;
899        }
900      required = nbytes + encoding_buffer_size (coding, nbytes);
901      if (encode_terminal_bufsize < required)
902        {
903          encode_terminal_bufsize = required;
904          encode_terminal_buf = xrealloc (encode_terminal_buf, required);
905        }
906    
907      encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes,
908                     nbytes, encode_terminal_bufsize - nbytes);
909      return encode_terminal_buf + nbytes;
910  }  }
911    
   
912  void  void
913  write_glyphs (string, len)  write_glyphs (string, len)
914       register struct glyph *string;       register struct glyph *string;
915       register int len;       register int len;
916  {  {
   int produced, consumed;  
917    struct frame *sf = XFRAME (selected_frame);    struct frame *sf = XFRAME (selected_frame);
918    struct frame *f = updating_frame ? updating_frame : sf;    struct frame *f = updating_frame ? updating_frame : sf;
919    unsigned char conversion_buffer[1024];    unsigned char *conversion_buffer;
920    int conversion_buffer_size = sizeof conversion_buffer;    struct coding_system *coding;
921    
922    if (write_glyphs_hook    if (write_glyphs_hook
923        && ! FRAME_TERMCAP_P (f))        && ! FRAME_TERMCAP_P (f))
# Line 933  write_glyphs (string, len) Line 941  write_glyphs (string, len)
941    
942    cmplus (len);    cmplus (len);
943    
944      /* If terminal_coding does any conversion, use it, otherwise use
945         safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here
946         because it always return 1 if the member src_multibyte is 1.  */
947      coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
948                ? &terminal_coding : &safe_terminal_coding);
949    /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at    /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
950       the tail.  */       the tail.  */
951    terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;    coding->mode &= ~CODING_MODE_LAST_BLOCK;
952    
953    while (len > 0)    while (len > 0)
954      {      {
# Line 951  write_glyphs (string, len) Line 964  write_glyphs (string, len)
964        highlight_if_desired ();        highlight_if_desired ();
965        turn_on_face (f, face_id);        turn_on_face (f, face_id);
966    
967        while (n > 0)        if (n == len)
968            /* This is the last run.  */
969            coding->mode |= CODING_MODE_LAST_BLOCK;
970          conversion_buffer = encode_terminal_code (string, n, coding);
971          if (coding->produced > 0)
972          {          {
973            /* We use a fixed size (1024 bytes) of conversion buffer.            fwrite (conversion_buffer, 1, coding->produced, stdout);
974               Usually it is sufficient, but if not, we just repeat the            if (ferror (stdout))
975               loop.  */              clearerr (stdout);
976            produced = encode_terminal_code (string, conversion_buffer,            if (termscript)
977                                             n, conversion_buffer_size,              fwrite (conversion_buffer, 1, coding->produced, termscript);
                                            &consumed);  
           if (produced > 0)  
             {  
               fwrite (conversion_buffer, 1, produced, stdout);  
               if (ferror (stdout))  
                 clearerr (stdout);  
               if (termscript)  
                 fwrite (conversion_buffer, 1, produced, termscript);  
             }  
           len -= consumed;  
           n -= consumed;  
           string += consumed;  
978          }          }
979          len -= n;
980          string += n;
981    
982        /* Turn appearance modes off.  */        /* Turn appearance modes off.  */
983        turn_off_face (f, face_id);        turn_off_face (f, face_id);
984        turn_off_highlight ();        turn_off_highlight ();
985      }      }
986    
   /* We may have to output some codes to terminate the writing.  */  
   if (CODING_REQUIRE_FLUSHING (&terminal_coding))  
     {  
       terminal_coding.mode |= CODING_MODE_LAST_BLOCK;  
       encode_coding (&terminal_coding, "", conversion_buffer,  
                      0, conversion_buffer_size);  
       if (terminal_coding.produced > 0)  
         {  
           fwrite (conversion_buffer, 1, terminal_coding.produced, stdout);  
           if (ferror (stdout))  
             clearerr (stdout);  
           if (termscript)  
             fwrite (conversion_buffer, 1, terminal_coding.produced,  
                     termscript);  
         }  
     }  
   
987    cmcheckmagic ();    cmcheckmagic ();
988  }  }
989    
# Line 1007  insert_glyphs (start, len) Line 997  insert_glyphs (start, len)
997    char *buf;    char *buf;
998    struct glyph *glyph = NULL;    struct glyph *glyph = NULL;
999    struct frame *f, *sf;    struct frame *f, *sf;
1000      unsigned char *conversion_buffer;
1001      unsigned char space[1];
1002      struct coding_system *coding;
1003    
1004    if (len <= 0)    if (len <= 0)
1005      return;      return;
# Line 1032  insert_glyphs (start, len) Line 1025  insert_glyphs (start, len)
1025    
1026    turn_on_insert ();    turn_on_insert ();
1027    cmplus (len);    cmplus (len);
1028    /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail.  */  
1029    terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK;    if (! start)
1030        space[0] = SPACEGLYPH;
1031    
1032      /* If terminal_coding does any conversion, use it, otherwise use
1033         safe_terminal_coding.  We can't use CODING_REQUIRE_ENCODING here
1034         because it always return 1 if the member src_multibyte is 1.  */
1035      coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK
1036                ? &terminal_coding : &safe_terminal_coding);
1037      /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
1038         the tail.  */
1039      coding->mode &= ~CODING_MODE_LAST_BLOCK;
1040    
1041    while (len-- > 0)    while (len-- > 0)
1042      {      {
       int produced, consumed;  
       unsigned char conversion_buffer[1024];  
       int conversion_buffer_size = sizeof conversion_buffer;  
   
1043        OUTPUT1_IF (TS_ins_char);        OUTPUT1_IF (TS_ins_char);
1044        if (!start)        if (!start)
1045          {          {
1046            conversion_buffer[0] = SPACEGLYPH;            conversion_buffer = space;
1047            produced = 1;            coding->produced = 1;
1048          }          }
1049        else        else
1050          {          {
# Line 1062  insert_glyphs (start, len) Line 1062  insert_glyphs (start, len)
1062    
1063            if (len <= 0)            if (len <= 0)
1064              /* This is the last glyph.  */              /* This is the last glyph.  */
1065              terminal_coding.mode |= CODING_MODE_LAST_BLOCK;              coding->mode |= CODING_MODE_LAST_BLOCK;
1066    
1067            /* The size of conversion buffer (1024 bytes) is surely            conversion_buffer = encode_terminal_code (glyph, 1, coding);
              sufficient for just one glyph.  */  
           produced = encode_terminal_code (glyph, conversion_buffer, 1,  
                                            conversion_buffer_size, &consumed);  
1068          }          }
1069    
1070        if (produced > 0)        if (coding->produced > 0)
1071          {          {
1072            fwrite (conversion_buffer, 1, produced, stdout);            fwrite (conversion_buffer, 1, coding->produced, stdout);
1073            if (ferror (stdout))            if (ferror (stdout))
1074              clearerr (stdout);              clearerr (stdout);
1075            if (termscript)            if (termscript)
1076              fwrite (conversion_buffer, 1, produced, termscript);              fwrite (conversion_buffer, 1, coding->produced, termscript);
1077          }          }
1078    
1079        OUTPUT1_IF (TS_pad_inserted_char);        OUTPUT1_IF (TS_pad_inserted_char);
# Line 2257  term_init (terminal_type) Line 2254  term_init (terminal_type)
2254    int status;    int status;
2255    struct frame *sf = XFRAME (selected_frame);    struct frame *sf = XFRAME (selected_frame);
2256    
2257      encode_terminal_bufsize = 0;
2258    
2259  #ifdef WINDOWSNT  #ifdef WINDOWSNT
2260    initialize_w32_display ();    initialize_w32_display ();
2261    

Legend:
Removed from v.1.156  
changed lines
  Added in v.1.157

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26