Changeset 1499564 in mainline


Ignore:
Timestamp:
2012-08-15T14:18:30Z (12 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f66ca57f
Parents:
8a99c7e
Message:

wacomdump: Act as absolute mouse device

Location:
uspace/app/wacomdump
Files:
2 added
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/wacomdump/wacomdump.c

    r8a99c7e r1499564  
    3232#include <loc.h>
    3333#include <stdio.h>
     34#include <fibril_synch.h>
     35#include <abi/ipc/methods.h>
     36#include <ipc/mouseev.h>
    3437
    3538#include "isdv4.h"
    3639
     40#define NAME "wacomdump"
     41
     42static async_sess_t *client_sess = NULL;
     43static fibril_mutex_t client_mutex;
     44static isdv4_state_t state;
     45
    3746static void syntax_print(void)
    3847{
    39         fprintf(stderr, "Usage: wacomdump [--baud=<baud>] [device_service]\n");
    40 }
    41 
    42 static void print_event(const isdv4_event_t *event)
     48        fprintf(stderr, "Usage: wacomdump [--baud=<baud>] [--print-events] [device_service]\n");
     49}
     50
     51static int read_fibril(void *unused)
     52{
     53        int rc = isdv4_read_events(&state);
     54        if (rc != EOK) {
     55                fprintf(stderr, "Failed reading events");
     56                return rc;
     57        }
     58
     59        isdv4_fini(&state);
     60        return EOK;
     61}
     62
     63static void mouse_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     64{
     65        async_answer_0(iid, EOK);
     66       
     67        async_sess_t *sess =
     68            async_callback_receive(EXCHANGE_SERIALIZE);
     69        fibril_mutex_lock(&client_mutex);
     70                if (client_sess == NULL) {
     71                        client_sess = sess;
     72                }
     73        fibril_mutex_unlock(&client_mutex);
     74
     75        while (true) {
     76                ipc_call_t call;
     77                ipc_callid_t callid = async_get_call(&call);
     78               
     79                if (!IPC_GET_IMETHOD(call))
     80                        break;
     81               
     82                async_answer_0(callid, ENOTSUP);
     83        }
     84}
     85
     86static void emit_event(const isdv4_event_t *event)
     87{
     88        fibril_mutex_lock(&client_mutex);
     89        async_sess_t *sess = client_sess;
     90        fibril_mutex_unlock(&client_mutex);
     91       
     92        if (!sess) return;
     93       
     94        async_exch_t *exch = async_exchange_begin(sess);
     95        if (exch) {
     96                unsigned int max_x = state.stylus_max_x;
     97                unsigned int max_y = state.stylus_max_y;
     98                if (event->source == TOUCH) {
     99                        max_x = state.touch_max_x;
     100                        max_y = state.touch_max_y;
     101                }
     102                async_msg_4(exch, MOUSEEV_ABS_MOVE_EVENT, event->x, event->y,
     103                                    max_x, max_y);
     104                if (event->type == PRESS || event->type == RELEASE) {
     105                        async_msg_2(exch, MOUSEEV_BUTTON_EVENT, event->button,
     106                                    event->type == PRESS);
     107                }
     108        }
     109        async_exchange_end(exch);
     110}
     111
     112static void print_and_emit_event(const isdv4_event_t *event)
    43113{
    44114        const char *type = NULL;
     
    58128                case MOVE:
    59129                        type = "MOVE";
    60                         return;
    61                 case UNKNOWN:
     130                        break;
     131                default:
    62132                        type = "UNKNOWN";
    63133                        break;
     
    77147        }
    78148
    79         const char *buttons = "none";
    80         switch (event->button) {
    81                 case 1:
    82                         buttons = "button1";
    83                         break;
    84                 case 2:
    85                         buttons = "button2";
    86                         break;
    87                 case 3:
    88                         buttons = "both";
    89                         break;
    90         }
    91 
    92         printf("%s %s %u %u %u %s\n", type, source, event->x, event->y,
    93             event->pressure, buttons);
     149        printf("%s %s %u %u %u %u\n", type, source, event->x, event->y,
     150            event->pressure, event->button);
     151       
     152        emit_event(event);
    94153}
    95154
     
    120179        int rc;
    121180
     181        isdv4_event_fn event_fn = emit_event;
     182
    122183        if (argc > arg && str_test_prefix(argv[arg], "--baud=")) {
    123184                size_t arg_offset = str_lsize(argv[arg], 7);
     
    138199        }
    139200
     201        if (argc > arg && str_cmp(argv[arg], "--print-events") == 0) {
     202                event_fn = print_and_emit_event;
     203                arg++;
     204        }
     205
    140206        if (argc > arg) {
    141207                rc = loc_service_get_id(argv[arg], &svc_id, 0);
     
    181247        }
    182248
     249        fibril_mutex_initialize(&client_mutex);
     250
    183251        async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE, svc_id,
    184252            IPC_FLAG_BLOCKING);
     
    197265        }
    198266
    199         isdv4_state_t state;
    200         rc = isdv4_init(&state, sess, print_event);
     267        rc = isdv4_init(&state, sess, event_fn);
    201268        if (rc != EOK) {
    202269                fprintf(stderr, "Failed initializing isdv4 state");
     
    221288        printf(" Touch: %ux%u type: %s\n", state.touch_max_x, state.touch_max_y,
    222289                touch_type(state.touch_type));
    223 
    224         rc = isdv4_read_events(&state);
    225         if (rc != EOK) {
    226                 fprintf(stderr, "Failed reading events");
    227                 return 2;
    228         }
    229 
    230         isdv4_fini(&state);
    231 
     290       
     291        fid_t fibril = fibril_create(read_fibril, NULL);
     292        /* From this on, state is to be used only by read_fibril */
     293        fibril_add_ready(fibril);
     294
     295        async_set_client_connection(mouse_connection);
     296        rc = loc_server_register(NAME);
     297        if (rc != EOK) {
     298                printf("%s: Unable to register driver.\n", NAME);
     299                return rc;
     300        }
     301
     302        service_id_t service_id;
     303        rc = loc_service_register("mouse/wacom", &service_id);
     304        if (rc != EOK) {
     305                printf(NAME ": Unable to register device mouse/wacom.\n");
     306                return rc;
     307        }
     308
     309        category_id_t mouse_category;
     310        rc = loc_category_get_id("mouse", &mouse_category, IPC_FLAG_BLOCKING);
     311        if (rc != EOK) {
     312                printf(NAME ": Unable to get mouse category id.\n");
     313        }
     314        else {
     315                rc = loc_service_add_to_cat(service_id, mouse_category);
     316                if (rc != EOK) {
     317                        printf(NAME ": Unable to add device to mouse category.\n");
     318                }
     319        }
     320
     321        printf("%s: Accepting connections\n", NAME);
     322        task_retval(0);
     323        async_manager();
     324
     325        /* Not reached */
    232326        return 0;
    233327}
Note: See TracChangeset for help on using the changeset viewer.