Ignore:
File:
1 edited

Legend:

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

    r8e4a408 r00ddb40  
    5656#include <loc.h>
    5757
    58 #include <event.h>
    5958#include <io/keycode.h>
    6059#include <io/mode.h>
    6160#include <io/visualizer.h>
    6261#include <io/window.h>
     62#include <io/console.h>
    6363
    6464#include <transform.h>
     
    8484static sysarg_t coord_origin;
    8585static pixel_t bg_color;
     86static filter_t filter = filter_bilinear;
     87static unsigned int filter_index = 1;
    8688
    8789typedef struct {
     
    144146/** Input server proxy */
    145147static input_t *input;
    146 
     148static bool active = false;
     149
     150static int comp_active(input_t *);
     151static int comp_deactive(input_t *);
    147152static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    148153static int comp_mouse_move(input_t *, int, int);
     
    151156
    152157static input_ev_ops_t input_ev_ops = {
     158        .active = comp_active,
     159        .deactive = comp_deactive,
    153160        .key = comp_key_press,
    154161        .move = comp_mouse_move,
     
    156163        .button = comp_mouse_button
    157164};
    158 
    159 static void input_disconnect(void);
    160165
    161166static pointer_t *input_pointer(input_t *input)
     
    230235static void window_destroy(window_t *win)
    231236{
    232         if (win && atomic_get(&win->ref_cnt) == 0) {
     237        if ((win) && (atomic_get(&win->ref_cnt) == 0)) {
    233238                while (!list_empty(&win->queue.list)) {
    234239                        window_event_t *event = (window_event_t *) list_first(&win->queue.list);
     
    236241                        free(event);
    237242                }
    238 
    239                 if (win->surface) {
     243               
     244                if (win->surface)
    240245                        surface_destroy(win->surface);
    241                 }
     246               
    242247                free(win);
    243248        }
     
    251256        transform_invert(&win_trans);
    252257        transform_apply_affine(&win_trans, &x, &y);
    253 
    254         /* Since client coordinate origin is (0, 0), it is necessary to check
     258       
     259        /*
     260         * Since client coordinate origin is (0, 0), it is necessary to check
    255261         * coordinates to avoid underflow. Moreover, it is convenient to also
    256262         * check against provided upper limits to determine whether the converted
    257          * coordinates are within the client window.  */
    258         if (x < 0 || y < 0) {
     263         * coordinates are within the client window.
     264         */
     265        if ((x < 0) || (y < 0))
    259266                return false;
    260         } else {
    261                 (*x_out) = (sysarg_t) (x + 0.5);
    262                 (*y_out) = (sysarg_t) (y + 0.5);
    263 
    264                 if ((*x_out) >= x_lim || (*y_out) >= y_lim) {
    265                         return false;
    266                 } else {
    267                         return true;
    268                 }
    269         }
     267       
     268        (*x_out) = (sysarg_t) (x + 0.5);
     269        (*y_out) = (sysarg_t) (y + 0.5);
     270       
     271        if (((*x_out) >= x_lim) || ((*y_out) >= y_lim))
     272                return false;
     273       
     274        return true;
    270275}
    271276
     
    277282        transform_apply_affine(&win_trans, &x, &y);
    278283       
    279         /* It is assumed that compositor coordinate origin is chosen in such way,
    280          * that underflow/overflow here would be unlikely. */
     284        /*
     285         * It is assumed that compositor coordinate origin is chosen in such way,
     286         * that underflow/overflow here would be unlikely.
     287         */
    281288        (*x_out) = (sysarg_t) (x + 0.5);
    282289        (*y_out) = (sysarg_t) (y + 0.5);
     
    403410
    404411                        source_init(&source);
    405                         source_set_filter(&source, filter_nearest);
     412                        source_set_filter(&source, filter);
    406413                        drawctx_init(&context, vp->surface);
    407414                        drawctx_set_compose(&context, compose_over);
     
    436443                                        transform_translate(&transform, -pos.x, -pos.y);
    437444
    438                                         source_set_transform(&source, transform);                               
    439                                         source_set_texture(&source, win->surface, false);
     445                                        source_set_transform(&source, transform);
     446                                        source_set_texture(&source, win->surface,
     447                                            PIXELMAP_EXTEND_TRANSPARENT_SIDES);
    440448                                        source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0));
    441449
     
    565573
    566574        /* Notify visualizers about updated regions. */
    567         list_foreach(viewport_list, link, viewport_t, vp) {
    568                 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    569                 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
    570                 surface_reset_damaged_region(vp->surface);
    571                 visualizer_update_damaged_region(
    572                     vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0);
    573         }
    574 
     575        if (active) {
     576                list_foreach(viewport_list, link, viewport_t, vp) {
     577                        sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
     578                        surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
     579                        surface_reset_damaged_region(vp->surface);
     580                        visualizer_update_damaged_region(vp->sess,
     581                            x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0);
     582                }
     583        }
     584       
    575585        fibril_mutex_unlock(&viewport_list_mtx);
    576586}
     
    588598                return;
    589599        }
     600       
    590601        int rc = async_data_read_finalize(callid, event, len);
    591602        if (rc != EOK) {
     
    594605                return;
    595606        }
     607       
    596608        async_answer_0(iid, EOK);
    597        
    598609        free(event);
    599610}
     
    606617        double height = IPC_GET_ARG4(*icall);
    607618
    608         if (width == 0 || height == 0) {
     619        if ((width == 0) || (height == 0)) {
    609620                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    610621        } else {
     
    855866
    856867        comp_damage(x, y, width, height);
    857 
    858868        async_answer_0(iid, EOK);
    859869}
     
    861871static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    862872{
    863     window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     873        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    864874        if (event == NULL) {
    865875                async_answer_0(iid, ENOMEM);
     
    10011011                                break;
    10021012                        case WINDOW_CLOSE:
    1003                                 /* Postpone the closing until the phone is hung up to cover
    1004                                  * the case when the client is killed abruptly. */
     1013                                /*
     1014                                 * Postpone the closing until the phone is hung up to cover
     1015                                 * the case when the client is killed abruptly.
     1016                                 */
    10051017                                async_answer_0(callid, EOK);
    10061018                                break;
     
    10171029static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    10181030{
    1019         int rc;
    10201031        sysarg_t mode_idx = IPC_GET_ARG2(*icall);
    10211032        fibril_mutex_lock(&viewport_list_mtx);
     
    10231034        /* Retrieve the mode that shall be set. */
    10241035        vslmode_t new_mode;
    1025         rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
     1036        int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
    10261037        if (rc != EOK) {
    10271038                fibril_mutex_unlock(&viewport_list_mtx);
     
    10411052        /* Try to set the mode and share out the surface. */
    10421053        rc = visualizer_set_mode(vp->sess,
    1043                 new_mode.index, new_mode.version, surface_direct_access(new_surface));
     1054            new_mode.index, new_mode.version, surface_direct_access(new_surface));
    10441055        if (rc != EOK) {
    10451056                surface_destroy(new_surface);
     
    10711082}
    10721083
     1084#if 0
     1085static void comp_shutdown(void)
     1086{
     1087        loc_service_unregister(winreg_id);
     1088        input_disconnect();
     1089       
     1090        /* Close all clients and their windows. */
     1091        fibril_mutex_lock(&window_list_mtx);
     1092        list_foreach(window_list, link, window_t, win) {
     1093                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     1094                if (event) {
     1095                        link_initialize(&event->link);
     1096                        event->type = WINDOW_CLOSE;
     1097                        prodcons_produce(&win->queue, &event->link);
     1098                }
     1099        }
     1100        fibril_mutex_unlock(&window_list_mtx);
     1101       
     1102        async_answer_0(iid, EOK);
     1103       
     1104        /* All fibrils of the compositor will terminate soon. */
     1105}
     1106#endif
     1107
    10731108static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    10741109{
    10751110        /* Release viewport resources. */
    10761111        fibril_mutex_lock(&viewport_list_mtx);
     1112       
    10771113        list_remove(&vp->link);
    10781114        viewport_destroy(vp);
    1079 
    1080         /* Terminate compositor if there are no more viewports. */
    1081         if (list_empty(&viewport_list)) {
    1082                 fibril_mutex_unlock(&viewport_list_mtx);
    1083                 loc_service_unregister(winreg_id);
    1084                 input_disconnect();
    1085 
    1086                 /* Close all clients and their windows. */
    1087                 fibril_mutex_lock(&window_list_mtx);
    1088                 list_foreach(window_list, link, window_t, win) {
    1089                         window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    1090                         if (event) {
    1091                                 link_initialize(&event->link);
    1092                                 event->type = WINDOW_CLOSE;
    1093                                 prodcons_produce(&win->queue, &event->link);
    1094                         }
    1095                 }
    1096                 fibril_mutex_unlock(&window_list_mtx);
    1097 
    1098                 async_answer_0(iid, EOK);
    1099 
    1100                 /* All fibrils of the compositor will terminate soon. */
    1101         } else {
    1102                 fibril_mutex_unlock(&viewport_list_mtx);
    1103                 async_answer_0(iid, EOK);
    1104 
    1105                 comp_restrict_pointers();
    1106                 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    1107         }
     1115       
     1116        fibril_mutex_unlock(&viewport_list_mtx);
     1117       
     1118        async_answer_0(iid, EOK);
     1119       
     1120        comp_restrict_pointers();
     1121        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    11081122}
    11091123
     
    11201134        fibril_mutex_unlock(&viewport_list_mtx);
    11211135
    1122         if (!vp) {
     1136        if (!vp)
    11231137                return;
    1124         }
    11251138
    11261139        /* Ignore parameters, the connection is already opened. */
     
    12231236        /* Try to set the mode and share out the surface. */
    12241237        rc = visualizer_set_mode(vp->sess,
    1225                 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
     1238            vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
    12261239        if (rc != EOK) {
    12271240                printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc));
     
    12331246        if (claimed)
    12341247                visualizer_yield(vp->sess);
     1248       
    12351249        if (vp->sess != NULL)
    12361250                async_hangup(vp->sess);
     1251       
    12371252        free(vp);
    12381253        free(vsl_name);
     
    17751790}
    17761791
     1792static int comp_active(input_t *input)
     1793{
     1794        active = true;
     1795        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
     1796       
     1797        return EOK;
     1798}
     1799
     1800static int comp_deactive(input_t *input)
     1801{
     1802        active = false;
     1803        return EOK;
     1804}
     1805
    17771806static int comp_key_press(input_t *input, kbd_event_type_t type, keycode_t key,
    17781807    keymod_t mods, wchar_t c)
     
    17921821            key == KC_O || key == KC_P);
    17931822        bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
    1794 
    1795         bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
     1823        bool filter_switch = (mods & KM_ALT) && (key == KC_Y);
     1824
     1825        bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
    17961826            win_opacity || win_close || win_switch || viewport_move ||
    1797             viewport_change || kconsole_switch);
    1798 
    1799         if (filter) {
     1827            viewport_change || kconsole_switch || filter_switch);
     1828
     1829        if (key_filter) {
    18001830                /* no-op */
    18011831        } else if (win_transform) {
     
    20632093                fibril_mutex_unlock(&viewport_list_mtx);
    20642094        } else if (kconsole_switch) {
    2065                 __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
     2095                if (console_kcon())
     2096                        active = false;
     2097        } else if (filter_switch) {
     2098                filter_index++;
     2099                if (filter_index > 1)
     2100                        filter_index = 0;
     2101                if (filter_index == 0) {
     2102                        filter = filter_nearest;
     2103                }
     2104                else {
     2105                        filter = filter_bilinear;
     2106                }
     2107                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    20662108        } else {
    20672109                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     
    21322174}
    21332175
    2134 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    2135 {
    2136         comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2137 }
    2138 
    2139 static int discover_viewports(void)
    2140 {
     2176static void discover_viewports(void)
     2177{
     2178        fibril_mutex_lock(&discovery_mtx);
     2179       
    21412180        /* Create viewports and connect them to visualizers. */
    21422181        category_id_t cat_id;
    21432182        int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
    2144         if (rc != EOK) {
    2145                 printf("%s: Failed to get visualizer category.\n", NAME);
    2146                 return -1;
    2147         }
     2183        if (rc != EOK)
     2184                goto ret;
    21482185       
    21492186        service_id_t *svcs;
    21502187        size_t svcs_cnt = 0;
    21512188        rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
    2152         if (rc != EOK || svcs_cnt == 0) {
    2153                 printf("%s: Failed to get visualizer category services.\n", NAME);
    2154                 return -1;
    2155         }
    2156 
    2157         fibril_mutex_lock(&viewport_list_mtx); 
     2189        if (rc != EOK)
     2190                goto ret;
     2191       
     2192        fibril_mutex_lock(&viewport_list_mtx);
    21582193        for (size_t i = 0; i < svcs_cnt; ++i) {
    21592194                bool exists = false;
     
    21742209        fibril_mutex_unlock(&viewport_list_mtx);
    21752210       
    2176         /* TODO damage only newly added viewports */
    2177         comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2178         return EOK;
     2211        if (!list_empty(&viewport_list))
     2212                input_activate(input);
     2213       
     2214ret:
     2215        fibril_mutex_unlock(&discovery_mtx);
    21792216}
    21802217
    21812218static void category_change_cb(void)
    21822219{
    2183         fibril_mutex_lock(&discovery_mtx);
    21842220        discover_viewports();
    2185         fibril_mutex_unlock(&discovery_mtx);
    21862221}
    21872222
     
    21962231        /* Register compositor server. */
    21972232        async_set_client_connection(client_connection);
     2233       
    21982234        int rc = loc_server_register(NAME);
    21992235        if (rc != EOK) {
    22002236                printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
    22012237                return -1;
    2202         }
    2203        
    2204         /* Register interrupt handler to switch back from kconsole. */
    2205         async_set_interrupt_received(interrupt_received);
    2206         rc = event_subscribe(EVENT_KCONSOLE, 0);
    2207         if (rc != EOK) {
    2208                 printf("%s: Failed to register kconsole notifications (%s)\n",
    2209                     NAME, str_error(rc));
    22102238        }
    22112239       
     
    22292257                return -1;
    22302258        }
    2231 
     2259       
    22322260        /* Establish input bidirectional connection. */
    22332261        rc = input_connect(input_svc);
     
    22362264                return rc;
    22372265        }
    2238 
     2266       
    22392267        rc = loc_register_cat_change_cb(category_change_cb);
    22402268        if (rc != EOK) {
     
    22422270                input_disconnect();
    22432271                return rc;
    2244         }       
    2245 
    2246         rc = discover_viewports();
    2247         if (rc != EOK) {
    2248                 input_disconnect();
    2249                 return rc;
    2250         }
    2251        
    2252         if (list_empty(&viewport_list)) {
    2253                 printf("%s: Failed to get viewports.\n", NAME);
    2254                 input_disconnect();
    2255                 return -1;
    2256         }
    2257 
     2272        }
     2273       
     2274        discover_viewports();
     2275       
    22582276        comp_restrict_pointers();
    22592277        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2260        
    22612278       
    22622279        return EOK;
Note: See TracChangeset for help on using the changeset viewer.