1/**
2 * \file
3 * \brief Trigger API for terminal client library.
4 */
5
6/*
7 * Copyright (c) 2012, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich,
13 * Attn: Systems Group.
14 */
15
16#include <assert.h>
17#include <stdint.h>
18
19#include <barrelfish/barrelfish.h>
20#include <if/terminal_config_defs.h>
21#include <term/client/client.h>
22#include <term/client/trigger.h>
23
24#include "trigger_priv.h"
25
26/* internal functions */
27static int32_t trigger_list_id_cmp(void *data, void *arg);
28static int32_t trigger_list_user_cmp(void *data, void *arg);
29
30/**
31 * \brief Add a character trigger.
32 *
33 * \param client  Terminal client state.
34 * \param trigger Trigger to add.
35 *
36 * \return Trigger ID.
37 */
38term_trigger_id_t term_client_add_trigger(struct term_client *client,
39                                          struct term_trigger trigger)
40{
41    return term_client_add_trigger_type(client, trigger,
42                                        TERM_TRIGGER_TYPE_USER);
43}
44
45errval_t term_client_remove_trigger(struct term_client *client,
46                                    term_trigger_id_t id)
47{
48    errval_t err = SYS_ERR_OK;
49    struct term_trigger_priv *removed = NULL;
50
51    assert(client != NULL);
52    assert(client->triggers != NULL);
53
54    removed = collections_list_remove_if(client->triggers, trigger_list_id_cmp,
55                                         &id);
56    free(removed);
57    if (removed == NULL) {
58        err = TERM_ERR_TRIGGER_NOT_FOUND;
59    }
60    return err;
61}
62
63void term_client_remove_all_triggers(struct term_client *client)
64{
65    assert(client != NULL);
66    assert(client->triggers != NULL);
67
68    /* remove all user triggers, i.e. all but built-in triggers */
69    collections_list_remove_if_all(client->triggers, trigger_list_user_cmp,
70                                   NULL);
71}
72
73/**
74 * \privatesection
75 * Internal functions follow.
76 */
77term_trigger_id_t term_client_add_trigger_type(struct term_client *client,
78                                               struct term_trigger trigger,
79                                               enum term_trigger_type type)
80{
81    struct term_trigger_priv *trigger_priv = NULL;
82
83    assert(client != NULL);
84    assert(client->triggers != NULL);
85
86    /* create new trigger */
87    trigger_priv = malloc(sizeof(struct term_trigger_priv));
88    assert(trigger_priv != NULL);
89    trigger_priv->trigger = trigger;
90    trigger_priv->id = ++client->max_trigger_id;
91    trigger_priv->type = type;
92
93    /* add trigger to list of triggers */
94    collections_list_insert_tail(client->triggers, trigger_priv);
95
96    return trigger_priv->id;
97}
98
99static int32_t trigger_list_id_cmp(void *data, void *arg)
100{
101    struct term_trigger_priv *trigger_priv = data;
102    term_trigger_id_t id = *(term_trigger_id_t *) arg;
103
104    if ((trigger_priv->type == TERM_TRIGGER_TYPE_USER) &&
105        (trigger_priv->id == id)) {
106        return 1;
107    } else {
108        return 0;
109    }
110}
111
112static int32_t trigger_list_user_cmp(void *data, void *arg)
113{
114    struct term_trigger_priv *trigger_priv = data;
115
116    if (trigger_priv->type == TERM_TRIGGER_TYPE_USER) {
117        return 1;
118    } else {
119        return 0;
120    }
121}
122
123void term_trigger_free(void *data)
124{
125    free(data);
126}
127