Exemplo n.º 1
0
Arquivo: cbuf.c Projeto: danscu/lk
size_t cbuf_read_char(cbuf_t *cbuf, char *c, bool block)
{
	DEBUG_ASSERT(cbuf);
	DEBUG_ASSERT(c);

	enter_critical_section();

	if (block)
		event_wait(&cbuf->event);

	// see if there's data available
	size_t ret = 0;
	if (cbuf->tail != cbuf->head) {

		*c = cbuf->buf[cbuf->tail];
		cbuf->tail = INC_POINTER(cbuf, cbuf->tail, 1);

		if (cbuf->tail == cbuf->head) {
			// we've emptied the buffer, unsignal the event
			event_unsignal(&cbuf->event);
		}

		ret = 1;
	}

	exit_critical_section();

	return ret;
}
Exemplo n.º 2
0
Arquivo: cbuf.c Projeto: dankex/lk
size_t cbuf_read(cbuf_t *cbuf, void *_buf, size_t buflen, bool block)
{
	size_t ret;
	char *buf = (char *)_buf;

	DEBUG_ASSERT(cbuf);
	DEBUG_ASSERT(_buf);

	enter_critical_section();

	if (block)
		event_wait(&cbuf->event);

	// see if there's data available
	if (cbuf->tail != cbuf->head) {
		size_t pos = 0;

		// loop until we've read everything we need
		// at most this will make two passes to deal with wraparound
		while (pos < buflen && cbuf->tail != cbuf->head) {
			size_t read_len;
			if (cbuf->head > cbuf->tail) {
				// simple case where there is no wraparound
				read_len = MIN(cbuf->head - cbuf->tail, buflen - pos);
			} else {
				// read to the end of buffer in this pass
				read_len = MIN(valpow2(cbuf->len_pow2) - cbuf->tail, buflen - pos);
			}

			memcpy(buf + pos, cbuf->buf + cbuf->tail, read_len);

			cbuf->tail = INC_POINTER(cbuf, cbuf->tail, read_len);
			pos += read_len;
		}

		if (cbuf->tail == cbuf->head) {
			// we've emptied the buffer, unsignal the event
			event_unsignal(&cbuf->event);
		}

		ret = pos;
	} else {
		DEBUG_ASSERT(!block);
		ret = 0;
	}

	exit_critical_section();

	return ret;
}
Exemplo n.º 3
0
Arquivo: cbuf.c Projeto: danscu/lk
size_t cbuf_write_char(cbuf_t *cbuf, char c, bool canreschedule)
{
	DEBUG_ASSERT(cbuf);

	enter_critical_section();

	size_t ret = 0;
	if (cbuf_space_avail(cbuf) > 0) {
		cbuf->buf[cbuf->head] = c;

		cbuf->head = INC_POINTER(cbuf, cbuf->head, 1);
		ret = 1;

		if (cbuf->head != cbuf->tail)
			event_signal(&cbuf->event, canreschedule);
	}

	exit_critical_section();

	return ret;
}
Exemplo n.º 4
0
Arquivo: cbuf.c Projeto: danscu/lk
size_t cbuf_write(cbuf_t *cbuf, const void *_buf, size_t len, bool canreschedule)
{
	const char *buf = (const char *)_buf;

	LTRACEF("len %zd\n", len);

	DEBUG_ASSERT(cbuf);
	DEBUG_ASSERT(_buf);
	DEBUG_ASSERT(len < valpow2(cbuf->len_pow2));

	enter_critical_section();

	size_t write_len;
	size_t pos = 0;

	while (pos < len && cbuf_space_avail(cbuf) > 0) {
		if (cbuf->head >= cbuf->tail) {
			write_len = MIN(valpow2(cbuf->len_pow2) - cbuf->head, len - pos);
		} else {
			write_len = MIN(cbuf->tail - cbuf->head - 1, len - pos);
		}

		// if it's full, abort and return how much we've written
		if (write_len == 0) {
			break;
		}

		memcpy(cbuf->buf + cbuf->head, buf + pos, write_len);

		cbuf->head = INC_POINTER(cbuf, cbuf->head, write_len);
		pos += write_len;
	}

	if (cbuf->head != cbuf->tail)
		event_signal(&cbuf->event, canreschedule);

	exit_critical_section();

	return pos;
}
Exemplo n.º 5
0
wchar_t
inkey(int to, int delay)
{
	wchar_t		 k;
	int              c, mapping;
	keymap_t	*current = _cursesi_screen->base_keymap;
	FILE            *infd = _cursesi_screen->infd;

	k = 0;		/* XXX gcc -Wuninitialized */

#ifdef DEBUG
	__CTRACE(__CTRACE_INPUT, "inkey (%d, %d)\n", to, delay);
#endif
	for (;;) {		/* loop until we get a complete key sequence */
reread:
		if (state == INKEY_NORM) {
			if (delay && __timeout(delay) == ERR)
				return ERR;
			c = fgetc(infd);
			if (c == EOF) {
				clearerr(infd);
				return ERR;
			}

			if (delay && (__notimeout() == ERR))
				return ERR;

			k = (wchar_t) c;
#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
			    "inkey (state normal) got '%s'\n", unctrl(k));
#endif

			working = start;
			inbuf[working] = k;
			INC_POINTER(working);
			end = working;
			state = INKEY_ASSEMBLING;	/* go to the assembling
							 * state now */
		} else if (state == INKEY_BACKOUT) {
			k = inbuf[working];
			INC_POINTER(working);
			if (working == end) {	/* see if we have run
						 * out of keys in the
						 * backlog */

				/* if we have then switch to assembling */
				state = INKEY_ASSEMBLING;
			}
		} else if (state == INKEY_ASSEMBLING) {
			/* assembling a key sequence */
			if (delay) {
				if (__timeout(to ? (ESCDELAY / 100) : delay)
				    == ERR)
					return ERR;
			} else {
				if (to && (__timeout(ESCDELAY / 100) == ERR))
					return ERR;
			}

			c = fgetc(infd);
			if (ferror(infd)) {
				clearerr(infd);
				return ERR;
			}

			if ((to || delay) && (__notimeout() == ERR))
					return ERR;

#ifdef DEBUG
			__CTRACE(__CTRACE_INPUT,
			    "inkey (state assembling) got '%s'\n", unctrl(k));
#endif
			if (feof(infd) || c == -1) {	/* inter-char timeout,
							 * start backing out */
				clearerr(infd);
				if (start == end)
					/* no chars in the buffer, restart */
					goto reread;

				k = inbuf[start];
				state = INKEY_TIMEOUT;
			} else {
				k = (wchar_t) c;
				inbuf[working] = k;
				INC_POINTER(working);
				end = working;
			}
		} else {
			fprintf(stderr, "Inkey state screwed - exiting!!!");
			exit(2);
		}

		  /*
		   * Check key has no special meaning and we have not
		   * timed out and the key has not been disabled
		   */
		mapping = current->mapping[k];
		if (((state == INKEY_TIMEOUT) || (mapping < 0))
			|| ((current->key[mapping]->type == KEYMAP_LEAF)
			    && (current->key[mapping]->enable == FALSE))) {
			/* return the first key we know about */
			k = inbuf[start];

			INC_POINTER(start);
			working = start;

			if (start == end) {	/* only one char processed */
				state = INKEY_NORM;
			} else {/* otherwise we must have more than one char
				 * to backout */
				state = INKEY_BACKOUT;
			}
			return k;
		} else {	/* must be part of a multikey sequence */
			/* check for completed key sequence */
			if (current->key[current->mapping[k]]->type == KEYMAP_LEAF) {
				start = working;	/* eat the key sequence
							 * in inbuf */

				/* check if inbuf empty now */
				if (start == end) {
					/* if it is go back to normal */
					state = INKEY_NORM;
				} else {
					/* otherwise go to backout state */
					state = INKEY_BACKOUT;
				}

				/* return the symbol */
				return current->key[current->mapping[k]]->value.symbol;

			} else {
				/*
				 * Step on to next part of the multi-key
				 * sequence.
				 */
				current = current->key[current->mapping[k]]->value.next;
			}
		}
	}
}
Exemplo n.º 6
0
/*
 * GetClipboardSavebuf - gets data from the clipboard, and builds a
 *                       temporary savebuf from it
 */
int GetClipboardSavebuf( savebuf *clip )
{
    GLOBALHANDLE        hglob;
    char                _HUGE_ *ptr;
    char                _HUGE_ *cpos;
    fcb_list            fcblist;
    int                 i;
    bool                is_flushed;
    bool                has_lf;
    bool                record_done;
    char                ch;
    int                 used;

    if( !openClipboardForRead() ) {
        return( ERR_CLIPBOARD_EMPTY );
    }
    hglob = GetClipboardData( CF_TEXT );
    if( hglob == NULL ) {
        return( ERR_CLIPBOARD );
    }
    ptr = GetPtrGlobalLock( hglob );
    cpos = ptr;
    i = 0;
    is_flushed = false;
    has_lf = false;
    fcblist.head = NULL;
    fcblist.tail = NULL;
    record_done = false;

    /*
     * add all characters to ReadBuffer.  Each time this fills,
     * create a new FCB
     */
    while( (ch = *ptr) != '\0' ) {
        INC_POINTER( ptr );
        ReadBuffer[i++] = ch;
        if( ch == LF ) {
            has_lf = true;
        }
        if( i >= MAX_IO_BUFFER ) {
            is_flushed = true;
            used = addAnFcb( &fcblist, i );
            ptr = GET_POINTER( cpos, used );
            cpos = ptr;
            i = 0;
        }
    }

    /*
     * after we are done, see if any characters are left unprocessed
     */
    if( i != 0 ) {
        /*
         * check if this is a partial line
         */
        if( !is_flushed && !has_lf ) {
            clip->type = SAVEBUF_LINE;
            ReadBuffer[i] = 0;
            clip->u.data = MemAlloc( i + 1 );
            strcpy( clip->u.data, ReadBuffer );
            record_done = true;
        } else {
            // add LF to end of buffer
            if( i >= MAX_IO_BUFFER - 2 ) {
                addAnFcb( &fcblist, i );
                i = 0;
            }
            ReadBuffer[i++] = CR;
            ReadBuffer[i++] = LF;
            addAnFcb( &fcblist, i );
        }
    } else if( !is_flushed ) {
        clip->type = SAVEBUF_NOP;
        record_done = true;
    }

    if( !record_done ) {
        clip->type = SAVEBUF_FCBS;
        clip->u.fcbs.head = fcblist.head;
        clip->u.fcbs.tail = fcblist.tail;
    }

    GlobalUnlock( hglob );
    CloseClipboard();

    return( ERR_NO_ERR );

} /* GetClipboardSavebuf */
Exemplo n.º 7
0
/*
 * AddFcbsToClipboard - add all lines in a given set of fcbs to the clipboard
 */
int AddFcbsToClipboard( fcb_list *fcblist )
{
    fcb                 *cfcb;
    line                *cline;
    char                _HUGE_ *ptr;
    long                size;
    int                 i;
    GLOBALHANDLE        hglob;
    bool                crlf_left_to_write = false;

    if( !openClipboardForWrite() ) {
        return( ERR_CLIPBOARD );
    }

    /*
     * compute the number of bytes in total
     */
    size = 1;   // for trailing null char
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        size += (long)cfcb->byte_cnt +
                (long)(cfcb->end_line-cfcb->start_line + 1);
        if( cfcb == fcblist->tail ) {
            break;
        }
    }

    /*
     * get the memory to store this stuff
     */
    hglob = GlobalAlloc( GMEM_MOVEABLE, size );
    if( hglob == NULL ) {
        CloseClipboard();
        return( ERR_CLIPBOARD );
    }

    ptr = GetPtrGlobalLock( hglob );
    if( ptr == NULL ) {
        CloseClipboard();
        return( ERR_CLIPBOARD );
    }

    /*
     * copy all lines into this pointer
     */
    for( cfcb = fcblist->head; cfcb != NULL; cfcb = cfcb->next ) {
        FetchFcb( cfcb );
        for( cline = cfcb->lines.head; cline != NULL; cline = cline->next ) {
            // one CR,LF left to write?
            if( crlf_left_to_write ) {
                // yes: write it
                crlf_left_to_write = false;
                *ptr = CR;
                INC_POINTER( ptr );
                *ptr = LF;
                INC_POINTER( ptr );
            }
            for( i = 0; i < cline->len; i++ ) {
                *ptr = cline->data[i];
                INC_POINTER( ptr );
            }
            // remember to write one CR,LF next time
            crlf_left_to_write = true;
        }
        if( cfcb == fcblist->tail ) {
            break;
        }
    }
    // the last CR,LF is omitted
    *ptr = 0;
    GlobalUnlock( hglob );
    SetClipboardData( CF_TEXT, hglob );
    CloseClipboard();
    return( ERR_NO_ERR );

} /* AddFcbsToClipboard */