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 libraries 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"
53 PendingTextChunk chunk;
55 fprintf(stderr, "head: %lx\n", list->head);
56 fprintf(stderr, "tail: %lx\n", list->tail);
58 for (chunk = list->head; chunk != list->tail; chunk = chunk->next)
60 fprintf(stderr, "chunk: 0x%lx\n", chunk);
61 fprintf(stderr, " buffer : %c\n", chunk->buffer[0]);
62 fprintf(stderr, " buffLen: %d\n", chunk->buffLen);
63 fprintf(stderr, " bufPtr : %c\n", chunk->bufPtr[0]);
64 fprintf(stderr, " len : %d\n", chunk->len);
65 fprintf(stderr, " next : 0x%lx\n", chunk->next);
66 fprintf(stderr, " prev : 0x%lx\n", chunk->prev);
72 ** Allocate, and initialize a new PendingTextChunk.
78 PendingTextChunk newChunk;
80 Debug('q', fprintf(stderr, ">>mallocChunk() starting\n"));
82 newChunk = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
85 return((PendingTextChunk) NULL);
88 newChunk->buffLen = len;
89 newChunk->buffer = (unsigned char *) XtMalloc(newChunk->buffLen);
90 if (!newChunk->buffer)
92 XtFree((char *) newChunk);
93 return((PendingTextChunk) NULL);
97 ** Finish initializing the new chunk.
99 newChunk->bufPtr = newChunk->buffer;
101 newChunk->next = (PendingTextChunk)NULL;
102 newChunk->prev = (PendingTextChunk)NULL;
107 ** Add a new pending text chunk to the end of the list. If possible, reuse
108 ** an existing chunk, else allocate a new one. Return true if successful,
109 ** else return false.
112 _DtTermPrimPendingTextAppendChunk
118 PendingTextChunk newChunk;
120 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppendChunk() starting\n"));
122 walkPendingText(list);
124 #ifdef RECYCLE_CHUNKS
128 ** There are chunks on the free list, this will
131 newChunk = list->free;
136 ** We have no free chunks.
138 newChunk = mallocChunk(len);
142 return(PendingTextChunk(NULL));
146 ** append the new chunk to the list...
148 list->free = list->free->next;
149 newChunk->next = (PendingTextChunk)NULL;
150 list->tail->next = newChunk;
151 list->tail = newChunk;
153 #else /* RECYCLE_CHUNKS */
155 ** Create a new chunk.
157 newChunk = mallocChunk(len);
161 return((PendingTextChunk)NULL);
163 newChunk->next = list->tail;
164 newChunk->prev = list->tail->prev;
165 list->tail->prev->next = newChunk;
166 list->tail->prev = newChunk;
168 #endif /* RECYCLE_CHUNKS */
172 _DtTermPrimPendingTextReplace
174 PendingTextChunk chunk,
175 unsigned char *buffer,
180 chunk->buffer = (unsigned char *) XtRealloc((char *) chunk->buffer,
182 chunk->buffLen = bufferLen;
183 chunk->bufPtr = chunk->buffer;
184 chunk->len = bufferLen;
185 (void) memmove(chunk->buffer, buffer, bufferLen);
189 ** Remove a pending text chunk from the head of the list, and add it to
193 _DtTermPrimPendingTextRemoveChunk
196 PendingTextChunk chunk
199 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextRemoveChunk() starting\n"));
201 walkPendingText(list);
204 ** add the chunk to the free list...
206 /* don't allow removal of either head or tail... */
207 if ((chunk == list->head) || (chunk == list->tail)) {
211 chunk->prev->next = chunk->next;
212 chunk->next->prev = chunk->prev;
213 #ifdef RECYCLE_CHUNKS
215 chunk->next = list->free;
217 #else /* RECYCLE_CHUNKS */
218 XtFree((char *) chunk->buffer);
219 XtFree((char *) chunk);
220 #endif /* RECYCLE_CHUNKS */
223 /* Check to see if there is any pending text in the pending text list...
226 _DtTermPrimPendingTextIsPending
231 if (list->head->next != list->tail) {
238 ** Get a pending text chunk from the head of the list.
241 _DtTermPrimPendingTextGetChunk
246 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextGetChunk() starting\n"));
248 walkPendingText(list);
251 if (list->head->next != list->tail) {
252 return(list->head->next);
254 return((PendingTextChunk) 0);
259 ** Flush a pending text list. This function takes the easy way out of
260 ** calling _DtTermPrimPendingTextGetChunk() to get each chunk and
261 ** _DtTermPrimPendingTextRemoveChunk() to remove them.
264 _DtTermPrimPendingTextFlush
269 PendingTextChunk chunk;
271 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextFlush() starting\n"));
273 walkPendingText(list);
276 while ((chunk = _DtTermPrimPendingTextGetChunk(list))) {
277 (void) _DtTermPrimPendingTextRemoveChunk(list, chunk);
282 ** Append the supplied text to the pending text list. Return True if
283 ** all text was appended, else return False.
286 _DtTermPrimPendingTextAppend
293 PendingTextChunk newChunk;
294 PendingTextChunk oldTail;
296 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextAppend() starting\n"));
298 walkPendingText(list);
301 ** remember this if we are unable to get all the text
304 oldTail = list->tail->prev;
307 ** add a new chunk to the list
311 newChunk = _DtTermPrimPendingTextAppendChunk(list,
312 (len > DEFAULT_CHUNK_BUF_SIZE) ? DEFAULT_CHUNK_BUF_SIZE : len);
316 ** the allocation failed, free up all newly created
317 ** chunks and return...
319 while (oldTail != list->tail->prev)
321 _DtTermPrimPendingTextRemoveChunk(list, list->tail->prev);
326 ** chunk buffers are a fixed size, copy a much as possible
327 ** from 'text' to the chunk buffer, then adjust 'len'...
329 newChunk->len = MIN(len, newChunk->buffLen);
330 (void)memcpy(newChunk->buffer, text, newChunk->len);
331 len -= newChunk->buffLen;
337 ** Write a pending text chunk from the head of the list.
340 _DtTermPrimPendingTextWrite
346 int bytesWritten = 0;
347 PendingTextChunk chunk;
349 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextWrite() starting\n"));
351 walkPendingText(list);
353 chunk = list->head->next;
354 Debug('q', fprintf(stderr, ">> len: %3.3d\n", chunk->len));
355 Debug('q', fprintf(stderr, ">> bufPtr: <%*.*s>\n",
356 chunk->len, chunk->len, chunk->bufPtr));
358 bytesWritten = write(fd, chunk->bufPtr, chunk->len <= MAX_PTY_WRITE ?
359 chunk->len : MAX_PTY_WRITE);
361 if (bytesWritten < 0) {
364 fprintf(stderr, "_DtTermPrimPendingTextWrite: write failed\n");
369 if ((chunk->len -= bytesWritten) <= 0) {
371 ** All text in this chunk has been written,
372 ** remove it from the list.
374 _DtTermPrimPendingTextRemoveChunk(list, chunk);
378 ** only some of the text in this chunk was written,
379 ** simply adjust the write pointer...
380 ** (list->head->len was adjusted above)
382 chunk->bufPtr += bytesWritten;
388 _DtTermPrimPendingTextCreate(
394 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextCreate() starting\n"));
396 ptr = (PendingText) XtMalloc(sizeof(PendingTextRec));
397 (void) memset(ptr, '\0', sizeof(PendingTextRec));
398 ptr->head = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
399 (void) memset(ptr->head, '\0', sizeof(PendingTextChunkRec));
400 ptr->tail = (PendingTextChunk) XtMalloc(sizeof(PendingTextChunkRec));
401 (void) memset(ptr->tail, '\0', sizeof(PendingTextChunkRec));
403 ptr->head->next = ptr->tail;
404 ptr->tail->prev = ptr->head;
407 walkPendingText(ptr);
413 _DtTermPrimPendingTextDestroy(
417 PendingTextChunk chunk;
419 Debug('q', fprintf(stderr, ">>_DtTermPrimPendingTextDestroy() starting\n"));
422 walkPendingText(ptr);
427 ptr->head = ptr->head->next;
429 (void) XtFree((char *) chunk->buffer);
431 (void) XtFree((char *) chunk);
433 (void) XtFree((char *) ptr);