|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Motif
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are free software; you can
|
|
Packit |
b099d7 |
* redistribute them and/or modify them under the terms of the GNU
|
|
Packit |
b099d7 |
* Lesser General Public License as published by the Free Software
|
|
Packit |
b099d7 |
* Foundation; either version 2 of the License, or (at your option)
|
|
Packit |
b099d7 |
* any later version.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* These libraries and programs are distributed in the hope that
|
|
Packit |
b099d7 |
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
Packit |
b099d7 |
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
Packit |
b099d7 |
* PURPOSE. See the GNU Lesser General Public License for more
|
|
Packit |
b099d7 |
* details.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
b099d7 |
* License along with these librararies and programs; if not, write
|
|
Packit |
b099d7 |
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
Packit |
b099d7 |
* Floor, Boston, MA 02110-1301 USA
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* HISTORY
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
b099d7 |
#include <config.h>
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#ifdef REV_INFO
|
|
Packit |
b099d7 |
#ifndef lint
|
|
Packit |
b099d7 |
static char rcsid[] = "$XConsortium: TextStrSo.c /main/14 1996/10/23 16:05:21 cde-osf $"
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
Packit |
b099d7 |
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define FIX_1320
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#include <ctype.h>
|
|
Packit |
b099d7 |
#include <limits.h>
|
|
Packit |
b099d7 |
#include <X11/Xatom.h>
|
|
Packit |
b099d7 |
#include <X11/Xmd.h>
|
|
Packit |
b099d7 |
#include <Xm/AtomMgr.h>
|
|
Packit |
b099d7 |
#include <Xm/TextSelP.h>
|
|
Packit |
b099d7 |
#include <Xm/TextStrSoP.h>
|
|
Packit |
b099d7 |
#include <Xm/XmosP.h>
|
|
Packit |
b099d7 |
#include "XmI.h" /* for _XmValidTimestamp() */
|
|
Packit |
b099d7 |
#include "TextI.h"
|
|
Packit |
b099d7 |
#include "TextStrSoI.h"
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/******** Static Function Declarations ********/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void AddWidget(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextWidget tw);
|
|
Packit |
b099d7 |
static char * _XmStringSourceGetChar(XmSourceData data,
|
|
Packit |
b099d7 |
XmTextPosition position);
|
|
Packit |
b099d7 |
static int CountLines(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
unsigned long length);
|
|
Packit |
b099d7 |
static void RemoveWidget(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextWidget tw);
|
|
Packit |
b099d7 |
static void _XmStringSourceReadString(XmTextSource source,
|
|
Packit |
b099d7 |
int start,
|
|
Packit |
b099d7 |
XmTextBlock block);
|
|
Packit |
b099d7 |
static XmTextPosition ReadSource(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition position,
|
|
Packit |
b099d7 |
XmTextPosition last_position,
|
|
Packit |
b099d7 |
XmTextBlock block);
|
|
Packit |
b099d7 |
static XmTextStatus Replace(XmTextWidget initiator,
|
|
Packit |
b099d7 |
XEvent *event,
|
|
Packit |
b099d7 |
XmTextPosition *start,
|
|
Packit |
b099d7 |
XmTextPosition *end,
|
|
Packit |
b099d7 |
XmTextBlock block,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int call_callbacks);
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean call_callbacks);
|
|
Packit |
b099d7 |
#endif /* NeedsWidePrototypes */
|
|
Packit |
b099d7 |
static void ScanParagraph(XmSourceData data,
|
|
Packit |
b099d7 |
XmTextPosition *new_position,
|
|
Packit |
b099d7 |
XmTextScanDirection dir,
|
|
Packit |
b099d7 |
int ddir,
|
|
Packit |
b099d7 |
XmTextPosition *last_char);
|
|
Packit |
b099d7 |
static XmTextPosition Scan(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition pos,
|
|
Packit |
b099d7 |
XmTextScanType sType,
|
|
Packit |
b099d7 |
XmTextScanDirection dir,
|
|
Packit |
b099d7 |
int count,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int include);
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean include);
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
static Boolean GetSelection(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition *left,
|
|
Packit |
b099d7 |
XmTextPosition *right);
|
|
Packit |
b099d7 |
static void SetSelection(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition left,
|
|
Packit |
b099d7 |
XmTextPosition right,
|
|
Packit |
b099d7 |
Time set_time);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/******** End Static Function Declarations ********/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define TEXT_INCREMENT 1024
|
|
Packit |
b099d7 |
#define TEXT_INITIAL_INCREM 64
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Convert a stream of bytes into a char*, BITS16*, or wchar_t* array.
|
|
Packit |
b099d7 |
* Return number of characters created.
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* If num_chars == 1, don't add a null terminator, else if a null terminator
|
|
Packit |
b099d7 |
* is present on the byte stream, convert it and add it to the character
|
|
Packit |
b099d7 |
* array; Count returned does not include NULL terminator (just like strlen).
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* This routine assumes that a BITS16 is two-bytes;
|
|
Packit |
b099d7 |
* the routine must be modified if these assumptions are incorrect.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
int
|
|
Packit |
b099d7 |
_XmTextBytesToCharacters(char * characters,
|
|
Packit |
b099d7 |
char * bytes,
|
|
Packit |
b099d7 |
int num_chars,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int add_null_terminator,
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean add_null_terminator,
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
int max_char_size)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
unsigned char * tmp_bytes;
|
|
Packit |
b099d7 |
int num_bytes;
|
|
Packit |
b099d7 |
int count=0;
|
|
Packit |
b099d7 |
BITS16 *bits16_ptr, temp_bits16;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_ptr;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If 0 characters requested, or a null pointer passed, dont do
|
|
Packit |
b099d7 |
* anything... just return 0 characters converted.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (num_chars == 0 || bytes == NULL) return 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch (max_char_size) {
|
|
Packit |
b099d7 |
case 1: {
|
|
Packit |
b099d7 |
(void) memcpy((void*)characters, (void*)bytes, num_chars);
|
|
Packit |
b099d7 |
count = num_chars;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 1 */
|
|
Packit |
b099d7 |
case 2: {
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) characters;
|
|
Packit |
b099d7 |
tmp_bytes = (unsigned char*) bytes;
|
|
Packit |
b099d7 |
for (
|
|
Packit |
b099d7 |
#ifndef NO_MULTIBYTE
|
|
Packit |
b099d7 |
num_bytes = mblen((char*)tmp_bytes, max_char_size),
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
num_bytes = *tmp_bytes ? 1 : 0,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
temp_bits16 = 0;
|
|
Packit |
b099d7 |
num_chars > 0 && num_bytes > 0;
|
|
Packit |
b099d7 |
num_chars--,
|
|
Packit |
b099d7 |
#ifndef NO_MULTIBYTE
|
|
Packit |
b099d7 |
num_bytes = mblen((char*)tmp_bytes, max_char_size),
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
num_bytes = *tmp_bytes ? 1 : 0,
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
temp_bits16 = 0, bits16_ptr ++) {
|
|
Packit |
b099d7 |
if (num_bytes == 1) {
|
|
Packit |
b099d7 |
temp_bits16 = (BITS16) *tmp_bytes++;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
temp_bits16 = (BITS16) *tmp_bytes++;
|
|
Packit |
b099d7 |
temp_bits16 = temp_bits16 << 8;
|
|
Packit |
b099d7 |
temp_bits16 |= (BITS16) *tmp_bytes++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
*bits16_ptr = temp_bits16;
|
|
Packit |
b099d7 |
count++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* if bytes is NULL terminated, characters should be too */
|
|
Packit |
b099d7 |
if (add_null_terminator == True)
|
|
Packit |
b099d7 |
*bits16_ptr = (BITS16) 0;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 2 */
|
|
Packit |
b099d7 |
default: {
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *)characters;
|
|
Packit |
b099d7 |
count = mbstowcs(wchar_t_ptr, bytes, num_chars);
|
|
Packit |
b099d7 |
if (add_null_terminator == True && count >= 0)
|
|
Packit |
b099d7 |
wchar_t_ptr[count] = (wchar_t)0;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end default */
|
|
Packit |
b099d7 |
} /* end switch */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return count;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Convert an array of char*, BITS16*, or wchar_t* into a stream of bytes.
|
|
Packit |
b099d7 |
* Return the number of bytes placed into 'bytes'
|
|
Packit |
b099d7 |
*
|
|
Packit |
b099d7 |
* Null terminate the byte stream - caller better have alloc'ed enough space!
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* ARGSUSED */
|
|
Packit |
b099d7 |
int
|
|
Packit |
b099d7 |
_XmTextCharactersToBytes(char * bytes,
|
|
Packit |
b099d7 |
char * characters,
|
|
Packit |
b099d7 |
int num_chars,
|
|
Packit |
b099d7 |
int max_char_size)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
unsigned char *temp_char;
|
|
Packit |
b099d7 |
unsigned char *byte_ptr;
|
|
Packit |
b099d7 |
int count = 0;
|
|
Packit |
b099d7 |
int i, j;
|
|
Packit |
b099d7 |
BITS16 *bits16_ptr, temp_bits16;
|
|
Packit |
b099d7 |
wchar_t *wchars;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (num_chars == 0 || characters == 0) {
|
|
Packit |
b099d7 |
*bytes = '\0';
|
|
Packit |
b099d7 |
return 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch (max_char_size) {
|
|
Packit |
b099d7 |
case 1: {
|
|
Packit |
b099d7 |
(void) memcpy((void*)bytes, (void*)characters, num_chars);
|
|
Packit |
b099d7 |
count = num_chars;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 1 */
|
|
Packit |
b099d7 |
case 2: {
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) characters;
|
|
Packit |
b099d7 |
byte_ptr = (unsigned char*) bytes;
|
|
Packit |
b099d7 |
temp_char = (unsigned char*) XtMalloc (max_char_size);
|
|
Packit |
b099d7 |
for (i = 0; i < num_chars && *bits16_ptr != 0; i++, bits16_ptr++) {
|
|
Packit |
b099d7 |
temp_bits16 = *bits16_ptr;
|
|
Packit |
b099d7 |
/* create an array of chars; char[max_char_size - 1] contains the
|
|
Packit |
b099d7 |
* low order byte */
|
|
Packit |
b099d7 |
for (j = max_char_size - 1; j >= 0; j--) {
|
|
Packit |
b099d7 |
temp_char[j] = (unsigned char)(temp_bits16 & 0377);
|
|
Packit |
b099d7 |
temp_bits16 = temp_bits16 >> 8;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* start with high order byte. If any byte is 0, skip it. */
|
|
Packit |
b099d7 |
for (j = 0; j < max_char_size; j++) {
|
|
Packit |
b099d7 |
if (temp_char[j] > 0) {
|
|
Packit |
b099d7 |
*byte_ptr = temp_char[j];
|
|
Packit |
b099d7 |
byte_ptr++; count++;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
XtFree ((char*)temp_char);
|
|
Packit |
b099d7 |
if (count < num_chars) *byte_ptr = '\0';
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 2 */
|
|
Packit |
b099d7 |
default: {
|
|
Packit |
b099d7 |
int nbytes;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wchars = (wchar_t *)characters;
|
|
Packit |
b099d7 |
for (i = 0; i < num_chars && *wchars != 0L; i++, wchars++) {
|
|
Packit |
b099d7 |
nbytes = wctomb(bytes, *wchars);
|
|
Packit |
b099d7 |
if (nbytes < 0)
|
|
Packit |
b099d7 |
break; /* illegal char */
|
|
Packit |
b099d7 |
count += nbytes;
|
|
Packit |
b099d7 |
bytes += nbytes;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (count >= 0)
|
|
Packit |
b099d7 |
bytes[count] = '\0';
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end default */
|
|
Packit |
b099d7 |
} /* end switch */
|
|
Packit |
b099d7 |
return (count); /* return the number of bytes placed in bptr */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
char *
|
|
Packit |
b099d7 |
_XmStringSourceGetString(XmTextWidget tw,
|
|
Packit |
b099d7 |
XmTextPosition from,
|
|
Packit |
b099d7 |
XmTextPosition to,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int want_wchar)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean want_wchar)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
char *buf;
|
|
Packit |
b099d7 |
wchar_t *wc_buf;
|
|
Packit |
b099d7 |
XmTextBlockRec block;
|
|
Packit |
b099d7 |
int destpos;
|
|
Packit |
b099d7 |
XmTextPosition pos, ret_pos;
|
|
Packit |
b099d7 |
int return_val = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
destpos = 0;
|
|
Packit |
b099d7 |
if (!want_wchar) {
|
|
Packit |
b099d7 |
/* NOTE: to - from could result in a truncated long. */
|
|
Packit |
b099d7 |
buf = XtMalloc(((int)(to - from) + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
for (pos = from; pos < to; ) {
|
|
Packit |
b099d7 |
pos = ReadSource(tw->text.source, pos, to, &block);
|
|
Packit |
b099d7 |
if (block.length == 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(void)memcpy((void*)&buf[destpos], (void*)block.ptr, block.length);
|
|
Packit |
b099d7 |
destpos += block.length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
buf[destpos] = 0;
|
|
Packit |
b099d7 |
return buf;
|
|
Packit |
b099d7 |
} else { /* want buffer of wchar_t * data */
|
|
Packit |
b099d7 |
/* NOTE: to - from could result in a truncated long. */
|
|
Packit |
b099d7 |
buf = XtMalloc(((int)(to - from) + 1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
wc_buf = (wchar_t *)buf;
|
|
Packit |
b099d7 |
for (pos = from; pos < to; ) {
|
|
Packit |
b099d7 |
ret_pos = ReadSource(tw->text.source, pos, to, &block);
|
|
Packit |
b099d7 |
if (block.length == 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: ret_pos - pos could result in a truncated long. */
|
|
Packit |
b099d7 |
return_val = mbstowcs(&wc_buf[destpos], block.ptr,
|
|
Packit |
b099d7 |
(unsigned int) (ret_pos - pos));
|
|
Packit |
b099d7 |
if (return_val > 0) destpos += return_val;
|
|
Packit |
b099d7 |
pos = ret_pos;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wc_buf[destpos] = (wchar_t)0L;
|
|
Packit |
b099d7 |
return ((char*)wc_buf);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
AddWidget(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextWidget tw)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
data->numwidgets++;
|
|
Packit |
b099d7 |
data->widgets = (XmTextWidget *)
|
|
Packit |
b099d7 |
XtRealloc((char *) data->widgets,
|
|
Packit |
b099d7 |
(unsigned) (sizeof(XmTextWidget) * data->numwidgets));
|
|
Packit |
b099d7 |
data->widgets[data->numwidgets - 1] = tw;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->numwidgets == 1)
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget) tw, 0, tw->text.last_position,
|
|
Packit |
b099d7 |
XmHIGHLIGHT_NORMAL);
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
tw->text.highlight.list = (_XmHighlightRec *)
|
|
Packit |
b099d7 |
XtRealloc((char *) tw->text.highlight.list,
|
|
Packit |
b099d7 |
data->widgets[0]->text.highlight.maximum *
|
|
Packit |
b099d7 |
sizeof(_XmHighlightRec));
|
|
Packit |
b099d7 |
tw->text.highlight.maximum = data->widgets[0]->text.highlight.maximum;
|
|
Packit |
b099d7 |
tw->text.highlight.number = data->widgets[0]->text.highlight.number;
|
|
Packit |
b099d7 |
memmove((void *) tw->text.highlight.list,
|
|
Packit |
b099d7 |
(void *) data->widgets[0]->text.highlight.list,
|
|
Packit |
b099d7 |
(size_t) data->widgets[0]->text.highlight.number *
|
|
Packit |
b099d7 |
sizeof(_XmHighlightRec));
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->hasselection && data->numwidgets == 1) {
|
|
Packit |
b099d7 |
Time select_time = XtLastTimestampProcessed(XtDisplay((Widget)tw));
|
|
Packit |
b099d7 |
if (!select_time) select_time = _XmValidTimestamp((Widget)tw);
|
|
Packit |
b099d7 |
if (!XmePrimarySource((Widget) data->widgets[0], select_time)) {
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, 1, 0, select_time);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->prim_time = select_time;
|
|
Packit |
b099d7 |
cb.reason = XmCR_GAIN_PRIMARY;
|
|
Packit |
b099d7 |
cb.event = NULL;
|
|
Packit |
b099d7 |
XtCallCallbackList ((Widget) data->widgets[0],
|
|
Packit |
b099d7 |
data->widgets[0]->text.gain_primary_callback,
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/********************************<->***********************************/
|
|
Packit |
b099d7 |
static char *
|
|
Packit |
b099d7 |
_XmStringSourceGetChar(XmSourceData data,
|
|
Packit |
b099d7 |
XmTextPosition position) /* starting position */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* gap_size is the number of character in the gap, not number of bytes */
|
|
Packit |
b099d7 |
register int gap_size;
|
|
Packit |
b099d7 |
register XmTextPosition char_pos;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
int char_size;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (tw->text.char_size > 1) {
|
|
Packit |
b099d7 |
if (tw->text.char_size == 2)
|
|
Packit |
b099d7 |
char_size = 2;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
char_size = sizeof(wchar_t);
|
|
Packit |
b099d7 |
char_pos = position * char_size;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* regardless of what it contains, data->ptr is treated as a char * ptr */
|
|
Packit |
b099d7 |
if (data->ptr + char_pos < data->gap_start)
|
|
Packit |
b099d7 |
return (&data->ptr[char_pos]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
gap_size = (data->gap_end - data->gap_start) / char_size;
|
|
Packit |
b099d7 |
if (position + gap_size >= data->maxlength)
|
|
Packit |
b099d7 |
return ("");
|
|
Packit |
b099d7 |
return (&data->ptr[(position + gap_size) * char_size]);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
char_pos = position;
|
|
Packit |
b099d7 |
/* regardless of what it contains, data->ptr is treated as a char * ptr */
|
|
Packit |
b099d7 |
if (data->ptr + char_pos < data->gap_start)
|
|
Packit |
b099d7 |
return (&data->ptr[char_pos]);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
gap_size = (data->gap_end - data->gap_start);
|
|
Packit |
b099d7 |
if (char_pos + gap_size >= data->maxlength)
|
|
Packit |
b099d7 |
return ("");
|
|
Packit |
b099d7 |
return (&data->ptr[(char_pos + gap_size)]);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*DELTA: length IS NOW TREATED AS NUMBER OF CHARACTERS - CALLERS MUST CHANGE*/
|
|
Packit |
b099d7 |
static int
|
|
Packit |
b099d7 |
CountLines(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition start,
|
|
Packit |
b099d7 |
unsigned long length)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
int num_lines = 0;
|
|
Packit |
b099d7 |
unsigned long seg_length;
|
|
Packit |
b099d7 |
char *ptr;
|
|
Packit |
b099d7 |
BITS16 *bits16_ptr, *bits16_gap_start, *bits16_gap_end;
|
|
Packit |
b099d7 |
wchar_t *wchar_t_ptr, *wchar_t_gap_start, *wchar_t_gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* verify that the 'start' and 'length' parameters are reasonable */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (start + length > data->length)
|
|
Packit |
b099d7 |
length = data->length - start;
|
|
Packit |
b099d7 |
if (length == 0) return num_lines;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
seg_length = (data->gap_start - data->ptr) / (tw->text.char_size < 3 ?
|
|
Packit |
b099d7 |
(int)tw->text.char_size :
|
|
Packit |
b099d7 |
sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* make sure the segment length is not greater than the length desired */
|
|
Packit |
b099d7 |
if (length < seg_length) seg_length = length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch ((int)tw->text.char_size) {
|
|
Packit |
b099d7 |
case 1: {
|
|
Packit |
b099d7 |
/* setup the variables for the search of new lines before the gap */
|
|
Packit |
b099d7 |
ptr = data->ptr + start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* search up to gap */
|
|
Packit |
b099d7 |
while (seg_length--) {
|
|
Packit |
b099d7 |
if (*ptr++ == *(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* check to see if we need more data after the gap */
|
|
Packit |
b099d7 |
if ((int)length > data->gap_start - (data->ptr + start)) {
|
|
Packit |
b099d7 |
if (data->gap_start - (data->ptr + start) > 0) /* if we searched
|
|
Packit |
b099d7 |
* before gap,
|
|
Packit |
b099d7 |
* adjust length */
|
|
Packit |
b099d7 |
length -= data->gap_start - (data->ptr + start);
|
|
Packit |
b099d7 |
ptr = data->gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* continue search till length is completed */
|
|
Packit |
b099d7 |
while (length--) {
|
|
Packit |
b099d7 |
if (*ptr++ == *(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 1 */
|
|
Packit |
b099d7 |
case 2: {
|
|
Packit |
b099d7 |
/* setup the variables for the search of new lines before the gap */
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) data->ptr;
|
|
Packit |
b099d7 |
bits16_gap_start = (BITS16 *) data->gap_start;
|
|
Packit |
b099d7 |
bits16_gap_end = (BITS16 *) data->gap_end;
|
|
Packit |
b099d7 |
bits16_ptr += start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* search up to gap */
|
|
Packit |
b099d7 |
while (seg_length--) {
|
|
Packit |
b099d7 |
if (*bits16_ptr++ == *(BITS16 *)(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* check to see if we need more data after the gap */
|
|
Packit |
b099d7 |
if ((int)length > bits16_gap_start - ((BITS16 *)data->ptr + start)) {
|
|
Packit |
b099d7 |
/* if we searched before gap, adjust length */
|
|
Packit |
b099d7 |
if (bits16_gap_start - ((BITS16 *)data->ptr + start) > 0)
|
|
Packit |
b099d7 |
length -= bits16_gap_start - ((BITS16 *)data->ptr + start);
|
|
Packit |
b099d7 |
bits16_ptr = bits16_gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* continue search till length is completed */
|
|
Packit |
b099d7 |
while (length--) {
|
|
Packit |
b099d7 |
if (*bits16_ptr++ == *(BITS16 *)(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end case 2 */
|
|
Packit |
b099d7 |
default: {
|
|
Packit |
b099d7 |
/* setup the variables for the search of new lines before the gap */
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) data->ptr;
|
|
Packit |
b099d7 |
wchar_t_gap_start = (wchar_t *) data->gap_start;
|
|
Packit |
b099d7 |
wchar_t_gap_end = (wchar_t *) data->gap_end;
|
|
Packit |
b099d7 |
wchar_t_ptr += start;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* search up to gap */
|
|
Packit |
b099d7 |
while (seg_length--) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr++ == *(wchar_t *)(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* check to see if we need more data after the gap */
|
|
Packit |
b099d7 |
if ((int)length > wchar_t_gap_start - ((wchar_t *)data->ptr + start)) {
|
|
Packit |
b099d7 |
/* if we searched before gap, adjust length */
|
|
Packit |
b099d7 |
if (wchar_t_gap_start - ((wchar_t *)data->ptr + start) > 0)
|
|
Packit |
b099d7 |
length -= wchar_t_gap_start - ((wchar_t *)data->ptr + start);
|
|
Packit |
b099d7 |
wchar_t_ptr = wchar_t_gap_end;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* continue search till length is completed */
|
|
Packit |
b099d7 |
while (length--) {
|
|
Packit |
b099d7 |
if (*wchar_t_ptr++ == *(wchar_t *)(data->PSWC_NWLN)) ++num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} /* end default */
|
|
Packit |
b099d7 |
} /* end switch */
|
|
Packit |
b099d7 |
return num_lines;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
RemoveWidget(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextWidget tw)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
if (data->widgets[i] == tw) {
|
|
Packit |
b099d7 |
XmTextPosition left, right;
|
|
Packit |
b099d7 |
Boolean had_selection = False;
|
|
Packit |
b099d7 |
Time select_time =
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay((Widget)tw));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->hasselection) {
|
|
Packit |
b099d7 |
(*source->GetSelection)(source, &left, &right);
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, 1, -999, select_time);
|
|
Packit |
b099d7 |
had_selection = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
data->numwidgets--;
|
|
Packit |
b099d7 |
data->widgets[i] = data->widgets[data->numwidgets];
|
|
Packit |
b099d7 |
if (i == 0 && data->numwidgets > 0 && had_selection)
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, left, right, select_time);
|
|
Packit |
b099d7 |
if (data->numwidgets == 0) _XmStringSourceDestroy(source);
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean *
|
|
Packit |
b099d7 |
_XmStringSourceGetPending(XmTextWidget tw)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean *pending;
|
|
Packit |
b099d7 |
XmSourceData data = tw->text.source->data;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
pending = (Boolean *)XtMalloc(data->numwidgets*sizeof(Boolean));
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++)
|
|
Packit |
b099d7 |
pending[i] = ((XmTextWidget)data->widgets[i])->text.pendingoff;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return pending;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceSetPending(XmTextWidget tw,
|
|
Packit |
b099d7 |
Boolean *pending)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = tw->text.source->data;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if ((long)pending > 1)
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++)
|
|
Packit |
b099d7 |
((XmTextWidget)data->widgets[i])->text.pendingoff = pending[i];
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++)
|
|
Packit |
b099d7 |
((XmTextWidget)data->widgets[i])->text.pendingoff =
|
|
Packit |
b099d7 |
(Boolean)(long)pending;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Determines where to move the gap and calls memmove to move the gap.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
/********************************<->***********************************/
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceSetGappedBuffer(XmSourceData data,
|
|
Packit |
b099d7 |
XmTextPosition position) /* starting position */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
int count, char_size = (tw->text.char_size < 3 ?
|
|
Packit |
b099d7 |
(int)tw->text.char_size :
|
|
Packit |
b099d7 |
sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if no change in gap placement, return */
|
|
Packit |
b099d7 |
if (data->ptr + (position * char_size) == data->gap_start)
|
|
Packit |
b099d7 |
return;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->ptr + (position * char_size) < data->gap_start) {
|
|
Packit |
b099d7 |
/* move gap to the left */
|
|
Packit |
b099d7 |
count = data->gap_start -
|
|
Packit |
b099d7 |
(data->ptr + (position * char_size));
|
|
Packit |
b099d7 |
memmove(data->gap_end - count, data->ptr + (position*char_size), count);
|
|
Packit |
b099d7 |
data->gap_start -= count; /* ie, data->gap_start = position; */
|
|
Packit |
b099d7 |
data->gap_end -= count; /* ie, data->gap_end = position + gap_size; */
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
/* move gap to the right */
|
|
Packit |
b099d7 |
count = (data->ptr +
|
|
Packit |
b099d7 |
(position * char_size)) - data->gap_start;
|
|
Packit |
b099d7 |
memmove(data->gap_start, data->gap_end, count);
|
|
Packit |
b099d7 |
data->gap_start += count; /* ie, data->gap_start = position; */
|
|
Packit |
b099d7 |
data->gap_end += count; /* ie, data->gap_end = position + gap_size; */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/********************************<->***********************************/
|
|
Packit |
b099d7 |
/* The only caller of this routine expects to get char* in block */
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
_XmStringSourceReadString(XmTextSource source,
|
|
Packit |
b099d7 |
int start,
|
|
Packit |
b099d7 |
XmTextBlock block)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
int gap_size = data->gap_end - data->gap_start;
|
|
Packit |
b099d7 |
int byte_start = start * (tw->text.char_size < 3 ?
|
|
Packit |
b099d7 |
(int)tw->text.char_size :
|
|
Packit |
b099d7 |
sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->ptr + byte_start + block->length <= data->gap_start)
|
|
Packit |
b099d7 |
block->ptr = data->ptr + byte_start;
|
|
Packit |
b099d7 |
else if (data->ptr + byte_start + gap_size >= data->gap_end)
|
|
Packit |
b099d7 |
block->ptr = data->ptr + byte_start + gap_size;
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
block->ptr = data->ptr + byte_start;
|
|
Packit |
b099d7 |
block->length = data->gap_start - (data->ptr + byte_start);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Caller wants block to contain char*; _XmStringSourceReadString provides
|
|
Packit |
b099d7 |
* char*, BITS16* or wchar_t*; so we need to modify what it gives us.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
static XmTextPosition
|
|
Packit |
b099d7 |
ReadSource(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition position, /* starting position */
|
|
Packit |
b099d7 |
XmTextPosition last_position, /* The last position we're interested
|
|
Packit |
b099d7 |
in. Don't return info about any
|
|
Packit |
b099d7 |
later positions. */
|
|
Packit |
b099d7 |
XmTextBlock block) /* RETURN: text read in */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextPosition return_pos;
|
|
Packit |
b099d7 |
int num_bytes;
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
int char_size = (tw->text.char_size < 3 ?
|
|
Packit |
b099d7 |
(int)tw->text.char_size :
|
|
Packit |
b099d7 |
sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (last_position > data->length) last_position = data->length;
|
|
Packit |
b099d7 |
/* NOTE: the length calculation could result in a truncated long */
|
|
Packit |
b099d7 |
block->length = (int)((last_position - position) * char_size);
|
|
Packit |
b099d7 |
if (block->length < 0 ) block->length = 0;
|
|
Packit |
b099d7 |
block->format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
_XmStringSourceReadString(source, (int)position, block);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (block->length > 0) {
|
|
Packit |
b099d7 |
if (data->old_length == 0) {
|
|
Packit |
b099d7 |
data->value = (char *)
|
|
Packit |
b099d7 |
XtMalloc((unsigned)(block->length + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
data->old_length = block->length;
|
|
Packit |
b099d7 |
} else if (block->length > data->old_length) {
|
|
Packit |
b099d7 |
data->value = XtRealloc(data->value, (unsigned)
|
|
Packit |
b099d7 |
((block->length + 1) * (int)tw->text.char_size));
|
|
Packit |
b099d7 |
data->old_length = block->length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if ((int)tw->text.char_size == 1) {
|
|
Packit |
b099d7 |
return_pos = position + block->length;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
return_pos = position + (block->length / char_size);
|
|
Packit |
b099d7 |
num_bytes = _XmTextCharactersToBytes(data->value, block->ptr,
|
|
Packit |
b099d7 |
block->length / char_size,
|
|
Packit |
b099d7 |
(int)tw->text.char_size);
|
|
Packit |
b099d7 |
block->length = num_bytes;
|
|
Packit |
b099d7 |
block->ptr = data->value;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return return_pos;
|
|
Packit |
b099d7 |
} else
|
|
Packit |
b099d7 |
return 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmTextValidate(XmTextPosition * start,
|
|
Packit |
b099d7 |
XmTextPosition * end,
|
|
Packit |
b099d7 |
int maxsize)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (*start < 0) *start = 0;
|
|
Packit |
b099d7 |
if (*start > maxsize) {
|
|
Packit |
b099d7 |
*start = maxsize;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (*end < 0) *end = 0;
|
|
Packit |
b099d7 |
if (*end > maxsize) {
|
|
Packit |
b099d7 |
*end = maxsize;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*start > *end) {
|
|
Packit |
b099d7 |
XmTextPosition tmp; /* tmp variable for swapping positions */
|
|
Packit |
b099d7 |
tmp = *end;
|
|
Packit |
b099d7 |
*end = *start;
|
|
Packit |
b099d7 |
*start = tmp;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmTextModifyVerify(XmTextWidget initiator,
|
|
Packit |
b099d7 |
XEvent *event,
|
|
Packit |
b099d7 |
XmTextPosition *start,
|
|
Packit |
b099d7 |
XmTextPosition *end,
|
|
Packit |
b099d7 |
XmTextPosition *cursorPos, /* RETURN, may be NULL if not */
|
|
Packit |
b099d7 |
XmTextBlock block,
|
|
Packit |
b099d7 |
XmTextBlock newblock, /* RETURN */
|
|
Packit |
b099d7 |
Boolean *freeBlock)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
register XmSourceData data = initiator->text.source->data;
|
|
Packit |
b099d7 |
register long delta;
|
|
Packit |
b099d7 |
register int block_num_chars; /* number of characters in the block */
|
|
Packit |
b099d7 |
XmTextPosition newInsert = initiator->text.cursor_position;
|
|
Packit |
b099d7 |
XmTextVerifyCallbackStruct tvcb;
|
|
Packit |
b099d7 |
XmTextVerifyCallbackStructWcs wcs_tvcb;
|
|
Packit |
b099d7 |
XmTextBlockRecWcs wcs_newblock;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*start == *end && block->length == 0) return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextValidate(start, end, data->length);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
newblock->length = block->length; /* RETURNed values */
|
|
Packit |
b099d7 |
newblock->format = block->format;
|
|
Packit |
b099d7 |
newblock->ptr = block->ptr;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!initiator->text.modify_verify_callback &&
|
|
Packit |
b099d7 |
!initiator->text.wcs_modify_verify_callback)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
/* we have neither callback, so do expensive
|
|
Packit |
b099d7 |
** computation only if cursorPos is needed
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (cursorPos)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
block_num_chars = _XmTextCountCharacters(block->ptr, block->length);
|
|
Packit |
b099d7 |
*cursorPos = *start + block_num_chars;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* cursorPos may be needed to be returned. If not, and if the text is
|
|
Packit |
b099d7 |
** not editable, can drop out now
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (!cursorPos && !data->editable)
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* there is at least one callback, so block_num_chars is needed;
|
|
Packit |
b099d7 |
** this is the potentially-expensive operation that we're trying to avoid
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
block_num_chars = _XmTextCountCharacters(block->ptr, block->length);
|
|
Packit |
b099d7 |
if (cursorPos) *cursorPos = *start + block_num_chars;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!data->editable) /* if cursorPos was needed, it's set; can now drop out */
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* we have at least one callback on editable text, and cursorPos may or may
|
|
Packit |
b099d7 |
** not need to be set. block_num_chars has been set, so perform some other
|
|
Packit |
b099d7 |
** quick evaluations on whether or not the modify is reasonable. Then
|
|
Packit |
b099d7 |
** call one or both of the callbacks, and if necessary reset cursorPos.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
delta = block_num_chars - (*end - *start);
|
|
Packit |
b099d7 |
if (delta > 0 && (data->length + delta > data->maxallowed))
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If both modify_verify and modify_verify_wcs are registered:
|
|
Packit |
b099d7 |
* - first call the char* callback, then
|
|
Packit |
b099d7 |
* - pass the modified data from the char* callback to the
|
|
Packit |
b099d7 |
* wchar_t callback.
|
|
Packit |
b099d7 |
* If programmers set both callback lists, they get's what they asked for.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
wcs_newblock.wcsptr = (wchar_t *)NULL;
|
|
Packit |
b099d7 |
wcs_newblock.length = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If there are char* callbacks registered, call them. */
|
|
Packit |
b099d7 |
if (initiator->text.modify_verify_callback) {
|
|
Packit |
b099d7 |
/* Fill in the block to pass to the callback. */
|
|
Packit |
b099d7 |
if (block->length) {
|
|
Packit |
b099d7 |
newblock->ptr = (char *) XtMalloc(block->length + 1);
|
|
Packit |
b099d7 |
*freeBlock = True;
|
|
Packit |
b099d7 |
(void) memcpy((void*) newblock->ptr, (void*) block->ptr,
|
|
Packit |
b099d7 |
block->length);
|
|
Packit |
b099d7 |
newblock->ptr[block->length] = '\0';
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Call Verification Callback to indicate that text is being modified */
|
|
Packit |
b099d7 |
tvcb.reason = XmCR_MODIFYING_TEXT_VALUE;
|
|
Packit |
b099d7 |
tvcb.event = event;
|
|
Packit |
b099d7 |
tvcb.currInsert = (XmTextPosition) (initiator->text.cursor_position);
|
|
Packit |
b099d7 |
tvcb.newInsert = (XmTextPosition) (initiator->text.cursor_position);
|
|
Packit |
b099d7 |
tvcb.startPos = *start;
|
|
Packit |
b099d7 |
tvcb.endPos = *end;
|
|
Packit |
b099d7 |
tvcb.doit = True;
|
|
Packit |
b099d7 |
tvcb.text = newblock;
|
|
Packit |
b099d7 |
XtCallCallbackList ((Widget) initiator,
|
|
Packit |
b099d7 |
initiator->text.modify_verify_callback,
|
|
Packit |
b099d7 |
(XtPointer) &tvcb);
|
|
Packit |
b099d7 |
/* If doit flag is false, application wants to negate the action,
|
|
Packit |
b099d7 |
* so free allocate space and return False.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (!tvcb.doit) {
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr)
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*start = tvcb.startPos;
|
|
Packit |
b099d7 |
*end = tvcb.endPos;
|
|
Packit |
b099d7 |
newInsert = tvcb.newInsert;
|
|
Packit |
b099d7 |
_XmTextValidate (start, end, data->length);
|
|
Packit |
b099d7 |
if (tvcb.text != newblock || tvcb.text->ptr != newblock->ptr) {
|
|
Packit |
b099d7 |
newblock->length = tvcb.text->length;
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr)
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
if (newblock->length) {
|
|
Packit |
b099d7 |
newblock->ptr = XtMalloc(newblock->length + 1);
|
|
Packit |
b099d7 |
*freeBlock = True;
|
|
Packit |
b099d7 |
(void)memcpy((void*)newblock->ptr, (void*)tvcb.text->ptr,
|
|
Packit |
b099d7 |
tvcb.text->length);
|
|
Packit |
b099d7 |
} else newblock->ptr = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
newblock->format = tvcb.text->format;
|
|
Packit |
b099d7 |
block_num_chars = _XmTextCountCharacters(newblock->ptr,
|
|
Packit |
b099d7 |
newblock->length);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
delta = block_num_chars - (*end - *start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (delta > 0 && data->length + delta > data->maxallowed &&
|
|
Packit |
b099d7 |
(!UnderVerifyPreedit(initiator))) {
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr)
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} /* end if there are char* modify verify callbacks */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (initiator->text.wcs_modify_verify_callback) {
|
|
Packit |
b099d7 |
wcs_newblock.wcsptr = (wchar_t *)XtMalloc((unsigned)sizeof(wchar_t) *
|
|
Packit |
b099d7 |
(newblock->length + 1));
|
|
Packit |
b099d7 |
wcs_newblock.length = mbstowcs(wcs_newblock.wcsptr, newblock->ptr,
|
|
Packit |
b099d7 |
block_num_chars);
|
|
Packit |
b099d7 |
if (wcs_newblock.length < 0) wcs_newblock.length = 0;
|
|
Packit |
b099d7 |
wcs_tvcb.reason = XmCR_MODIFYING_TEXT_VALUE;
|
|
Packit |
b099d7 |
wcs_tvcb.event = event;
|
|
Packit |
b099d7 |
wcs_tvcb.currInsert = initiator->text.cursor_position;
|
|
Packit |
b099d7 |
wcs_tvcb.newInsert = initiator->text.cursor_position;
|
|
Packit |
b099d7 |
wcs_tvcb.startPos = *start;
|
|
Packit |
b099d7 |
wcs_tvcb.endPos = *end;
|
|
Packit |
b099d7 |
wcs_tvcb.doit = True;
|
|
Packit |
b099d7 |
wcs_tvcb.text = &wcs_newblock;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget) initiator,
|
|
Packit |
b099d7 |
initiator->text.wcs_modify_verify_callback,
|
|
Packit |
b099d7 |
(XtPointer) &wcs_tvcb);
|
|
Packit |
b099d7 |
if (!wcs_tvcb.doit) {
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr)
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
if (wcs_newblock.wcsptr) XtFree((char*)wcs_newblock.wcsptr);
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*start = wcs_tvcb.startPos;
|
|
Packit |
b099d7 |
*end = wcs_tvcb.endPos;
|
|
Packit |
b099d7 |
newInsert = wcs_tvcb.newInsert;
|
|
Packit |
b099d7 |
_XmTextValidate (start, end, data->length);
|
|
Packit |
b099d7 |
/* use newblock as a temporary holder and put the char*
|
|
Packit |
b099d7 |
* data there */
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr) {
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
newblock->ptr = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
if (wcs_tvcb.text->length) {
|
|
Packit |
b099d7 |
newblock->ptr = (char*) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(1 + wcs_tvcb.text->length) *
|
|
Packit |
b099d7 |
(int)initiator->text.char_size);
|
|
Packit |
b099d7 |
*freeBlock = True;
|
|
Packit |
b099d7 |
wcs_tvcb.text->wcsptr[wcs_tvcb.text->length] = (wchar_t) 0L;
|
|
Packit |
b099d7 |
/* NOTE: wcstombs returns a long which could be truncated */
|
|
Packit |
b099d7 |
newblock->length = (int) wcstombs(newblock->ptr,
|
|
Packit |
b099d7 |
wcs_tvcb.text->wcsptr,
|
|
Packit |
b099d7 |
(wcs_tvcb.text->length + 1) *
|
|
Packit |
b099d7 |
(int)initiator->text.char_size);
|
|
Packit |
b099d7 |
if (newblock->length < 0) newblock->length = 0;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
newblock->ptr = NULL;
|
|
Packit |
b099d7 |
newblock->length = 0;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block_num_chars = wcs_tvcb.text->length;
|
|
Packit |
b099d7 |
delta = block_num_chars - (*end - *start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if the wcstombs found bad data, newblock->length is negative */
|
|
Packit |
b099d7 |
if ((delta > 0 && data->length + delta > data->maxallowed &&
|
|
Packit |
b099d7 |
(!UnderVerifyPreedit(initiator))) ||
|
|
Packit |
b099d7 |
newblock->length < 0) {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (newblock->ptr && newblock->ptr != block->ptr)
|
|
Packit |
b099d7 |
XtFree(newblock->ptr);
|
|
Packit |
b099d7 |
*freeBlock = False;
|
|
Packit |
b099d7 |
if (wcs_newblock.wcsptr) XtFree((char*)wcs_newblock.wcsptr);
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* If we alloced space for the wcs_newblock, we need to clean it up */
|
|
Packit |
b099d7 |
if (wcs_newblock.wcsptr) XtFree((char*)wcs_newblock.wcsptr);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
} /* end if there are wide char modify verify callbacks */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (cursorPos)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (initiator->text.cursor_position != newInsert) /* true only if we have callbacks */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
if (newInsert > data->length + delta) {
|
|
Packit |
b099d7 |
*cursorPos = data->length + delta;
|
|
Packit |
b099d7 |
} else if (newInsert < 0) {
|
|
Packit |
b099d7 |
*cursorPos = 0;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*cursorPos = newInsert;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
*cursorPos = *start + block_num_chars;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*ARGSUSED*/
|
|
Packit |
b099d7 |
static XmTextStatus
|
|
Packit |
b099d7 |
Replace(XmTextWidget initiator,
|
|
Packit |
b099d7 |
XEvent * event, /* unused */
|
|
Packit |
b099d7 |
XmTextPosition *start,
|
|
Packit |
b099d7 |
XmTextPosition *end,
|
|
Packit |
b099d7 |
XmTextBlock block,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int call_callbacks) /* unused */
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean call_callbacks) /* unused */
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
register XmSourceData data = initiator->text.source->data;
|
|
Packit |
b099d7 |
register int i;
|
|
Packit |
b099d7 |
register long delta;
|
|
Packit |
b099d7 |
register int block_num_chars; /* number of characters in the block */
|
|
Packit |
b099d7 |
int gap_size;
|
|
Packit |
b099d7 |
int old_maxlength;
|
|
Packit |
b099d7 |
int char_size = (initiator->text.char_size < 3 ?
|
|
Packit |
b099d7 |
(int)initiator->text.char_size :
|
|
Packit |
b099d7 |
sizeof(wchar_t));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (*start == *end && block->length == 0) return EditReject;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextValidate(start, end, data->length);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
block_num_chars = _XmTextCountCharacters(block->ptr, block->length);
|
|
Packit |
b099d7 |
delta = block_num_chars - (*end - *start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!data->editable ||
|
|
Packit |
b099d7 |
(delta > 0 && data->length + delta > data->maxallowed &&
|
|
Packit |
b099d7 |
(!UnderVerifyPreedit(initiator))))
|
|
Packit |
b099d7 |
return EditError;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/**********************************************************************/
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
initiator->text.output->DrawInsertionPoint(initiator,
|
|
Packit |
b099d7 |
initiator->text.cursor_position,
|
|
Packit |
b099d7 |
off);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Move the gap to the editing position (*start). */
|
|
Packit |
b099d7 |
_XmStringSourceSetGappedBuffer(data, *start);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
_XmTextDisableRedisplay(data->widgets[i], TRUE);
|
|
Packit |
b099d7 |
if (data->hasselection)
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget)data->widgets[i], data->left,
|
|
Packit |
b099d7 |
data->right, XmHIGHLIGHT_NORMAL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
old_maxlength = data->maxlength;
|
|
Packit |
b099d7 |
if (data->length + delta >= data->maxlength) {
|
|
Packit |
b099d7 |
int gap_start_offset, gap_end_offset;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (data->length + delta >= data->maxlength) {
|
|
Packit |
b099d7 |
if (data->maxlength < TEXT_INCREMENT)
|
|
Packit |
b099d7 |
data->maxlength *= 2;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
data->maxlength += TEXT_INCREMENT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
gap_start_offset = data->gap_start - data->ptr;
|
|
Packit |
b099d7 |
gap_end_offset = data->gap_end - data->ptr;
|
|
Packit |
b099d7 |
data->ptr = XtRealloc(data->ptr, (unsigned)
|
|
Packit |
b099d7 |
((data->maxlength) * char_size));
|
|
Packit |
b099d7 |
data->gap_start = data->ptr + gap_start_offset;
|
|
Packit |
b099d7 |
data->gap_end = data->ptr + gap_end_offset +
|
|
Packit |
b099d7 |
(char_size * (data->maxlength - old_maxlength));
|
|
Packit |
b099d7 |
if (gap_end_offset != (old_maxlength * char_size))
|
|
Packit |
b099d7 |
memmove(data->gap_end, data->ptr + gap_end_offset,
|
|
Packit |
b099d7 |
(char_size * old_maxlength) - gap_end_offset);
|
|
Packit |
b099d7 |
/* Do something to move the allocated space into the buffer */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: the value of delta could be truncated by cast to int. */
|
|
Packit |
b099d7 |
data->length += (int) delta;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->hasselection && *start < data->right && *end > data->left) {
|
|
Packit |
b099d7 |
if (*start <= data->left) {
|
|
Packit |
b099d7 |
if (*end < data->right) {
|
|
Packit |
b099d7 |
data->left = *end; /* delete encompasses left half of the
|
|
Packit |
b099d7 |
selection so move left endpoint */
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
data->right = data->left; /* delete encompasses the selection
|
|
Packit |
b099d7 |
so set selection to NULL */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (*end >= data->right) {
|
|
Packit |
b099d7 |
data->right = *start; /* delete encompasses the right half of the
|
|
Packit |
b099d7 |
selection so move right endpoint */
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
data->right -= (*end - *start); /* delete is completely within the
|
|
Packit |
b099d7 |
selection so shrink the selection */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* delete data */
|
|
Packit |
b099d7 |
gap_size = data->gap_end - data->gap_start;
|
|
Packit |
b099d7 |
/* expand the end of the gap to the right */
|
|
Packit |
b099d7 |
if ((data->ptr + gap_size + (*end * char_size)) > data->gap_end)
|
|
Packit |
b099d7 |
data->gap_end += ((*end - *start) * char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* add data */
|
|
Packit |
b099d7 |
/* copy the data into the gap_start and increment the gap start pointer */
|
|
Packit |
b099d7 |
/* convert data from char* to characters and copy into the gapped buffer */
|
|
Packit |
b099d7 |
if ((int)initiator->text.char_size == 1) {
|
|
Packit |
b099d7 |
for (i=0; i < block->length; i++) {
|
|
Packit |
b099d7 |
/* if (data->gap_start == data->gap_end) break; */
|
|
Packit |
b099d7 |
*data->gap_start++ = block->ptr[i];
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
data->gap_start += char_size *
|
|
Packit |
b099d7 |
_XmTextBytesToCharacters(data->gap_start,
|
|
Packit |
b099d7 |
&block->ptr[0],
|
|
Packit |
b099d7 |
block_num_chars, False,
|
|
Packit |
b099d7 |
(int)initiator->text.char_size);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->hasselection && data->left != data->right) {
|
|
Packit |
b099d7 |
if (*end <= data->left) {
|
|
Packit |
b099d7 |
data->left += delta;
|
|
Packit |
b099d7 |
data->right += delta;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (data->left > data->right)
|
|
Packit |
b099d7 |
data->right = data->left;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
_XmTextInvalidate(data->widgets[i], *start, *end, delta);
|
|
Packit |
b099d7 |
_XmTextUpdateLineTable((Widget) data->widgets[i], *start,
|
|
Packit |
b099d7 |
*end, block, True);
|
|
Packit |
b099d7 |
if (data->hasselection)
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget)data->widgets[i], data->left,
|
|
Packit |
b099d7 |
data->right, XmHIGHLIGHT_SELECTED);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
_XmTextEnableRedisplay(data->widgets[i]);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
initiator->text.output->DrawInsertionPoint(initiator,
|
|
Packit |
b099d7 |
initiator->text.cursor_position,
|
|
Packit |
b099d7 |
on);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->maxlength != TEXT_INITIAL_INCREM &&
|
|
Packit |
b099d7 |
((data->maxlength > TEXT_INCREMENT &&
|
|
Packit |
b099d7 |
data->length <= data->maxlength - TEXT_INCREMENT) ||
|
|
Packit |
b099d7 |
data->length <= data->maxlength >> 1)) {
|
|
Packit |
b099d7 |
/* Move the gap to the last position. */
|
|
Packit |
b099d7 |
_XmStringSourceSetGappedBuffer(data, data->length);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->maxlength = TEXT_INITIAL_INCREM;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (data->length >= data->maxlength) {
|
|
Packit |
b099d7 |
if (data->maxlength < TEXT_INCREMENT)
|
|
Packit |
b099d7 |
data->maxlength *= 2;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
data->maxlength += TEXT_INCREMENT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->ptr = XtRealloc(data->ptr, (unsigned)
|
|
Packit |
b099d7 |
((data->maxlength) * char_size));
|
|
Packit |
b099d7 |
data->gap_start = data->ptr + (data->length * char_size);
|
|
Packit |
b099d7 |
data->gap_end = data->ptr + ((data->maxlength - 1) * char_size);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
return EditDone;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define Increment(data, position, direction)\
|
|
Packit |
b099d7 |
{\
|
|
Packit |
b099d7 |
if (direction == XmsdLeft) {\
|
|
Packit |
b099d7 |
if (position > 0) \
|
|
Packit |
b099d7 |
position--;\
|
|
Packit |
b099d7 |
} else {\
|
|
Packit |
b099d7 |
if (position < data->length)\
|
|
Packit |
b099d7 |
position++;\
|
|
Packit |
b099d7 |
}\
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
#define Look(data, position, dir) \
|
|
Packit |
b099d7 |
((dir == XmsdLeft) \
|
|
Packit |
b099d7 |
? ((position) ? _XmStringSourceGetChar(data, position - 1) \
|
|
Packit |
b099d7 |
: NULL) \
|
|
Packit |
b099d7 |
: ((position == data->length) ? NULL \
|
|
Packit |
b099d7 |
: _XmStringSourceGetChar(data, position)))
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
ScanParagraph(XmSourceData data,
|
|
Packit |
b099d7 |
XmTextPosition *new_position,
|
|
Packit |
b099d7 |
XmTextScanDirection dir,
|
|
Packit |
b099d7 |
int ddir,
|
|
Packit |
b099d7 |
XmTextPosition *last_char)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
Boolean found = False;
|
|
Packit |
b099d7 |
XmTextPosition position = *new_position;
|
|
Packit |
b099d7 |
char mb_char[1 + MB_LEN_MAX];
|
|
Packit |
b099d7 |
char * c;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (position >= 0 && position <= data->length) {
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
/* DELTA: EFFECIENCY: LEAVE AS SHORT*, INT*, ... COMPARE TO PSWC_NWLN */
|
|
Packit |
b099d7 |
c = Look(data, position, dir);
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char, c, 1,
|
|
Packit |
b099d7 |
(int)data->widgets[0]->text.char_size);
|
|
Packit |
b099d7 |
if (mb_char && *mb_char == '\n') {
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
c = Look(data, position + ddir, dir);
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char, c, 1,
|
|
Packit |
b099d7 |
(int)data->widgets[0]->text.char_size);
|
|
Packit |
b099d7 |
while (mb_char && isspace((unsigned char)*mb_char)) {
|
|
Packit |
b099d7 |
if (*mb_char == '\n') {
|
|
Packit |
b099d7 |
found = True;
|
|
Packit |
b099d7 |
while (mb_char && isspace((unsigned char)*mb_char)) {
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
c = Look(data, position + ddir, dir);
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char, c, 1,
|
|
Packit |
b099d7 |
(int)data->widgets[0]->text.char_size);
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
c = Look(data, position + ddir, dir);
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char, c, 1,
|
|
Packit |
b099d7 |
(int)data->widgets[0]->text.char_size);
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
/* BEGIN 3145 fix -- Do not bypass a nonspace character */
|
|
Packit |
b099d7 |
if (!isspace((unsigned char)*c))
|
|
Packit |
b099d7 |
*last_char = (position) + ddir;
|
|
Packit |
b099d7 |
/* END 3145 */
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (found) break;
|
|
Packit |
b099d7 |
} else if (mb_char && !isspace((unsigned char)*mb_char)) {
|
|
Packit |
b099d7 |
*last_char = (position) + ddir;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if(((dir == XmsdRight) && (position == data->length)) ||
|
|
Packit |
b099d7 |
((dir == XmsdLeft) && (position == 0)))
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
*new_position = position;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static XmTextPosition
|
|
Packit |
b099d7 |
Scan(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition pos,
|
|
Packit |
b099d7 |
XmTextScanType sType,
|
|
Packit |
b099d7 |
XmTextScanDirection dir,
|
|
Packit |
b099d7 |
int count,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int include)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean include)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
register long whiteSpace = -1;
|
|
Packit |
b099d7 |
register XmTextPosition position = pos;
|
|
Packit |
b099d7 |
register int i;
|
|
Packit |
b099d7 |
XmTextPosition temp;
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget)data->widgets[0];
|
|
Packit |
b099d7 |
char * c;
|
|
Packit |
b099d7 |
BITS16 * bits16_ptr;
|
|
Packit |
b099d7 |
wchar_t * wchar_t_ptr;
|
|
Packit |
b099d7 |
char mb_char[1 + MB_LEN_MAX];
|
|
Packit |
b099d7 |
Boolean start_is_mb, cur_is_mb; /* False == 1-byte char, else multi-byte */
|
|
Packit |
b099d7 |
int num_bytes = 0;
|
|
Packit |
b099d7 |
int ddir = (dir == XmsdRight) ? 1 : -1;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
switch (sType) {
|
|
Packit |
b099d7 |
case XmSELECT_POSITION:
|
|
Packit |
b099d7 |
if (!include && count > 0)
|
|
Packit |
b099d7 |
count -= 1;
|
|
Packit |
b099d7 |
for (i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case XmSELECT_WHITESPACE:
|
|
Packit |
b099d7 |
case XmSELECT_WORD:
|
|
Packit |
b099d7 |
if (tw->text.char_size == 1) {
|
|
Packit |
b099d7 |
char * c;
|
|
Packit |
b099d7 |
for (i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
whiteSpace = -1;
|
|
Packit |
b099d7 |
while (position >= 0 && position <= data->length) {
|
|
Packit |
b099d7 |
c = Look(data, position, dir);
|
|
Packit |
b099d7 |
if (c && isspace((unsigned char)*c)) {
|
|
Packit |
b099d7 |
if (whiteSpace < 0) whiteSpace = position;
|
|
Packit |
b099d7 |
#ifdef FIX_1320
|
|
Packit |
b099d7 |
if (*c == '\n') break;
|
|
Packit |
b099d7 |
#endif
|
|
Packit |
b099d7 |
} else if (whiteSpace >= 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
position += ddir;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
for (i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
whiteSpace = -1;
|
|
Packit |
b099d7 |
num_bytes = _XmTextCharactersToBytes(mb_char,
|
|
Packit |
b099d7 |
Look(data, position, dir),
|
|
Packit |
b099d7 |
1,(int)tw->text.char_size);
|
|
Packit |
b099d7 |
start_is_mb = (num_bytes < 2 ? False : True);
|
|
Packit |
b099d7 |
while (position >= 0 && position <= data->length) {
|
|
Packit |
b099d7 |
num_bytes = _XmTextCharactersToBytes(mb_char,
|
|
Packit |
b099d7 |
Look(data, position, dir),
|
|
Packit |
b099d7 |
1, (int)tw->text.char_size);
|
|
Packit |
b099d7 |
cur_is_mb = (num_bytes < 2 ? False : True);
|
|
Packit |
b099d7 |
if (!cur_is_mb && mb_char &&
|
|
Packit |
b099d7 |
isspace((unsigned char)*mb_char)) {
|
|
Packit |
b099d7 |
if (whiteSpace < 0) whiteSpace = position;
|
|
Packit |
b099d7 |
} else if ((sType == XmSELECT_WORD) &&
|
|
Packit |
b099d7 |
(start_is_mb ^ cur_is_mb)) {
|
|
Packit |
b099d7 |
if (whiteSpace < 0) whiteSpace = position;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
} else if (whiteSpace >= 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
position += ddir;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (!include) {
|
|
Packit |
b099d7 |
if(whiteSpace < 0 && dir == XmsdRight)
|
|
Packit |
b099d7 |
whiteSpace = data->length;
|
|
Packit |
b099d7 |
position = whiteSpace;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case XmSELECT_LINE:
|
|
Packit |
b099d7 |
for (i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
while (position >= 0 && position <= data->length) {
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
if ((int)tw->text.char_size == 1) {
|
|
Packit |
b099d7 |
c = Look(data, position, dir);
|
|
Packit |
b099d7 |
if ((c == '\0') || (*c == *data->PSWC_NWLN))
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else if ((int)tw->text.char_size == 2) {
|
|
Packit |
b099d7 |
bits16_ptr = (BITS16 *) Look(data, position, dir);
|
|
Packit |
b099d7 |
if ((bits16_ptr == NULL) ||
|
|
Packit |
b099d7 |
(*bits16_ptr == *(BITS16 *)data->PSWC_NWLN))
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
else { /* MB_CUR_MAX == 3 or 4 or more */
|
|
Packit |
b099d7 |
wchar_t_ptr = (wchar_t *) Look(data, position, dir);
|
|
Packit |
b099d7 |
if ((wchar_t_ptr == NULL) ||
|
|
Packit |
b099d7 |
(*wchar_t_ptr == *(wchar_t *)data->PSWC_NWLN))
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if(((dir == XmsdRight) && (position == data->length)) ||
|
|
Packit |
b099d7 |
((dir == XmsdLeft) && (position == 0)))
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (i + 1 != count)
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (include) {
|
|
Packit |
b099d7 |
/* later!!!check for last char in file # eol */
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case XmSELECT_PARAGRAPH:
|
|
Packit |
b099d7 |
/* Muliple paragraph scanning is not guarenteed to work. */
|
|
Packit |
b099d7 |
for (i = 0; i < count; i++) {
|
|
Packit |
b099d7 |
XmTextPosition start_position = position;
|
|
Packit |
b099d7 |
XmTextPosition last_char = position;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* if scanning forward, check for between paragraphs condition */
|
|
Packit |
b099d7 |
if (dir == XmsdRight) {
|
|
Packit |
b099d7 |
/* DELTA: Look now returns a pointer */
|
|
Packit |
b099d7 |
c = Look(data, position, dir);
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char,
|
|
Packit |
b099d7 |
Look(data, position, dir),
|
|
Packit |
b099d7 |
1, (int)tw->text.char_size);
|
|
Packit |
b099d7 |
/* if is space, go back to first non-space */
|
|
Packit |
b099d7 |
while (mb_char && isspace((unsigned char)*mb_char)) {
|
|
Packit |
b099d7 |
if (position > 0)
|
|
Packit |
b099d7 |
position--;
|
|
Packit |
b099d7 |
else if (position == 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
(void) _XmTextCharactersToBytes(mb_char,
|
|
Packit |
b099d7 |
Look(data, position, dir),
|
|
Packit |
b099d7 |
1, (int)tw->text.char_size);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
temp = position;
|
|
Packit |
b099d7 |
ScanParagraph(data, &temp, dir, ddir, &last_char);
|
|
Packit |
b099d7 |
position = temp;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* If we are at the beginning of the paragraph and we are
|
|
Packit |
b099d7 |
* scanning left, we need to rescan to find the character
|
|
Packit |
b099d7 |
* at the beginning of the next paragraph.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
if (dir == XmsdLeft) {
|
|
Packit |
b099d7 |
/* If we started at the beginning of the paragraph, rescan */
|
|
Packit |
b099d7 |
if (last_char == start_position) {
|
|
Packit |
b099d7 |
temp = position;
|
|
Packit |
b099d7 |
ScanParagraph(data, &temp, dir, ddir, &last_char);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
/*
|
|
Packit |
b099d7 |
* Set position to the last non-space
|
|
Packit |
b099d7 |
* character that was scanned.
|
|
Packit |
b099d7 |
*/
|
|
Packit |
b099d7 |
position = last_char;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (i + 1 != count)
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (include) {
|
|
Packit |
b099d7 |
Increment(data, position, dir);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case XmSELECT_ALL:
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
if (dir == XmsdLeft)
|
|
Packit |
b099d7 |
position = 0;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
position = data->length;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (position < 0) position = 0;
|
|
Packit |
b099d7 |
if (position > data->length) position = data->length;
|
|
Packit |
b099d7 |
return(position);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static Boolean
|
|
Packit |
b099d7 |
GetSelection(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition *left,
|
|
Packit |
b099d7 |
XmTextPosition *right)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->hasselection && data->left < data->right && data->left >= 0) {
|
|
Packit |
b099d7 |
*left = data->left;
|
|
Packit |
b099d7 |
*right = data->right;
|
|
Packit |
b099d7 |
return True;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
*left = *right = 0;
|
|
Packit |
b099d7 |
data->hasselection = False;
|
|
Packit |
b099d7 |
data->take_selection = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
return False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
static void
|
|
Packit |
b099d7 |
SetSelection(XmTextSource source,
|
|
Packit |
b099d7 |
XmTextPosition left,
|
|
Packit |
b099d7 |
XmTextPosition right, /* if right == -999, then we're in
|
|
Packit |
b099d7 |
LoseSelection, so don't call
|
|
Packit |
b099d7 |
XtDisownSelection.*/
|
|
Packit |
b099d7 |
Time set_time)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw;
|
|
Packit |
b099d7 |
int i;
|
|
Packit |
b099d7 |
int oldleft, oldright;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!XtIsRealized((Widget)data->widgets[0]) ||
|
|
Packit |
b099d7 |
(left > right && !data->hasselection)) return;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (left < 0) left = right = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
tw = (XmTextWidget)(data->widgets[i]);
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position,
|
|
Packit |
b099d7 |
off);
|
|
Packit |
b099d7 |
_XmTextDisableRedisplay(data->widgets[i], FALSE);
|
|
Packit |
b099d7 |
if (data->hasselection)
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget)data->widgets[i], data->left,
|
|
Packit |
b099d7 |
data->right, XmHIGHLIGHT_NORMAL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->widgets[i]->text.output->data->refresh_ibeam_off = True;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
oldleft = data->left;
|
|
Packit |
b099d7 |
oldright = data->right;
|
|
Packit |
b099d7 |
data->left = left;
|
|
Packit |
b099d7 |
data->right = right;
|
|
Packit |
b099d7 |
if (data->numwidgets > 0) {
|
|
Packit |
b099d7 |
Widget widget = (Widget) data->widgets[0];
|
|
Packit |
b099d7 |
tw = (XmTextWidget)widget;
|
|
Packit |
b099d7 |
if (!set_time) set_time = _XmValidTimestamp(widget);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (left <= right) {
|
|
Packit |
b099d7 |
if (data->take_selection || (oldleft == oldright && left != right)) {
|
|
Packit |
b099d7 |
if (!XmePrimarySource(widget, set_time)) {
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, 1, 0, set_time);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->prim_time = set_time;
|
|
Packit |
b099d7 |
data->hasselection = True;
|
|
Packit |
b099d7 |
data->take_selection = False;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cb.reason = XmCR_GAIN_PRIMARY;
|
|
Packit |
b099d7 |
cb.event = NULL;
|
|
Packit |
b099d7 |
XtCallCallbackList ((Widget) data->widgets[0],
|
|
Packit |
b099d7 |
data->widgets[0]->text.gain_primary_callback,
|
|
Packit |
b099d7 |
(XtPointer) &cb;;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (data->hasselection && data->left < data->right) {
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget) data->widgets[i], data->left,
|
|
Packit |
b099d7 |
data->right, XmHIGHLIGHT_SELECTED);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
if (left == right) tw->text.add_mode = False;
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (right != -999)
|
|
Packit |
b099d7 |
XtDisownSelection(widget, XA_PRIMARY, set_time);
|
|
Packit |
b099d7 |
data->hasselection = False;
|
|
Packit |
b099d7 |
data->take_selection = True;
|
|
Packit |
b099d7 |
tw->text.add_mode = False;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
for (i=0; i<data->numwidgets; i++) {
|
|
Packit |
b099d7 |
tw = (XmTextWidget)(data->widgets[i]);
|
|
Packit |
b099d7 |
_XmTextEnableRedisplay(data->widgets[i]);
|
|
Packit |
b099d7 |
(*tw->text.output->DrawInsertionPoint)(tw, tw->text.cursor_position,
|
|
Packit |
b099d7 |
on);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* Public routines. */
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmTextValueChanged(XmTextWidget initiator,
|
|
Packit |
b099d7 |
XEvent *event)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmAnyCallbackStruct cb;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
cb.reason = XmCR_VALUE_CHANGED;
|
|
Packit |
b099d7 |
cb.event = event;
|
|
Packit |
b099d7 |
if (initiator->text.value_changed_callback)
|
|
Packit |
b099d7 |
XtCallCallbackList((Widget)initiator,
|
|
Packit |
b099d7 |
initiator->text.value_changed_callback, (XtPointer)&cb;;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
XmTextSource
|
|
Packit |
b099d7 |
_XmStringSourceCreate(char *value,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int is_wchar)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean is_wchar)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextSource source;
|
|
Packit |
b099d7 |
XmSourceData data;
|
|
Packit |
b099d7 |
int num_chars;
|
|
Packit |
b099d7 |
char newline = '\n';
|
|
Packit |
b099d7 |
wchar_t *wc_value;
|
|
Packit |
b099d7 |
char * tmp_value;
|
|
Packit |
b099d7 |
int char_size, max_char_size;
|
|
Packit |
b099d7 |
int ret_value = 0;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
source = (XmTextSource) XtMalloc((unsigned) sizeof(XmTextSourceRec));
|
|
Packit |
b099d7 |
data = source->data = (XmSourceData)
|
|
Packit |
b099d7 |
XtMalloc((unsigned) sizeof(XmSourceDataRec));
|
|
Packit |
b099d7 |
source->AddWidget = AddWidget;
|
|
Packit |
b099d7 |
source->CountLines = CountLines;
|
|
Packit |
b099d7 |
source->RemoveWidget = RemoveWidget;
|
|
Packit |
b099d7 |
source->ReadSource = ReadSource;
|
|
Packit |
b099d7 |
source->Replace = (ReplaceProc) Replace;
|
|
Packit |
b099d7 |
source->Scan = Scan;
|
|
Packit |
b099d7 |
source->GetSelection = GetSelection;
|
|
Packit |
b099d7 |
source->SetSelection = SetSelection;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->source = source;
|
|
Packit |
b099d7 |
switch (MB_CUR_MAX) {
|
|
Packit |
b099d7 |
case 1: case 2:
|
|
Packit |
b099d7 |
max_char_size = char_size = MB_CUR_MAX;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
case 0:
|
|
Packit |
b099d7 |
max_char_size = char_size = 1;
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
default:
|
|
Packit |
b099d7 |
max_char_size = MB_CUR_MAX;
|
|
Packit |
b099d7 |
char_size = sizeof(wchar_t);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (is_wchar) {
|
|
Packit |
b099d7 |
for (num_chars = 0, wc_value = (wchar_t*)value;
|
|
Packit |
b099d7 |
wc_value[num_chars] != 0L;
|
|
Packit |
b099d7 |
num_chars++)
|
|
Packit |
b099d7 |
/*EMPTY*/;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->maxlength = TEXT_INITIAL_INCREM;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while ((num_chars + 1) >= data->maxlength) {
|
|
Packit |
b099d7 |
if (data->maxlength < TEXT_INCREMENT)
|
|
Packit |
b099d7 |
data->maxlength *= 2;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
data->maxlength += TEXT_INCREMENT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->old_length = 0;
|
|
Packit |
b099d7 |
data->ptr = XtMalloc((unsigned)((data->maxlength) * char_size));
|
|
Packit |
b099d7 |
tmp_value = XtMalloc((unsigned)((num_chars + 1) * max_char_size));
|
|
Packit |
b099d7 |
ret_value = wcstombs(tmp_value, wc_value, (num_chars + 1) * max_char_size);
|
|
Packit |
b099d7 |
data->value = NULL; /* Scratch area for block->ptr conversions */
|
|
Packit |
b099d7 |
/* Doesnt include NULL */
|
|
Packit |
b099d7 |
if (ret_value < 0)
|
|
Packit |
b099d7 |
data->length = 0;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
data->length = _XmTextBytesToCharacters(data->ptr, tmp_value, num_chars,
|
|
Packit |
b099d7 |
False, max_char_size);
|
|
Packit |
b099d7 |
XtFree(tmp_value);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
if (value)
|
|
Packit |
b099d7 |
num_chars = _XmTextCountCharacters(value, strlen(value));
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
num_chars = 0;
|
|
Packit |
b099d7 |
data->maxlength = TEXT_INITIAL_INCREM;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while ((num_chars + 1) >= data->maxlength) {
|
|
Packit |
b099d7 |
if (data->maxlength < TEXT_INCREMENT)
|
|
Packit |
b099d7 |
data->maxlength *= 2;
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
data->maxlength += TEXT_INCREMENT;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->old_length = 0;
|
|
Packit |
b099d7 |
data->ptr = XtMalloc((unsigned)((data->maxlength) * char_size));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->value = NULL; /* Scratch area for block->ptr conversions */
|
|
Packit |
b099d7 |
data->length = _XmTextBytesToCharacters(data->ptr, value, num_chars,
|
|
Packit |
b099d7 |
False, max_char_size);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->PSWC_NWLN = (char *) XtMalloc(char_size);
|
|
Packit |
b099d7 |
_XmTextBytesToCharacters(data->PSWC_NWLN, &newline, 1, False,
|
|
Packit |
b099d7 |
max_char_size);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->numwidgets = 0;
|
|
Packit |
b099d7 |
data->widgets = (XmTextWidget *) XtMalloc((unsigned) sizeof(XmTextWidget));
|
|
Packit |
b099d7 |
data->hasselection = False;
|
|
Packit |
b099d7 |
data->take_selection = True;
|
|
Packit |
b099d7 |
data->left = data->right = 0;
|
|
Packit |
b099d7 |
data->editable = True;
|
|
Packit |
b099d7 |
data->maxallowed = INT_MAX;
|
|
Packit |
b099d7 |
data->gap_start = data->ptr + (data->length * char_size);
|
|
Packit |
b099d7 |
data->gap_end = data->ptr + ((data->maxlength - 1) * char_size);
|
|
Packit |
b099d7 |
data->prim_time = 0;
|
|
Packit |
b099d7 |
return source;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceDestroy(XmTextSource source)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XtFree((char *) source->data->ptr);
|
|
Packit |
b099d7 |
XtFree((char *) source->data->value);
|
|
Packit |
b099d7 |
XtFree((char *) source->data->widgets);
|
|
Packit |
b099d7 |
XtFree((char *) source->data->PSWC_NWLN);
|
|
Packit |
b099d7 |
XtFree((char *) source->data);
|
|
Packit |
b099d7 |
XtFree((char *) source);
|
|
Packit |
b099d7 |
source = NULL;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
char *
|
|
Packit |
b099d7 |
_XmStringSourceGetValue(XmTextSource source,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int want_wchar)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean want_wchar)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
XmTextWidget tw = (XmTextWidget) data->widgets[0];
|
|
Packit |
b099d7 |
XmTextBlockRec block;
|
|
Packit |
b099d7 |
int length = 0;
|
|
Packit |
b099d7 |
XmTextPosition pos = 0;
|
|
Packit |
b099d7 |
XmTextPosition ret_pos = 0;
|
|
Packit |
b099d7 |
XmTextPosition last_pos = 0;
|
|
Packit |
b099d7 |
char * temp;
|
|
Packit |
b099d7 |
wchar_t * wc_temp;
|
|
Packit |
b099d7 |
int return_val;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (!want_wchar) {
|
|
Packit |
b099d7 |
if (data->length > 0)
|
|
Packit |
b099d7 |
temp = (char *) XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(data->length + 1) * (int)tw->text.char_size);
|
|
Packit |
b099d7 |
else
|
|
Packit |
b099d7 |
return(XtNewString(""));
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
last_pos = (XmTextPosition) data->length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (pos < last_pos) {
|
|
Packit |
b099d7 |
ret_pos = ReadSource(source, pos, last_pos, &block);
|
|
Packit |
b099d7 |
if (block.length == 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(void)memcpy((void*)&temp[length], (void*)block.ptr, block.length);
|
|
Packit |
b099d7 |
length += block.length;
|
|
Packit |
b099d7 |
pos = ret_pos;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
temp[length] = '\0';
|
|
Packit |
b099d7 |
return (temp);
|
|
Packit |
b099d7 |
} else {
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (data->length > 0)
|
|
Packit |
b099d7 |
wc_temp = (wchar_t*)XtMalloc((unsigned)
|
|
Packit |
b099d7 |
(data->length+1) * sizeof(wchar_t));
|
|
Packit |
b099d7 |
else {
|
|
Packit |
b099d7 |
wc_temp = (wchar_t*)XtMalloc((unsigned) sizeof(wchar_t));
|
|
Packit |
b099d7 |
wc_temp[0] = (wchar_t)0L;
|
|
Packit |
b099d7 |
return (char*) wc_temp;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
last_pos = (XmTextPosition) data->length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
while (pos < last_pos) {
|
|
Packit |
b099d7 |
ret_pos = ReadSource(source, pos, last_pos, &block);
|
|
Packit |
b099d7 |
if (block.length == 0)
|
|
Packit |
b099d7 |
break;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
/* NOTE: ret_pos - pos could result in a truncated long. */
|
|
Packit |
b099d7 |
return_val = mbstowcs(&wc_temp[length], block.ptr, (int)(ret_pos - pos));
|
|
Packit |
b099d7 |
if (return_val > 0) length += return_val;
|
|
Packit |
b099d7 |
pos = ret_pos;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
wc_temp[length] = (wchar_t)0L;
|
|
Packit |
b099d7 |
return ((char*)wc_temp);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceSetValue(XmTextWidget tw,
|
|
Packit |
b099d7 |
char *value)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
XmTextSource source = tw->text.source;
|
|
Packit |
b099d7 |
XmSourceData data = source->data;
|
|
Packit |
b099d7 |
Boolean editable, freeBlock;
|
|
Packit |
b099d7 |
int maxallowed;
|
|
Packit |
b099d7 |
XmTextBlockRec block, newblock;
|
|
Packit |
b099d7 |
XmTextPosition fromPos = 0;
|
|
Packit |
b099d7 |
XmTextPosition toPos = data->length;
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
(*source->SetSelection)(source, 1, 0,
|
|
Packit |
b099d7 |
XtLastTimestampProcessed(XtDisplay(tw)));
|
|
Packit |
b099d7 |
block.format = XmFMT_8_BIT;
|
|
Packit |
b099d7 |
block.length = strlen(value);
|
|
Packit |
b099d7 |
block.ptr = value;
|
|
Packit |
b099d7 |
editable = data->editable;
|
|
Packit |
b099d7 |
maxallowed = data->maxallowed;
|
|
Packit |
b099d7 |
data->editable = TRUE;
|
|
Packit |
b099d7 |
data->maxallowed = INT_MAX;
|
|
Packit |
b099d7 |
_XmTextSetHighlight((Widget)tw, 0, tw->text.last_position,
|
|
Packit |
b099d7 |
XmHIGHLIGHT_NORMAL);
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
if (_XmTextModifyVerify(tw, NULL, &fromPos, &toPos,
|
|
Packit |
b099d7 |
NULL, &block, &newblock, &freeBlock)) {
|
|
Packit |
b099d7 |
(void)(source->Replace)(tw, NULL, &fromPos, &toPos, &newblock, False);
|
|
Packit |
b099d7 |
if (freeBlock && newblock.ptr) XtFree(newblock.ptr);
|
|
Packit |
b099d7 |
_XmTextValueChanged(tw, NULL);
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
data->editable = editable;
|
|
Packit |
b099d7 |
data->maxallowed = maxallowed;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmStringSourceHasSelection(XmTextSource source)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
return source->data->hasselection;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
Boolean
|
|
Packit |
b099d7 |
_XmStringSourceGetEditable(XmTextSource source)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
return source->data->editable;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceSetEditable(XmTextSource source,
|
|
Packit |
b099d7 |
#if NeedWidePrototypes
|
|
Packit |
b099d7 |
int editable)
|
|
Packit |
b099d7 |
#else
|
|
Packit |
b099d7 |
Boolean editable)
|
|
Packit |
b099d7 |
#endif /* NeedWidePrototypes */
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
source->data->editable = editable;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
int
|
|
Packit |
b099d7 |
_XmStringSourceGetMaxLength(XmTextSource source)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
return source->data->maxallowed;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
void
|
|
Packit |
b099d7 |
_XmStringSourceSetMaxLength(XmTextSource source,
|
|
Packit |
b099d7 |
int max)
|
|
Packit |
b099d7 |
{
|
|
Packit |
b099d7 |
source->data->maxallowed = max;
|
|
Packit |
b099d7 |
}
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|
|
Packit |
b099d7 |
|