Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/compositor/compositor.c

    rd17a4a9 r6d5e378  
    4949#include <adt/prodcons.h>
    5050#include <adt/list.h>
    51 #include <io/input.h>
    5251#include <ipc/graph.h>
     52#include <ipc/input.h>
    5353#include <ipc/window.h>
    5454
     
    9292        sysarg_t id;
    9393        uint8_t state;
    94         desktop_point_t pos;
     94        sysarg_t hpos;
     95        sysarg_t vpos;
    9596        sysarg_t btn_num;
    96         desktop_point_t btn_pos;
    97         desktop_vector_t accum;
     97        sysarg_t btn_hpos;
     98        sysarg_t btn_vpos;
     99        int accum_dx;
     100        int accum_dy;
    98101        sysarg_t grab_flags;
    99102        bool pressed;
     
    132135        vslmode_t mode;
    133136        async_sess_t *sess;
    134         desktop_point_t pos;
     137        sysarg_t hpos;
     138        sysarg_t vpos;
    135139        surface_t *surface;
    136140} viewport_t;
     
    139143static LIST_INITIALIZE(viewport_list);
    140144
    141 /** Input server proxy */
    142 static input_t *input;
    143 
    144 static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    145 static int comp_mouse_move(input_t *, int, int);
    146 static int comp_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned);
    147 static int comp_mouse_button(input_t *, int, int);
    148 
    149 static input_ev_ops_t input_ev_ops = {
    150         .key = comp_key_press,
    151         .move = comp_mouse_move,
    152         .abs_move = comp_abs_move,
    153         .button = comp_mouse_button
    154 };
    155 
    156 static void input_disconnect(void);
    157 
    158 
    159 static pointer_t *input_pointer(input_t *input)
    160 {
    161         return input->user;
    162 }
     145static async_sess_t *input_sess;
    163146
    164147static pointer_t *pointer_create()
     
    170153
    171154        link_initialize(&p->link);
    172         p->pos.x = coord_origin;
    173         p->pos.y = coord_origin;
     155        p->hpos = coord_origin;
     156        p->vpos = coord_origin;
    174157        p->btn_num = 1;
    175         p->btn_pos = p->pos;
    176         p->accum.x = 0;
    177         p->accum.y = 0;
     158        p->btn_hpos = p->hpos;
     159        p->btn_vpos = p->vpos;
     160        p->accum_dx = 0;
     161        p->accum_dy = 0;
    178162        p->grab_flags = GF_EMPTY;
    179163        p->pressed = false;
     
    302286                bool isec_vp = rectangle_intersect(
    303287                    x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob,
    304                     vp->pos.x, vp->pos.y, w_dmg_vp, h_dmg_vp,
     288                    vp->hpos, vp->vpos, w_dmg_vp, h_dmg_vp,
    305289                    &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
    306290
     
    308292
    309293                        /* Paint background color. */
    310                         for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
    311                                 for (sysarg_t x = x_dmg_vp - vp->pos.x; x < x_dmg_vp - vp->pos.x + w_dmg_vp; ++x) {
     294                        for (sysarg_t y = y_dmg_vp - vp->vpos; y <  y_dmg_vp - vp->vpos + h_dmg_vp; ++y) {
     295                                for (sysarg_t x = x_dmg_vp - vp->hpos; x < x_dmg_vp - vp->hpos + w_dmg_vp; ++x) {
    312296                                        surface_put_pixel(vp->surface, x, y, bg_color);
    313297                                }
     
    347331                                         * coordinates. */
    348332                                        transform = win->transform;
    349                                         double_point_t pos;
    350                                         pos.x = vp->pos.x;
    351                                         pos.y = vp->pos.y;
    352                                         transform_translate(&transform, -pos.x, -pos.y);
     333                                        double hpos = vp->hpos;
     334                                        double vpos = vp->vpos;
     335                                        transform_translate(&transform, -hpos, -vpos);
    353336
    354337                                        source_set_transform(&source, transform);                               
     
    357340
    358341                                        drawctx_transfer(&context,
    359                                             x_dmg_win - vp->pos.x, y_dmg_win - vp->pos.y, w_dmg_win, h_dmg_win);
     342                                            x_dmg_win - vp->hpos, y_dmg_win - vp->vpos, w_dmg_win, h_dmg_win);
    360343                                }
    361344                        }
     
    371354                                bool isec_ptr = rectangle_intersect(
    372355                                    x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
    373                                     ptr->pos.x, ptr->pos.y, w_dmg_ptr, h_dmg_ptr,
     356                                    ptr->hpos, ptr->vpos, w_dmg_ptr, h_dmg_ptr,
    374357                                    &x_dmg_ptr, &y_dmg_ptr, &w_dmg_ptr, &h_dmg_ptr);
    375358
     
    382365
    383366                                        pixel_t pix = 0;
    384                                         sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
    385                                         sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
    386                                         sysarg_t x_ptr = x_dmg_ptr - ptr->pos.x;
    387                                         sysarg_t y_ptr = y_dmg_ptr - ptr->pos.y;
     367                                        sysarg_t x_vp = x_dmg_ptr - vp->hpos;
     368                                        sysarg_t y_vp = y_dmg_ptr - vp->vpos;
     369                                        sysarg_t x_ptr = x_dmg_ptr - ptr->hpos;
     370                                        sysarg_t y_ptr = y_dmg_ptr - ptr->vpos;
    388371
    389372                                        for (sysarg_t y = 0; y < h_dmg_ptr; ++y) {
     
    776759                fibril_mutex_unlock(&viewport_list_mtx);
    777760                loc_service_unregister(winreg_id);
    778                 input_disconnect();
     761                async_hangup(input_sess);
    779762
    780763                /* Close all clients and their windows. */
     
    897880
    898881        link_initialize(&vp->link);
    899         vp->pos.x = coord_origin;
    900         vp->pos.y = coord_origin;
     882        vp->hpos = coord_origin;
     883        vp->vpos = coord_origin;
    901884
    902885        /* Establish output bidirectional connection. */
     
    998981        /* window_list_mtx locked by caller */
    999982
    1000         int dx = pointer->accum.x;
    1001         int dy = pointer->accum.y;
    1002         pointer->accum.x = 0;
    1003         pointer->accum.y = 0;
     983        int dx = pointer->accum_dx;
     984        int dy = pointer->accum_dy;
     985        pointer->accum_dx = 0;
     986        pointer->accum_dy = 0;
    1004987
    1005988        bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
     
    10721055}
    10731056
    1074 static int comp_abs_move(input_t *input, unsigned x , unsigned y,
    1075     unsigned max_x, unsigned max_y)
    1076 {
    1077         /* XXX TODO Use absolute coordinates directly */
    1078        
    1079         pointer_t *pointer = input_pointer(input);
    1080        
    1081         sysarg_t width, height;
    1082        
    1083         fibril_mutex_lock(&viewport_list_mtx);
    1084         if (list_empty(&viewport_list)) {
    1085                 printf("No viewport found\n");
    1086                 fibril_mutex_unlock(&viewport_list_mtx);
    1087                 return EOK; /* XXX */
    1088         }
    1089         link_t *link = list_first(&viewport_list);
    1090         viewport_t *vp = list_get_instance(link, viewport_t, link);
    1091         surface_get_resolution(vp->surface, &width, &height);
    1092         desktop_point_t vp_pos = vp->pos;
    1093         fibril_mutex_unlock(&viewport_list_mtx);
    1094 
    1095         desktop_point_t pos_in_viewport;
    1096         pos_in_viewport.x = x * width / max_x;
    1097         pos_in_viewport.y = y * height / max_y;
    1098        
    1099         /* Calculate offset from pointer */
    1100         fibril_mutex_lock(&pointer_list_mtx);
    1101         desktop_vector_t delta;
    1102         delta.x = (vp_pos.x + pos_in_viewport.x) - pointer->pos.x;
    1103         delta.y = (vp_pos.y + pos_in_viewport.y) - pointer->pos.y;
    1104         fibril_mutex_unlock(&pointer_list_mtx);
    1105        
    1106         return comp_mouse_move(input, delta.x, delta.y);
    1107 }
    1108 
    1109 static int comp_mouse_move(input_t *input, int dx, int dy)
    1110 {
    1111         pointer_t *pointer = input_pointer(input);
     1057static void comp_mouse_move(pointer_t *pointer, ipc_callid_t iid, ipc_call_t *icall)
     1058{
     1059        int dx = (int) IPC_GET_ARG1(*icall);
     1060        int dy = (int) IPC_GET_ARG2(*icall);
    11121061
    11131062        /* Update pointer position. */
    11141063        fibril_mutex_lock(&pointer_list_mtx);
    1115         desktop_point_t old_pos = pointer->pos;
     1064        sysarg_t old_hpos = pointer->hpos;
     1065        sysarg_t old_vpos = pointer->vpos;
    11161066        sysarg_t cursor_width;
    11171067        sysarg_t cursor_height;
    11181068        surface_get_resolution(pointer->cursor.states[pointer->state],
    11191069             &cursor_width, &cursor_height);
    1120         pointer->pos.x += dx;
    1121         pointer->pos.y += dy;
     1070        pointer->hpos += dx;
     1071        pointer->vpos += dy;
    11221072        fibril_mutex_unlock(&pointer_list_mtx);
    1123         comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
    1124         comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
     1073        comp_damage(old_hpos, old_vpos, cursor_width, cursor_height);
     1074        comp_damage(old_hpos + dx, old_vpos + dy, cursor_width, cursor_height);
    11251075
    11261076        fibril_mutex_lock(&window_list_mtx);
     
    11341084                        sysarg_t width, height;
    11351085                        surface_get_resolution(top->surface, &width, &height);
    1136                         within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1086                        within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
    11371087                            top->transform, width, height, &point_x, &point_y);
    11381088                        fibril_mutex_unlock(&window_list_mtx);
     
    11531103                } else {
    11541104                        /* Pointer is grabbed by top-level window action. */
    1155                         pointer->accum.x += dx;
    1156                         pointer->accum.y += dy;
     1105                        pointer->accum_dx += dx;
     1106                        pointer->accum_dy += dy;
    11571107#if ANIMATE_WINDOW_TRANSFORMS == 1
    11581108                        sysarg_t x, y, width, height;
     
    11681118        }
    11691119
    1170         return EOK;
    1171 }
    1172 
    1173 static int comp_mouse_button(input_t *input, int bnum, int bpress)
    1174 {
    1175         pointer_t *pointer = input_pointer(input);
    1176 
    1177         if (bpress) {
    1178                 pointer->btn_pos = pointer->pos;
    1179                 pointer->btn_num = bnum;
     1120        async_answer_0(iid, EOK);
     1121}
     1122
     1123static void comp_mouse_button(pointer_t *pointer, ipc_callid_t iid, ipc_call_t *icall)
     1124{
     1125        sysarg_t btn_num = IPC_GET_ARG1(*icall);
     1126        bool pressed = (bool) IPC_GET_ARG2(*icall);
     1127
     1128        if (pressed) {
     1129                pointer->btn_hpos = pointer->hpos;
     1130                pointer->btn_vpos = pointer->vpos;
     1131                pointer->btn_num = btn_num;
    11801132                pointer->pressed = true;
    11811133
     
    11851137                if (!win || !win->surface) {
    11861138                        fibril_mutex_unlock(&window_list_mtx);
    1187                         return EOK;
     1139                        async_answer_0(iid, EOK);
     1140                        return;
    11881141                }
    11891142                sysarg_t x, y, width, height;
    11901143                surface_get_resolution(win->surface, &width, &height);
    1191                 bool within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1144                bool within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
    11921145                    win->transform, width, height, &x, &y);
    11931146                fibril_mutex_unlock(&window_list_mtx);
     
    12011154                                event->data.pos.pos_id = pointer->id;
    12021155                                event->data.pos.type = POS_PRESS;
    1203                                 event->data.pos.btn_num = bnum;
     1156                                event->data.pos.btn_num = btn_num;
    12041157                                event->data.pos.hpos = x;
    12051158                                event->data.pos.vpos = y;
    12061159                                comp_post_event(event);
    12071160                        } else {
    1208                                 return ENOMEM;
    1209                         }
    1210                 }
    1211         } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
     1161                                async_answer_0(iid, ENOMEM);
     1162                                return;
     1163                        }
     1164                }
     1165        } else if (pointer->pressed && pointer->btn_num == btn_num) {
    12121166                pointer->pressed = false;
    12131167
     
    12241178                        if (win->surface) {
    12251179                                surface_get_resolution(win->surface, &width, &height);
    1226                                 within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1180                                within_client = comp_coord_to_client(pointer->hpos, pointer->vpos,
    12271181                                    win->transform, width, height, &point_x, &point_y);
    12281182                        }
     
    12371191                        pointer->grab_flags = GF_EMPTY;
    12381192                        fibril_mutex_unlock(&window_list_mtx);
    1239                         return EOK;
     1193                        async_answer_0(iid, EOK);
     1194                        return;
    12401195                }
    12411196
     
    13021257                                event->data.pos.pos_id = pointer->id;
    13031258                                event->data.pos.type = POS_RELEASE;
    1304                                 event->data.pos.btn_num = bnum;
     1259                                event->data.pos.btn_num = btn_num;
    13051260                                event->data.pos.hpos = point_x;
    13061261                                event->data.pos.vpos = point_y;
     
    13081263                        pointer->grab_flags = GF_EMPTY;
    13091264                       
    1310                 } else if (within_client && (pointer->grab_flags == GF_EMPTY) && (bnum == 1)) {
     1265                } else if (within_client && (pointer->grab_flags == GF_EMPTY) && (btn_num == 1)) {
    13111266
    13121267                        /* Bring the window to the foreground. */
     
    13311286        }
    13321287
    1333         return EOK;
    1334 }
    1335 
    1336 static int comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key,
    1337     keymod_t mods, wchar_t c)
    1338 {
     1288        async_answer_0(iid, EOK);
     1289}
     1290
     1291static void comp_key_press(ipc_callid_t iid, ipc_call_t *icall)
     1292{
     1293        kbd_event_type_t type = IPC_GET_ARG1(*icall);
     1294        keycode_t key = IPC_GET_ARG2(*icall);
     1295        keymod_t mods = IPC_GET_ARG3(*icall);
     1296        wchar_t c = IPC_GET_ARG4(*icall);
     1297
    13391298        bool win_transform = (mods & KM_ALT) && (
    13401299            key == KC_W || key == KC_S || key == KC_A || key == KC_D ||
     
    14191378                        if (event == NULL) {
    14201379                                fibril_mutex_unlock(&window_list_mtx);
    1421                                 return ENOMEM;
     1380                                async_answer_0(iid, ENOMEM);
     1381                                return;
    14221382                        }
    14231383
     
    14881448        } else if (win_close) {
    14891449                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    1490                 if (event == NULL)
    1491                         return ENOMEM;
     1450                if (event == NULL) {
     1451                        async_answer_0(iid, ENOMEM);
     1452                        return;
     1453                }
    14921454
    14931455                link_initialize(&event->link);
     
    15401502                        switch (key) {
    15411503                        case KC_I:
    1542                                 vp->pos.x += 0;
    1543                                 vp->pos.y += -20;
     1504                                vp->hpos += 0;
     1505                                vp->vpos += -20;
    15441506                                break;
    15451507                        case KC_K:
    1546                                 vp->pos.x += 0;
    1547                                 vp->pos.y += 20;
     1508                                vp->hpos += 0;
     1509                                vp->vpos += 20;
    15481510                                break;
    15491511                        case KC_J:
    1550                                 vp->pos.x += -20;
    1551                                 vp->pos.y += 0;
     1512                                vp->hpos += -20;
     1513                                vp->vpos += 0;
    15521514                                break;
    15531515                        case KC_L:
    1554                                 vp->pos.x += 20;
    1555                                 vp->pos.y += 0;
     1516                                vp->hpos += 20;
     1517                                vp->vpos += 0;
    15561518                                break;
    15571519                        default:
    1558                                 vp->pos.x += 0;
    1559                                 vp->pos.y += 0;
     1520                                vp->hpos += 0;
     1521                                vp->vpos += 0;
    15601522                                break;
    15611523                        }
    15621524                       
    1563                         sysarg_t x = vp->pos.x;
    1564                         sysarg_t y = vp->pos.y;
     1525                        sysarg_t x = vp->hpos;
     1526                        sysarg_t y = vp->vpos;
    15651527                        sysarg_t width, height;
    15661528                        surface_get_resolution(vp->surface, &width, &height);
     
    16321594        } else {
    16331595                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    1634                 if (event == NULL)
    1635                         return ENOMEM;
     1596                if (event == NULL) {
     1597                        async_answer_0(iid, ENOMEM);
     1598                        return;
     1599                }
    16361600
    16371601                link_initialize(&event->link);
     
    16451609        }
    16461610
    1647         return EOK;
    1648 }
    1649 
    1650 static int input_connect(const char *svc)
    1651 {
    1652         async_sess_t *sess;
    1653         service_id_t dsid;
    1654 
    1655         int rc = loc_service_get_id(svc, &dsid, 0);
    1656         if (rc != EOK) {
    1657                 printf("%s: Input service %s not found\n", NAME, svc);
    1658                 return rc;
    1659         }
    1660 
    1661         sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0);
    1662         if (sess == NULL) {
    1663                 printf("%s: Unable to connect to input service %s\n", NAME,
    1664                     svc);
    1665                 return EIO;
    1666         }
    1667 
     1611        async_answer_0(iid, EOK);
     1612}
     1613
     1614static void input_events(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     1615{
    16681616        fibril_mutex_lock(&pointer_list_mtx);
    16691617        pointer_t *pointer = pointer_create();
     
    16741622        fibril_mutex_unlock(&pointer_list_mtx);
    16751623
    1676         if (pointer == NULL) {
    1677                 printf("%s: Cannot create pointer.\n", NAME);
    1678                 async_hangup(sess);
    1679                 return ENOMEM;
    1680         }
    1681 
    1682         rc = input_open(sess, &input_ev_ops, pointer, &input);
     1624        /* Ignore parameters, the connection is already opened. */
     1625        while (true) {
     1626                ipc_call_t call;
     1627                ipc_callid_t callid = async_get_call(&call);
     1628
     1629                if (!IPC_GET_IMETHOD(call)) {
     1630                        fibril_mutex_lock(&pointer_list_mtx);
     1631                        if (pointer != NULL) {
     1632                                list_remove(&pointer->link);
     1633                                pointer_destroy(pointer);
     1634                        }
     1635                        fibril_mutex_unlock(&pointer_list_mtx);
     1636                        async_hangup(input_sess);
     1637                        return;
     1638                }
     1639
     1640                switch (IPC_GET_IMETHOD(call)) {
     1641                case INPUT_EVENT_KEY:
     1642                        comp_key_press(callid, &call);
     1643                        break;
     1644                case INPUT_EVENT_MOVE:
     1645                        comp_mouse_move(pointer, callid, &call);
     1646                        break;
     1647                case INPUT_EVENT_BUTTON:
     1648                        comp_mouse_button(pointer, callid, &call);
     1649                        break;
     1650                default:
     1651                        async_answer_0(callid, EINVAL);
     1652                }
     1653        }
     1654}
     1655
     1656static async_sess_t *input_connect(const char *svc)
     1657{
     1658        async_sess_t *sess;
     1659        service_id_t dsid;
     1660
     1661        int rc = loc_service_get_id(svc, &dsid, 0);
     1662        if (rc == EOK) {
     1663                sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0);
     1664                if (sess == NULL) {
     1665                        printf("%s: Unable to connect to input service %s\n", NAME, svc);
     1666                        return NULL;
     1667                }
     1668        } else
     1669                return NULL;
     1670
     1671        async_exch_t *exch = async_exchange_begin(sess);
     1672        rc = async_connect_to_me(exch, 0, 0, 0, input_events, NULL);
     1673        async_exchange_end(exch);
     1674
    16831675        if (rc != EOK) {
    16841676                async_hangup(sess);
    1685                 printf("%s: Unable to communicate with service %s (%s)\n",
     1677                printf("%s: Unable to create callback connection to service %s (%s)\n",
    16861678                    NAME, svc, str_error(rc));
    1687                 return rc;
    1688         }
    1689 
    1690         return EOK;
    1691 }
    1692 
    1693 static void input_disconnect(void)
    1694 {
    1695         pointer_t *pointer = input->user;
    1696         input_close(input);
    1697         pointer_destroy(pointer);
     1679                return NULL;
     1680        }
     1681
     1682        return sess;
    16981683}
    16991684
     
    17481733
    17491734        /* Establish input bidirectional connection. */
    1750         rc = input_connect(input_svc);
    1751         if (rc != EOK)
    1752                 return rc;
     1735        input_sess = input_connect(input_svc);
     1736        if (input_sess == NULL) {
     1737                return -1;
     1738        }
    17531739
    17541740        /* Create viewports and connect them to visualizers. */
     
    17561742        rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
    17571743        if (rc != EOK) {
    1758                 input_disconnect();
     1744                async_hangup(input_sess);
    17591745                return -1;
    17601746        }
     
    17641750        rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
    17651751        if (rc != EOK || svcs_cnt == 0) {
    1766                 input_disconnect();
     1752                async_hangup(input_sess);
    17671753                return -1;
    17681754        }
     
    17801766       
    17811767        if (list_empty(&viewport_list)) {
    1782                 input_disconnect();
     1768                async_hangup(input_sess);
    17831769                return -1;
    17841770        }
Note: See TracChangeset for help on using the changeset viewer.