#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if defined(lint) && defined(HAVE_NOTE_H)
#include <note.h>
#endif /* lint && HAVE_NOTE_H */

#include <iiimp-data.h>

#include "iiimp-dataP.h"


IIIMP_keyevent_list *
iiimp_keyevent_list_new(
    IIIMP_data_s *	data_s,
    int			count,
    IIIMP_keyevent *	k)
{
    IIIMP_keyevent_list *	data;
    size_t			nbyte;

    data = (IIIMP_keyevent_list *)malloc(sizeof (IIIMP_keyevent_list));
    if (NULL == data) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    nbyte = ((4 + 4 + 4 + 4) * count);

    data->nbyte = nbyte;
    data->count = count;

    nbyte = ((sizeof (IIIMP_keyevent)) * count);

    if (0 == count) {
	data->keyevent = NULL;
    } else {
	data->keyevent = (IIIMP_keyevent *)malloc(nbyte);
	if (NULL == data->keyevent) {
	    free(data);
	    data_s->status = IIIMP_DATA_MALLOC_ERROR;
	    return NULL;
	}

	(void)memcpy(data->keyevent, k, nbyte);
    }

    return data;
}


void
iiimp_keyevent_list_delete(IIIMP_data_s * data_s, IIIMP_keyevent_list * kel)
{
#if defined(lint) && defined(HAVE_NOTE_H)
    NOTE(ARGUNUSED(data_s))
#endif /* lint && HAVE_NOTE_H */
	if (NULL == kel) return;
    free(kel->keyevent);
    free(kel);
}


void
iiimp_keyevent_list_pack(
    IIIMP_data_s *		data_s,
    IIIMP_keyevent_list *	m,
    size_t *			nbyte,
    uchar_t **			ptr)
{
    size_t	rest;
    uchar_t *	p;
    int		i;

    rest = *nbyte;
    p = *ptr;

    for (i = 0; i < m->count; i++) {
	PUT32((m->keyevent + i)->keycode, rest, p, data_s->byte_swap);
	PUT32((m->keyevent + i)->keychar, rest, p, data_s->byte_swap);
	PUT32((m->keyevent + i)->modifier, rest, p, data_s->byte_swap);
	PUT32((m->keyevent + i)->time_stamp, rest, p, data_s->byte_swap);
    }

    *nbyte = rest;
    *ptr = p;

    return;
}


IIIMP_keyevent_list *
iiimp_keyevent_list_unpack(
    IIIMP_data_s *		data_s,
    size_t *			nbyte,
    const uchar_t **		ptr,
    size_t			nbyte_max)
{
    IIIMP_keyevent_list *	l;
    size_t			rest;
    const uchar_t *		p;
    int				count;
    int				i;

    rest = nbyte_max;
    p = *ptr;

    if ((*nbyte < rest)) {
	data_s->status = IIIMP_DATA_INVALID;
	return NULL;
    }

    count = (nbyte_max / KEY_EVENT_OBJECT_SIZE);
    if (nbyte_max != (count * KEY_EVENT_OBJECT_SIZE)) {
	data_s->status = IIIMP_DATA_INVALID;
	return NULL;
    }

    l = (IIIMP_keyevent_list *)malloc(sizeof (IIIMP_keyevent_list));
    if (NULL == l) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    l->count = count;

    if (0 == count) {
	l->keyevent = NULL;
	return l;
    }

    l->keyevent = (IIIMP_keyevent *)malloc((sizeof (IIIMP_keyevent)) * count);
    if (NULL == l->keyevent) {
	free(l);
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    for (i = 0; i < count; i++) {
	GET32((l->keyevent + i)->keycode, rest, p, data_s->byte_swap);
	GET32((l->keyevent + i)->keychar, rest, p, data_s->byte_swap);
	GET32((l->keyevent + i)->modifier, rest, p, data_s->byte_swap);
	GET32((l->keyevent + i)->time_stamp, rest, p, data_s->byte_swap);
    }

    /* This failed for the scenario of having multiple HOTKEYS and each
       having multiple keyevents.
       *nbyte = rest;
       */

    *nbyte -= (nbyte_max - rest);
    *ptr = p;

    return l;
}


void
iiimp_keyevent_print(
    IIIMP_data_s *	data_s,
    IIIMP_keyevent *	m)
{
    if (NULL == m) return;

    (void)fprintf(data_s->print_fp,
		  "\tcode=%02x char=%02x modifier=%02x time_stamp=%x\n",
		  m->keycode, m->keychar, m->modifier, m->time_stamp);
}


void
iiimp_keyevent_list_print(
    IIIMP_data_s *		data_s,
    IIIMP_keyevent_list *	m)
{
    int	i;

    if (NULL == m) return;

    for (i = 0; i < m->count; i++) {
	iiimp_keyevent_print(data_s, m->keyevent + i);
    }
}


/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
