2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 #ifdef VERBOSE_REV_INFO
25 static char rcs_id[] = "$TOG: TermPrimPendingText.c /main/3 1997/07/03 15:40:05 samborn $";
26 #endif /* VERBOSE_REV_INFO */
30 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
31 * (c) Copyright 1993, 1994 International Business Machines Corp. *
32 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
33 * (c) Copyright 1993, 1994 Novell, Inc. *
37 #include <X11/Intrinsic.h>
38 #include "TermHeader.h"
39 #include "TermPrimDebug.h"
40 #include "TermPrimPendingTextP.h"
58 PendingTextChunk chunk;
60 fprintf(stderr, "head: %lx\n", list->head);
61 fprintf(stderr, "tail: %lx\n", list->tail);
63 for (chunk = list->head; chunk != list->tail; chunk = chunk->next)
65 fprintf(stderr, "chunk: 0x%lx\n", chunk);
66 fprintf(stderr, " buffer : %c\n", chunk->buffer[0]);
67 fprintf(stderr, " buffLen: %d\n", chunk->buffLen);
68 fprintf(stderr, " bufPtr : %c\n", chunk->bufPtr[0]);
69 fprintf(stderr, " len : %d\n", chunk->len);
70 fprintf(stderr, " next : 0x%lx\n", chunk->next);
71 fprintf(stderr, " prev : 0x%lx\n", chunk->prev);
77 ** Allocate, and initialize a new PendingTextChunk.
83 PendingTextChunk newChunk;
85 Debug('q', fprintf(stderr, ">>mallocChunk() starting\n"));
87 newChunk = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
90 return((PendingTextChunk) NULL);
93 newChunk->buffLen = len;
94 newChunk->buffer = (unsigned char *) XtMalloc(newChunk->buffLen);
95 if (!newChunk->buffer)
97 XtFree((char *) newChunk);
98 return((PendingTextChunk) NULL);
102 ** Finish initializing the new chunk.
104 newChunk->bufPtr = newChunk->buffer;
106 newChunk->next = (PendingTextChunk)NULL;
107 newChunk->prev = (PendingTextChunk)NULL;
112 ** Add a new pending text chunk to the end of the list. If possible, reuse
113 ** an existing chunk, else allocate a new one. Return true if successful,
114 ** else return false.
117 _DtTermPrimPendingTextAppendChunk
123 PendingTextChunk newChunk;
125 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppendChunk() starting\n"));
127 walkPendingText(list);
129 #ifdef RECYCLE_CHUNKS
133 ** There are chunks on the free list, this will
136 newChunk = list->free;
141 ** We have no free chunks.
143 newChunk = mallocChunk(len);
147 return(PendingTextChunk(NULL));
151 ** append the new chunk to the list...
153 list->free = list->free->next;
154 newChunk->next = (PendingTextChunk)NULL;
155 list->tail->next = newChunk;
156 list->tail = newChunk;
158 #else /* RECYCLE_CHUNKS */
160 ** Create a new chunk.
162 newChunk = mallocChunk(len);
166 return((PendingTextChunk)NULL);
168 newChunk->next = list->tail;
169 newChunk->prev = list->tail->prev;
170 list->tail->prev->next = newChunk;
171 list->tail->prev = newChunk;
173 #endif /* RECYCLE_CHUNKS */
177 _DtTermPrimPendingTextReplace
179 PendingTextChunk chunk,
180 unsigned char *buffer,
185 chunk->buffer = (unsigned char *) XtRealloc((char *) chunk->buffer,
187 chunk->buffLen = bufferLen;
188 chunk->bufPtr = chunk->buffer;
189 chunk->len = bufferLen;
190 (void) memmove(chunk->buffer, buffer, bufferLen);
194 ** Remove a pending text chunk from the head of the list, and add it to
198 _DtTermPrimPendingTextRemoveChunk
201 PendingTextChunk chunk
204 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextRemoveChunk() starting\n"));
206 walkPendingText(list);
209 ** add the chunk to the free list...
211 /* don't allow removal of either head or tail... */
212 if ((chunk == list->head) || (chunk == list->tail)) {
216 chunk->prev->next = chunk->next;
217 chunk->next->prev = chunk->prev;
218 #ifdef RECYCLE_CHUNKS
220 chunk->next = list->free;
222 #else /* RECYCLE_CHUNKS */
223 XtFree((char *) chunk->buffer);
224 XtFree((char *) chunk);
225 #endif /* RECYCLE_CHUNKS */
228 /* Check to see if there is any pending text in the pending text list...
231 _DtTermPrimPendingTextIsPending
236 if (list->head->next != list->tail) {
243 ** Get a pending text chunk from the head of the list.
246 _DtTermPrimPendingTextGetChunk
251 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextGetChunk() starting\n"));
253 walkPendingText(list);
256 if (list->head->next != list->tail) {
257 return(list->head->next);
259 return((PendingTextChunk) 0);
264 ** Flush a pending text list. This function takes the easy way out of
265 ** calling _DtTermPrimPendingTextGetChunk() to get each chunk and
266 ** _DtTermPrimPendingTextRemoveChunk() to remove them.
269 _DtTermPrimPendingTextFlush
274 PendingTextChunk chunk;
276 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextFlush() starting\n"));
278 walkPendingText(list);
281 while ((chunk = _DtTermPrimPendingTextGetChunk(list))) {
282 (void) _DtTermPrimPendingTextRemoveChunk(list, chunk);
287 ** Append the supplied text to the pending text list. Return True if
288 ** all text was appended, else return False.
291 _DtTermPrimPendingTextAppend
298 PendingTextChunk newChunk;
299 PendingTextChunk oldTail;
301 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppend() starting\n"));
303 walkPendingText(list);
306 ** remember this if we are unable to get all the text
309 oldTail = list->tail->prev;
312 ** add a new chunk to the list
316 newChunk = _DtTermPrimPendingTextAppendChunk(list,
317 (len > DEFAULT_CHUNK_BUF_SIZE) ? DEFAULT_CHUNK_BUF_SIZE : len);
321 ** the allocation failed, free up all newly created
322 ** chunks and return...
324 while (oldTail != list->tail->prev)
326 _DtTermPrimPendingTextRemoveChunk(list, list->tail->prev);
331 ** chunk buffers are a fixed size, copy a much as possible
332 ** from 'text' to the chunk buffer, then adjust 'len'...
334 newChunk->len = MIN(len, newChunk->buffLen);
335 (void)memcpy(newChunk->buffer, text, newChunk->len);
336 len -= newChunk->buffLen;
342 ** Write a pending text chunk from the head of the list.
345 _DtTermPrimPendingTextWrite
351 int bytesWritten = 0;
352 PendingTextChunk chunk;
354 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextWrite() starting\n"));
356 walkPendingText(list);
358 chunk = list->head->next;
359 Debug('q', fprintf(stderr, ">> len: %3.3d\n", chunk->len));
360 Debug('q', fprintf(stderr, ">> bufPtr: <%*.*s>\n",
361 chunk->len, chunk->len, chunk->bufPtr));
363 bytesWritten = write(fd, chunk->bufPtr, chunk->len <= MAX_PTY_WRITE ?
364 chunk->len : MAX_PTY_WRITE);
366 if (bytesWritten < 0) {
369 fprintf(stderr, "_DtTermPrimPendingTextWrite: write failed\n");
374 if ((chunk->len -= bytesWritten) <= 0) {
376 ** All text in this chunk has been written,
377 ** remove it from the list.
379 _DtTermPrimPendingTextRemoveChunk(list, chunk);
383 ** only some of the text in this chunk was written,
384 ** simply adjust the write pointer...
385 ** (list->head->len was adjusted above)
387 chunk->bufPtr += bytesWritten;
393 _DtTermPrimPendingTextCreate(
399 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextCreate() starting\n"));
401 ptr = (PendingText) XtMalloc(sizeof(PendingTextRec));
402 (void) memset(ptr, '\0', sizeof(PendingTextRec));
403 ptr->head = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
404 (void) memset(ptr->head, '\0', sizeof(PendingTextChunkRec));
405 ptr->tail = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
406 (void) memset(ptr->tail, '\0', sizeof(PendingTextChunkRec));
408 ptr->head->next = ptr->tail;
409 ptr->tail->prev = ptr->head;
412 walkPendingText(ptr);
418 _DtTermPrimPendingTextDestroy(
422 PendingTextChunk chunk;
424 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextDestroy() starting\n"));
427 walkPendingText(ptr);
432 ptr->head = ptr->head->next;
434 (void) XtFree((char *) chunk->buffer);
436 (void) XtFree((char *) chunk);
438 (void) XtFree((char *) ptr);