Ignore:
File:
1 edited

Legend:

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

    r3b98311 r2f6ad06  
    5555#include <async.h>
    5656#include <loc.h>
    57 #include <devman.h>
    58 
    59 #include <event.h>
    60 #include <device/graph_dev.h>
     57#include <task.h>
     58
    6159#include <io/keycode.h>
    6260#include <io/mode.h>
    6361#include <io/visualizer.h>
    6462#include <io/window.h>
     63#include <io/console.h>
    6564
    6665#include <transform.h>
     
    7271#include <codec/tga.h>
    7372
    74 #include "images.h"
    7573#include "compositor.h"
    7674
     
    8785static sysarg_t coord_origin;
    8886static pixel_t bg_color;
     87static filter_t filter = filter_bilinear;
     88static unsigned int filter_index = 1;
    8989
    9090typedef struct {
    9191        link_t link;
    9292        atomic_t ref_cnt;
     93        window_flags_t flags;
    9394        service_id_t in_dsid;
    9495        service_id_t out_dsid;
     
    143144static LIST_INITIALIZE(viewport_list);
    144145
     146static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);
     147
    145148/** Input server proxy */
    146149static input_t *input;
    147 
     150static bool active = false;
     151
     152static int comp_active(input_t *);
     153static int comp_deactive(input_t *);
    148154static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    149155static int comp_mouse_move(input_t *, int, int);
     
    152158
    153159static input_ev_ops_t input_ev_ops = {
     160        .active = comp_active,
     161        .deactive = comp_deactive,
    154162        .key = comp_key_press,
    155163        .move = comp_mouse_move,
     
    158166};
    159167
    160 static void input_disconnect(void);
    161 
    162 
    163168static pointer_t *input_pointer(input_t *input)
    164169{
     
    166171}
    167172
    168 static pointer_t *pointer_create()
     173static pointer_t *pointer_create(void)
    169174{
    170175        pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
    171         if (!p) {
     176        if (!p)
    172177                return NULL;
    173         }
    174 
     178       
    175179        link_initialize(&p->link);
    176180        p->pos.x = coord_origin;
     
    184188        p->state = 0;
    185189        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    186 
     190       
    187191        /* Ghost window for transformation animation. */
    188192        transform_identity(&p->ghost.transform);
     
    197201        p->accum_ghost.x = 0;
    198202        p->accum_ghost.y = 0;
    199 
     203       
    200204        return p;
    201205}
     
    209213}
    210214
    211 static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
     215static window_t *window_create(void)
    212216{
    213217        window_t *win = (window_t *) malloc(sizeof(window_t));
    214         if (!win) {
     218        if (!win)
    215219                return NULL;
    216         }
    217 
     220       
    218221        link_initialize(&win->link);
    219222        atomic_set(&win->ref_cnt, 0);
    220223        prodcons_initialize(&win->queue);
    221224        transform_identity(&win->transform);
    222         transform_translate(&win->transform,
    223             coord_origin + x_offset, coord_origin + y_offset);
    224         win->dx = coord_origin + x_offset;
    225         win->dy = coord_origin + y_offset;
     225        transform_translate(&win->transform, coord_origin, coord_origin);
     226        win->dx = coord_origin;
     227        win->dy = coord_origin;
    226228        win->fx = 1;
    227229        win->fy = 1;
     
    229231        win->opacity = 255;
    230232        win->surface = NULL;
    231 
     233       
    232234        return win;
    233235}
     
    235237static void window_destroy(window_t *win)
    236238{
    237         if (win && atomic_get(&win->ref_cnt) == 0) {
     239        if ((win) && (atomic_get(&win->ref_cnt) == 0)) {
    238240                while (!list_empty(&win->queue.list)) {
    239241                        window_event_t *event = (window_event_t *) list_first(&win->queue.list);
     
    241243                        free(event);
    242244                }
    243 
    244                 if (win->surface) {
     245               
     246                if (win->surface)
    245247                        surface_destroy(win->surface);
    246                 }
     248               
    247249                free(win);
    248250        }
     
    256258        transform_invert(&win_trans);
    257259        transform_apply_affine(&win_trans, &x, &y);
    258 
    259         /* Since client coordinate origin is (0, 0), it is necessary to check
     260       
     261        /*
     262         * Since client coordinate origin is (0, 0), it is necessary to check
    260263         * coordinates to avoid underflow. Moreover, it is convenient to also
    261264         * check against provided upper limits to determine whether the converted
    262          * coordinates are within the client window.  */
    263         if (x < 0 || y < 0) {
     265         * coordinates are within the client window.
     266         */
     267        if ((x < 0) || (y < 0))
    264268                return false;
    265         } else {
    266                 (*x_out) = (sysarg_t) (x + 0.5);
    267                 (*y_out) = (sysarg_t) (y + 0.5);
    268 
    269                 if ((*x_out) >= x_lim || (*y_out) >= y_lim) {
    270                         return false;
    271                 } else {
    272                         return true;
    273                 }
    274         }
     269       
     270        (*x_out) = (sysarg_t) (x + 0.5);
     271        (*y_out) = (sysarg_t) (y + 0.5);
     272       
     273        if (((*x_out) >= x_lim) || ((*y_out) >= y_lim))
     274                return false;
     275       
     276        return true;
    275277}
    276278
     
    282284        transform_apply_affine(&win_trans, &x, &y);
    283285       
    284         /* It is assumed that compositor coordinate origin is chosen in such way,
    285          * that underflow/overflow here would be unlikely. */
     286        /*
     287         * It is assumed that compositor coordinate origin is chosen in such way,
     288         * that underflow/overflow here would be unlikely.
     289         */
    286290        (*x_out) = (sysarg_t) (x + 0.5);
    287291        (*y_out) = (sysarg_t) (y + 0.5);
     
    292296    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    293297{
    294         if (w_in > 0 && h_in > 0) {
     298        if ((w_in > 0) && (h_in > 0)) {
    295299                sysarg_t x[4];
    296300                sysarg_t y[4];
     301               
    297302                comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
    298303                comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
    299304                comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
    300305                comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
     306               
    301307                (*x_out) = x[0];
    302308                (*y_out) = y[0];
    303309                (*w_out) = x[0];
    304310                (*h_out) = y[0];
    305                 for (int i = 1; i < 4; ++i) {
     311               
     312                for (unsigned int i = 1; i < 4; ++i) {
    306313                        (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
    307314                        (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
     
    309316                        (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
    310317                }
     318               
    311319                (*w_out) = (*w_out) - (*x_out) + 1;
    312320                (*h_out) = (*h_out) - (*y_out) + 1;
     
    319327}
    320328
    321 static void comp_restrict_pointers(void)
     329static void comp_update_viewport_bound_rect(void)
    322330{
    323331        fibril_mutex_lock(&viewport_list_mtx);
    324 
     332       
    325333        sysarg_t x_res = coord_origin;
    326334        sysarg_t y_res = coord_origin;
    327335        sysarg_t w_res = 0;
    328336        sysarg_t h_res = 0;
    329 
     337       
    330338        if (!list_empty(&viewport_list)) {
    331339                viewport_t *vp = (viewport_t *) list_first(&viewport_list);
     
    334342                surface_get_resolution(vp->surface, &w_res, &h_res);
    335343        }
    336 
    337         list_foreach(viewport_list, link) {
    338                 viewport_t *vp = list_get_instance(link, viewport_t, link);
     344       
     345        list_foreach(viewport_list, link, viewport_t, vp) {
    339346                sysarg_t w_vp, h_vp;
    340347                surface_get_resolution(vp->surface, &w_vp, &h_vp);
    341                 rectangle_union(
    342                     x_res, y_res, w_res, h_res,
     348                rectangle_union(x_res, y_res, w_res, h_res,
    343349                    vp->pos.x, vp->pos.y, w_vp, h_vp,
    344350                    &x_res, &y_res, &w_res, &h_res);
    345351        }
    346 
     352       
    347353        viewport_bound_rect.x = x_res;
    348354        viewport_bound_rect.y = y_res;
    349355        viewport_bound_rect.w = w_res;
    350356        viewport_bound_rect.h = h_res;
    351 
     357       
    352358        fibril_mutex_unlock(&viewport_list_mtx);
    353 
     359}
     360
     361static void comp_restrict_pointers(void)
     362{
     363        comp_update_viewport_bound_rect();
     364       
    354365        fibril_mutex_lock(&pointer_list_mtx);
    355 
    356         list_foreach(pointer_list, link) {
    357                 pointer_t *ptr = list_get_instance(link, pointer_t, link);
     366       
     367        list_foreach(pointer_list, link, pointer_t, ptr) {
    358368                ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
    359369                ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
     
    363373                    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
    364374        }
    365 
     375       
    366376        fibril_mutex_unlock(&pointer_list_mtx);
    367377}
     
    374384        fibril_mutex_lock(&pointer_list_mtx);
    375385
    376         list_foreach(viewport_list, link) {
    377 
     386        list_foreach(viewport_list, link, viewport_t, vp) {
    378387                /* Determine what part of the viewport must be updated. */
    379                 viewport_t *vp = list_get_instance(link, viewport_t, link);
    380388                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    381389                surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
     
    404412
    405413                        source_init(&source);
    406                         source_set_filter(&source, filter_nearest);
     414                        source_set_filter(&source, filter);
    407415                        drawctx_init(&context, vp->surface);
    408416                        drawctx_set_compose(&context, compose_over);
     
    437445                                        transform_translate(&transform, -pos.x, -pos.y);
    438446
    439                                         source_set_transform(&source, transform);                               
    440                                         source_set_texture(&source, win->surface, false);
     447                                        source_set_transform(&source, transform);
     448                                        source_set_texture(&source, win->surface,
     449                                            PIXELMAP_EXTEND_TRANSPARENT_SIDES);
    441450                                        source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0));
    442451
     
    446455                        }
    447456
    448                         list_foreach(pointer_list, link) {
    449 
    450                                 pointer_t *ptr = list_get_instance(link, pointer_t, link);
     457                        list_foreach(pointer_list, link, pointer_t, ptr) {
    451458                                if (ptr->ghost.surface) {
    452459
     
    522529                        }
    523530
    524                         list_foreach(pointer_list, link) {
     531                        list_foreach(pointer_list, link, pointer_t, ptr) {
    525532
    526533                                /* Determine what part of the pointer intersects with the
    527534                                 * updated area of the current viewport. */
    528                                 pointer_t *ptr = list_get_instance(link, pointer_t, link);
    529535                                sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
    530536                                surface_t *sf_ptr = ptr->cursor.states[ptr->state];
     
    569575
    570576        /* Notify visualizers about updated regions. */
    571         list_foreach(viewport_list, link) {
    572                 viewport_t *vp = list_get_instance(link, viewport_t, link);
    573                 sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    574                 surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
    575                 surface_reset_damaged_region(vp->surface);
    576                 visualizer_update_damaged_region(
    577                     vp->sess, x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0);
    578         }
    579 
     577        if (active) {
     578                list_foreach(viewport_list, link, viewport_t, vp) {
     579                        sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
     580                        surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
     581                        surface_reset_damaged_region(vp->surface);
     582                        visualizer_update_damaged_region(vp->sess,
     583                            x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp, 0, 0);
     584                }
     585        }
     586       
    580587        fibril_mutex_unlock(&viewport_list_mtx);
    581588}
     
    593600                return;
    594601        }
     602       
    595603        int rc = async_data_read_finalize(callid, event, len);
    596604        if (rc != EOK) {
     
    599607                return;
    600608        }
     609       
    601610        async_answer_0(iid, EOK);
    602        
    603611        free(event);
    604612}
     
    611619        double height = IPC_GET_ARG4(*icall);
    612620
    613         if (width == 0 || height == 0) {
     621        if ((width == 0) || (height == 0)) {
    614622                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    615623        } else {
     
    629637        sysarg_t pos_id = IPC_GET_ARG1(*icall);
    630638        sysarg_t grab_flags = IPC_GET_ARG2(*icall);
     639       
     640        /*
     641         * Filter out resize grab flags if the window
     642         * is not resizeable.
     643         */
     644        if ((win->flags & WINDOW_RESIZEABLE) != WINDOW_RESIZEABLE)
     645                grab_flags &= ~(GF_RESIZE_X | GF_RESIZE_Y);
    631646
    632647        fibril_mutex_lock(&pointer_list_mtx);
    633         list_foreach(pointer_list, link) {
    634                 pointer_t *pointer = list_get_instance(link, pointer_t, link);
     648        list_foreach(pointer_list, link, pointer_t, pointer) {
    635649                if (pointer->id == pos_id) {
    636650                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     
    649663}
    650664
     665static void comp_recalc_transform(window_t *win)
     666{
     667        transform_t translate;
     668        transform_identity(&translate);
     669        transform_translate(&translate, win->dx, win->dy);
     670       
     671        transform_t scale;
     672        transform_identity(&scale);
     673        if ((win->fx != 1) || (win->fy != 1))
     674                transform_scale(&scale, win->fx, win->fy);
     675       
     676        transform_t rotate;
     677        transform_identity(&rotate);
     678        if (win->angle != 0)
     679                transform_rotate(&rotate, win->angle);
     680       
     681        transform_t transform;
     682        transform_t temp;
     683        transform_identity(&transform);
     684        temp = transform;
     685        transform_product(&transform, &temp, &translate);
     686        temp = transform;
     687        transform_product(&transform, &temp, &rotate);
     688        temp = transform;
     689        transform_product(&transform, &temp, &scale);
     690       
     691        win->transform = transform;
     692}
     693
    651694static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    652695{
    653         int rc;
    654 
    655696        ipc_callid_t callid;
    656697        size_t size;
    657698        unsigned int flags;
    658 
     699       
    659700        /* Start sharing resized window with client. */
    660701        if (!async_share_out_receive(&callid, &size, &flags)) {
     
    662703                return;
    663704        }
     705       
    664706        void *new_cell_storage;
    665         rc = async_share_out_finalize(callid, &new_cell_storage);
     707        int rc = async_share_out_finalize(callid, &new_cell_storage);
    666708        if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
    667709                async_answer_0(iid, ENOMEM);
    668710                return;
    669711        }
    670 
     712       
    671713        /* Create new surface for the resized window. */
    672         surface_t *new_surface = surface_create(
    673             IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
    674             new_cell_storage, SURFACE_FLAG_SHARED);
     714        surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
     715            IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
    675716        if (!new_surface) {
    676717                as_area_destroy(new_cell_storage);
     
    678719                return;
    679720        }
    680 
     721       
     722        sysarg_t offset_x = IPC_GET_ARG1(*icall);
     723        sysarg_t offset_y = IPC_GET_ARG2(*icall);
     724        window_placement_flags_t placement_flags =
     725            (window_placement_flags_t) IPC_GET_ARG5(*icall);
     726       
     727        comp_update_viewport_bound_rect();
     728       
    681729        /* Switch new surface with old surface and calculate damage. */
    682730        fibril_mutex_lock(&window_list_mtx);
    683 
     731       
    684732        sysarg_t old_width = 0;
    685733        sysarg_t old_height = 0;
     734       
    686735        if (win->surface) {
    687736                surface_get_resolution(win->surface, &old_width, &old_height);
    688737                surface_destroy(win->surface);
    689738        }
    690 
     739       
    691740        win->surface = new_surface;
    692 
     741       
    693742        sysarg_t new_width = 0;
    694743        sysarg_t new_height = 0;
    695744        surface_get_resolution(win->surface, &new_width, &new_height);
    696 
    697         sysarg_t x, y;
    698         sysarg_t width = old_width > new_width ? old_width : new_width;
    699         sysarg_t height = old_height > new_height ? old_height : new_height;
    700         comp_coord_bounding_rect(0, 0, width, height, win->transform, &x, &y, &width, &height);
    701 
     745       
     746        if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
     747                win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
     748                    new_width / 2;
     749       
     750        if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
     751                win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
     752                    new_height / 2;
     753       
     754        if (placement_flags & WINDOW_PLACEMENT_LEFT)
     755                win->dx = viewport_bound_rect.x;
     756       
     757        if (placement_flags & WINDOW_PLACEMENT_TOP)
     758                win->dy = viewport_bound_rect.y;
     759       
     760        if (placement_flags & WINDOW_PLACEMENT_RIGHT)
     761                win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
     762                    new_width;
     763       
     764        if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
     765                win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
     766                    new_height;
     767       
     768        if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
     769                win->dx = coord_origin + offset_x;
     770       
     771        if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
     772                win->dy = coord_origin + offset_y;
     773       
     774        /* Transform the window and calculate damage. */
     775        sysarg_t x1;
     776        sysarg_t y1;
     777        sysarg_t width1;
     778        sysarg_t height1;
     779       
     780        comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
     781            &x1, &y1, &width1, &height1);
     782       
     783        comp_recalc_transform(win);
     784       
     785        sysarg_t x2;
     786        sysarg_t y2;
     787        sysarg_t width2;
     788        sysarg_t height2;
     789       
     790        comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
     791            &x2, &y2, &width2, &height2);
     792       
     793        sysarg_t x;
     794        sysarg_t y;
     795        sysarg_t width;
     796        sysarg_t height;
     797       
     798        rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
     799            &x, &y, &width, &height);
     800       
    702801        fibril_mutex_unlock(&window_list_mtx);
    703 
     802       
    704803        comp_damage(x, y, width, height);
    705 
     804       
    706805        async_answer_0(iid, EOK);
    707806}
     
    710809{
    711810        fibril_mutex_lock(&window_list_mtx);
    712         window_t *window = NULL;
    713         list_foreach(window_list, link) {
    714                 window = list_get_instance(link, window_t, link);
     811       
     812        list_foreach(window_list, link, window_t, window) {
    715813                if (window == target) {
    716814                        prodcons_produce(&window->queue, &event->link);
    717                 }
    718         }
    719         if (!window) {
     815                        fibril_mutex_unlock(&window_list_mtx);
     816                        return;
     817                }
     818        }
     819       
     820        fibril_mutex_unlock(&window_list_mtx);
     821        free(event);
     822}
     823
     824static void comp_post_event_top(window_event_t *event)
     825{
     826        fibril_mutex_lock(&window_list_mtx);
     827       
     828        window_t *win = (window_t *) list_first(&window_list);
     829        if (win)
     830                prodcons_produce(&win->queue, &event->link);
     831        else
    720832                free(event);
    721         }
    722         fibril_mutex_unlock(&window_list_mtx);
    723 }
    724 
    725 static void comp_post_event_top(window_event_t *event)
    726 {
    727         fibril_mutex_lock(&window_list_mtx);
    728         window_t *win = (window_t *) list_first(&window_list);
    729         if (win) {
    730                 prodcons_produce(&win->queue, &event->link);
    731         } else {
    732                 free(event);
    733         }
     833       
    734834        fibril_mutex_unlock(&window_list_mtx);
    735835}
     
    775875
    776876        comp_damage(x, y, width, height);
    777 
    778877        async_answer_0(iid, EOK);
    779878}
     
    781880static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    782881{
    783     window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     882        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    784883        if (event == NULL) {
    785884                async_answer_0(iid, ENOMEM);
     
    798897        ipc_call_t call;
    799898        ipc_callid_t callid;
    800         service_id_t service_id = (service_id_t) IPC_GET_ARG1(*icall);
     899        service_id_t service_id = (service_id_t) IPC_GET_ARG2(*icall);
    801900
    802901        /* Allocate resources for new window and register it to the location service. */
     
    808907                        fibril_mutex_lock(&window_list_mtx);
    809908
    810                         window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
     909                        window_t *win = window_create();
    811910                        if (!win) {
    812911                                async_answer_2(callid, ENOMEM, 0, 0);
    813912                                return;
    814913                        }
     914                       
     915                        win->flags = IPC_GET_ARG1(call);
    815916
    816917                        char name_in[LOC_NAME_MAXLEN + 1];
     
    863964        window_t *win = NULL;
    864965        fibril_mutex_lock(&window_list_mtx);
    865         list_foreach(window_list, link) {
    866                 window_t *cur = list_get_instance(link, window_t, link);
     966        list_foreach(window_list, link, window_t, cur) {
    867967                if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
    868968                        win = cur;
     
    9221022                                break;
    9231023                        case WINDOW_CLOSE:
    924                                 /* Postpone the closing until the phone is hung up to cover
    925                                  * the case when the client is killed abruptly. */
     1024                                /*
     1025                                 * Postpone the closing until the phone is hung up to cover
     1026                                 * the case when the client is killed abruptly.
     1027                                 */
    9261028                                async_answer_0(callid, EOK);
    9271029                                break;
     
    9381040static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    9391041{
    940         int rc;
    9411042        sysarg_t mode_idx = IPC_GET_ARG2(*icall);
    9421043        fibril_mutex_lock(&viewport_list_mtx);
     
    9441045        /* Retrieve the mode that shall be set. */
    9451046        vslmode_t new_mode;
    946         rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
     1047        int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
    9471048        if (rc != EOK) {
    9481049                fibril_mutex_unlock(&viewport_list_mtx);
     
    9621063        /* Try to set the mode and share out the surface. */
    9631064        rc = visualizer_set_mode(vp->sess,
    964                 new_mode.index, new_mode.version, surface_direct_access(new_surface));
     1065            new_mode.index, new_mode.version, surface_direct_access(new_surface));
    9651066        if (rc != EOK) {
    9661067                surface_destroy(new_surface);
     
    9921093}
    9931094
     1095#if 0
     1096static void comp_shutdown(void)
     1097{
     1098        loc_service_unregister(winreg_id);
     1099        input_disconnect();
     1100       
     1101        /* Close all clients and their windows. */
     1102        fibril_mutex_lock(&window_list_mtx);
     1103        list_foreach(window_list, link, window_t, win) {
     1104                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     1105                if (event) {
     1106                        link_initialize(&event->link);
     1107                        event->type = WINDOW_CLOSE;
     1108                        prodcons_produce(&win->queue, &event->link);
     1109                }
     1110        }
     1111        fibril_mutex_unlock(&window_list_mtx);
     1112       
     1113        async_answer_0(iid, EOK);
     1114       
     1115        /* All fibrils of the compositor will terminate soon. */
     1116}
     1117#endif
     1118
    9941119static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    9951120{
    9961121        /* Release viewport resources. */
    9971122        fibril_mutex_lock(&viewport_list_mtx);
     1123       
    9981124        list_remove(&vp->link);
    9991125        viewport_destroy(vp);
    1000 
    1001         /* Terminate compositor if there are no more viewports. */
    1002         if (list_empty(&viewport_list)) {
    1003                 fibril_mutex_unlock(&viewport_list_mtx);
    1004                 loc_service_unregister(winreg_id);
    1005                 input_disconnect();
    1006 
    1007                 /* Close all clients and their windows. */
    1008                 fibril_mutex_lock(&window_list_mtx);
    1009                 list_foreach(window_list, link) {
    1010                         window_t *win = list_get_instance(link, window_t, link);
    1011                         window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    1012                         if (event) {
    1013                                 link_initialize(&event->link);
    1014                                 event->type = WINDOW_CLOSE;
    1015                                 prodcons_produce(&win->queue, &event->link);
    1016                         }
    1017                 }
    1018                 fibril_mutex_unlock(&window_list_mtx);
    1019 
    1020                 async_answer_0(iid, EOK);
    1021 
    1022                 /* All fibrils of the compositor will terminate soon. */
    1023         } else {
    1024                 fibril_mutex_unlock(&viewport_list_mtx);
    1025                 async_answer_0(iid, EOK);
    1026 
    1027                 comp_restrict_pointers();
    1028                 comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    1029         }
     1126       
     1127        fibril_mutex_unlock(&viewport_list_mtx);
     1128       
     1129        async_answer_0(iid, EOK);
     1130       
     1131        comp_restrict_pointers();
     1132        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    10301133}
    10311134
     
    10341137        viewport_t *vp = NULL;
    10351138        fibril_mutex_lock(&viewport_list_mtx);
    1036         list_foreach(viewport_list, link) {
    1037                 viewport_t *cur = list_get_instance(link, viewport_t, link);
     1139        list_foreach(viewport_list, link, viewport_t, cur) {
    10381140                if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
    10391141                        vp = cur;
     
    10431145        fibril_mutex_unlock(&viewport_list_mtx);
    10441146
    1045         if (!vp) {
     1147        if (!vp)
    10461148                return;
    1047         }
    10481149
    10491150        /* Ignore parameters, the connection is already opened. */
     
    10701171}
    10711172
    1072 static async_sess_t *vsl_connect(const char *svc)
     1173static async_sess_t *vsl_connect(service_id_t sid, const char *svc)
    10731174{
    10741175        int rc;
    10751176        async_sess_t *sess;
    1076         service_id_t dsid;
    1077         devman_handle_t handle;
    1078 
    1079         rc = loc_service_get_id(svc, &dsid, 0);
    1080         if (rc != EOK) {
     1177
     1178        sess = loc_service_connect(sid, INTERFACE_DDF, 0);
     1179        if (sess == NULL) {
     1180                printf("%s: Unable to connect to visualizer %s\n", NAME, svc);
    10811181                return NULL;
    10821182        }
    10831183
    1084         rc = devman_fun_sid_to_handle(dsid, &handle);
    1085         if (rc == EOK) {
    1086                 sess = devman_device_connect(EXCHANGE_SERIALIZE, handle, 0);
    1087                 if (sess == NULL) {
    1088                         printf("%s: Unable to connect to visualizer %s\n", NAME, svc);
    1089                         return NULL;
    1090                 }
    1091                 rc = graph_dev_connect(sess);
    1092                 if (rc != EOK) {
    1093                         return NULL;
    1094                 }
    1095         } else if (rc == ENOENT) {
    1096                 sess = loc_service_connect(EXCHANGE_SERIALIZE, dsid, 0);
    1097                 if (sess == NULL) {
    1098                         printf("%s: Unable to connect to visualizer %s\n", NAME, svc);
    1099                         return NULL;
    1100                 }
    1101         } else {
    1102                 return NULL;
    1103         }
    1104 
    11051184        async_exch_t *exch = async_exchange_begin(sess);
    1106         rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL);
     1185       
     1186        port_id_t port;
     1187        rc = async_create_callback_port(exch, INTERFACE_VISUALIZER_CB, 0, 0,
     1188            vsl_notifications, NULL, &port);
     1189       
    11071190        async_exchange_end(exch);
    11081191
     
    11171200}
    11181201
    1119 static viewport_t *viewport_create(const char *vsl_name)
     1202static viewport_t *viewport_create(service_id_t sid)
    11201203{
    11211204        int rc;
    1122 
    1123         viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t));
    1124         if (!vp) {
    1125                 return NULL;
    1126         }
     1205        char *vsl_name = NULL;
     1206        viewport_t *vp = NULL;
     1207        bool claimed = false;
     1208
     1209        rc = loc_service_get_name(sid, &vsl_name);
     1210        if (rc != EOK)
     1211                goto error;
     1212
     1213        vp = (viewport_t *) calloc(1, sizeof(viewport_t));
     1214        if (!vp)
     1215                goto error;
    11271216
    11281217        link_initialize(&vp->link);
     
    11311220
    11321221        /* Establish output bidirectional connection. */
    1133         vp->sess = vsl_connect(vsl_name);
    1134         rc = loc_service_get_id(vsl_name, &vp->dsid, 0);
    1135         if (vp->sess == NULL || rc != EOK) {
    1136                 free(vp);
    1137                 return NULL;
    1138         }
     1222        vp->dsid = sid;
     1223        vp->sess = vsl_connect(sid, vsl_name);
     1224        if (vp->sess == NULL)
     1225                goto error;
    11391226
    11401227        /* Claim the given visualizer. */
    11411228        rc = visualizer_claim(vp->sess, 0);
    11421229        if (rc != EOK) {
    1143                 async_hangup(vp->sess);
    1144                 free(vp);
    11451230                printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc));
    1146                 return NULL;
    1147         }
     1231                goto error;
     1232        }
     1233
     1234        claimed = true;
    11481235
    11491236        /* Retrieve the default mode. */
    11501237        rc = visualizer_get_default_mode(vp->sess, &vp->mode);
    11511238        if (rc != EOK) {
    1152                 visualizer_yield(vp->sess);
    1153                 async_hangup(vp->sess);
    1154                 free(vp);
    11551239                printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc));
    1156                 return NULL;
     1240                goto error;
    11571241        }
    11581242
     
    11611245            NULL, SURFACE_FLAG_SHARED);
    11621246        if (vp->surface == NULL) {
    1163                 visualizer_yield(vp->sess);
    1164                 async_hangup(vp->sess);
    1165                 free(vp);
    11661247                printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc));
    1167                 return NULL;
     1248                goto error;
    11681249        }
    11691250
    11701251        /* Try to set the mode and share out the surface. */
    11711252        rc = visualizer_set_mode(vp->sess,
    1172                 vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
     1253            vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
    11731254        if (rc != EOK) {
     1255                printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc));
     1256                goto error;
     1257        }
     1258
     1259        return vp;
     1260error:
     1261        if (claimed)
    11741262                visualizer_yield(vp->sess);
    1175                 surface_destroy(vp->surface);
     1263       
     1264        if (vp->sess != NULL)
    11761265                async_hangup(vp->sess);
    1177                 free(vp);
    1178                 printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc));
    1179                 return NULL;
    1180         }
    1181 
    1182         return vp;
    1183 }
    1184 
    1185 static void comp_recalc_transform(window_t *win)
    1186 {
    1187         transform_t translate;
    1188         transform_identity(&translate);
    1189         transform_translate(&translate, win->dx, win->dy);
    1190 
    1191         transform_t scale;
    1192         transform_identity(&scale);
    1193         if (win->fx != 1 || win->fy != 1) {
    1194                 transform_scale(&scale, win->fx, win->fy);
    1195         }
    1196 
    1197         transform_t rotate;
    1198         transform_identity(&rotate);
    1199         if (win->angle != 0) {
    1200                 transform_rotate(&rotate, win->angle);
    1201         }
    1202 
    1203         transform_t transform;
    1204         transform_t temp;
    1205         transform_identity(&transform);
    1206         temp = transform;
    1207         transform_multiply(&transform, &temp, &translate);
    1208         temp = transform;
    1209         transform_multiply(&transform, &temp, &rotate);
    1210         temp = transform;
    1211         transform_multiply(&transform, &temp, &scale);
    1212        
    1213 
    1214         win->transform = transform;
     1266       
     1267        free(vp);
     1268        free(vsl_name);
     1269        return NULL;
    12151270}
    12161271
     
    12361291                double cx = 0;
    12371292                double cy = 0;
    1238                 if (pointer->grab_flags & GF_MOVE_X) {
     1293               
     1294                if (pointer->grab_flags & GF_MOVE_X)
    12391295                        cx = 1;
    1240                 }
    1241                 if (pointer->grab_flags & GF_MOVE_Y) {
     1296               
     1297                if (pointer->grab_flags & GF_MOVE_Y)
    12421298                        cy = 1;
    1243                 }
    1244 
    1245                 if ((scale || resize) && (win->angle != 0)) {
     1299               
     1300                if (((scale) || (resize)) && (win->angle != 0)) {
    12461301                        transform_t rotate;
    12471302                        transform_identity(&rotate);
     1303                       
    12481304                        transform_rotate(&rotate, win->angle);
    12491305                        transform_apply_linear(&rotate, &cx, &cy);
    12501306                }
    12511307               
    1252                 cx = (cx < 0) ? (-1 * cx) : cx; 
     1308                cx = (cx < 0) ? (-1 * cx) : cx;
    12531309                cy = (cy < 0) ? (-1 * cy) : cy;
    1254 
     1310               
    12551311                win->dx += (cx * dx);
    12561312                win->dy += (cy * dy);
    12571313        }
    12581314
    1259         if (scale || resize) {
     1315        if ((scale) || (resize)) {
    12601316                double _dx = dx;
    12611317                double _dy = dy;
     
    12731329                        if (fx > 0) {
    12741330#if ANIMATE_WINDOW_TRANSFORMS == 0
    1275                                 if (scale) win->fx *= fx;
     1331                                if (scale)
     1332                                        win->fx *= fx;
    12761333#endif
    12771334#if ANIMATE_WINDOW_TRANSFORMS == 1
     
    14541511{
    14551512        pointer_t *pointer = input_pointer(input);
    1456 
     1513       
     1514        comp_update_viewport_bound_rect();
     1515       
    14571516        /* Update pointer position. */
    14581517        fibril_mutex_lock(&pointer_list_mtx);
     1518       
    14591519        desktop_point_t old_pos = pointer->pos;
     1520       
    14601521        sysarg_t cursor_width;
    14611522        sysarg_t cursor_height;
    1462         surface_get_resolution(pointer->cursor.states[pointer->state], 
     1523        surface_get_resolution(pointer->cursor.states[pointer->state],
    14631524             &cursor_width, &cursor_height);
    1464         if (pointer->pos.x + dx < viewport_bound_rect.x) {
     1525       
     1526        if (pointer->pos.x + dx < viewport_bound_rect.x)
    14651527                dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
    1466         }
    1467         if (pointer->pos.y + dy < viewport_bound_rect.y) {
     1528       
     1529        if (pointer->pos.y + dy < viewport_bound_rect.y)
    14681530                dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
    1469         }
    1470         if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
     1531       
     1532        if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
    14711533                dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
    1472         }
    1473         if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
     1534       
     1535        if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
    14741536                dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
    1475         }
     1537       
    14761538        pointer->pos.x += dx;
    14771539        pointer->pos.y += dy;
     
    14791541        comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
    14801542        comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
    1481 
     1543       
    14821544        fibril_mutex_lock(&window_list_mtx);
    14831545        fibril_mutex_lock(&pointer_list_mtx);
     
    15711633
    15721634        /* Determine the window which the mouse click belongs to. */
    1573         list_foreach(window_list, link) {
    1574                 win = list_get_instance(link, window_t, link);
     1635        list_foreach(window_list, link, window_t, cw) {
     1636                win = cw;
    15751637                if (win->surface) {
    15761638                        surface_get_resolution(win->surface, &width, &height);
     
    16401702
    16411703#if ANIMATE_WINDOW_TRANSFORMS == 0
    1642                 sysarg_t pre_x = 0; 
     1704                sysarg_t pre_x = 0;
    16431705                sysarg_t pre_y = 0;
    16441706                sysarg_t pre_width = 0;
     
    16721734                                link_initialize(&event_top->link);
    16731735                                event_top->type = ET_WINDOW_RESIZE;
    1674 
     1736                               
     1737                                event_top->data.resize.offset_x = 0;
     1738                                event_top->data.resize.offset_y = 0;
     1739                               
    16751740                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
    16761741                                int dy = (int) (((double) height) * (scale_back_y - 1.0));
    1677 
    1678                                 if (pointer->grab_flags & GF_RESIZE_X) {
    1679                                         event_top->data.rsz.width =
    1680                                                 ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    1681                                 } else {
    1682                                         event_top->data.rsz.width = width;
    1683                                 }
    1684 
    1685                                 if (pointer->grab_flags & GF_RESIZE_Y) {
    1686                                         event_top->data.rsz.height =
    1687                                                 ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    1688                                 } else {
    1689                                         event_top->data.rsz.height = height;
    1690                                 }
     1742                               
     1743                                if (pointer->grab_flags & GF_RESIZE_X)
     1744                                        event_top->data.resize.width =
     1745                                            ((((int) width) + dx) >= 0) ? (width + dx) : 0;
     1746                                else
     1747                                        event_top->data.resize.width = width;
     1748                               
     1749                                if (pointer->grab_flags & GF_RESIZE_Y)
     1750                                        event_top->data.resize.height =
     1751                                            ((((int) height) + dy) >= 0) ? (height + dy) : 0;
     1752                                else
     1753                                        event_top->data.resize.height = height;
     1754                               
     1755                                event_top->data.resize.placement_flags =
     1756                                    WINDOW_PLACEMENT_ANY;
    16911757                        }
    16921758
     
    17361802        }
    17371803
     1804        return EOK;
     1805}
     1806
     1807static int comp_active(input_t *input)
     1808{
     1809        active = true;
     1810        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
     1811       
     1812        return EOK;
     1813}
     1814
     1815static int comp_deactive(input_t *input)
     1816{
     1817        active = false;
    17381818        return EOK;
    17391819}
     
    17551835        bool viewport_change = (mods & KM_ALT) && (
    17561836            key == KC_O || key == KC_P);
    1757         bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
    1758         bool compositor_test = (mods & KM_ALT) && (key == KC_H);
    1759 
    1760         bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
     1837        bool kconsole_switch = (key == KC_PAUSE) || (key == KC_BREAK);
     1838        bool filter_switch = (mods & KM_ALT) && (key == KC_Y);
     1839
     1840        bool key_filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
    17611841            win_opacity || win_close || win_switch || viewport_move ||
    1762             viewport_change || kconsole_switch || compositor_test);
    1763 
    1764         if (filter) {
     1842            viewport_change || kconsole_switch || filter_switch);
     1843
     1844        if (key_filter) {
    17651845                /* no-op */
    17661846        } else if (win_transform) {
     
    17821862                                break;
    17831863                        case KC_Q:
    1784                                 win->angle += (PI / 2);
     1864                                win->angle += 0.1;
    17851865                                break;
    17861866                        case KC_E:
    1787                                 win->angle += -(PI / 2);
     1867                                win->angle -= 0.1;
    17881868                                break;
    17891869                        case KC_R:
     
    18201900                fibril_mutex_lock(&window_list_mtx);
    18211901                window_t *win = (window_t *) list_first(&window_list);
    1822                 if (win && win->surface) {
     1902                if ((win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) {
    18231903                        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    18241904                        if (event == NULL) {
     
    18261906                                return ENOMEM;
    18271907                        }
    1828 
     1908                       
    18291909                        sysarg_t width, height;
    18301910                        surface_get_resolution(win->surface, &width, &height);
    1831 
     1911                       
    18321912                        link_initialize(&event->link);
    18331913                        event->type = ET_WINDOW_RESIZE;
    1834 
     1914                       
     1915                        event->data.resize.offset_x = 0;
     1916                        event->data.resize.offset_y = 0;
     1917                       
    18351918                        switch (key) {
    18361919                        case KC_T:
    1837                                 event->data.rsz.width = width;
    1838                                 event->data.rsz.height = (height >= 20) ? height - 20 : 0;
     1920                                event->data.resize.width = width;
     1921                                event->data.resize.height = (height >= 20) ? height - 20 : 0;
    18391922                                break;
    18401923                        case KC_G:
    1841                                 event->data.rsz.width = width;
    1842                                 event->data.rsz.height = height + 20;
     1924                                event->data.resize.width = width;
     1925                                event->data.resize.height = height + 20;
    18431926                                break;
    18441927                        case KC_B:
    1845                                 event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
    1846                                 event->data.rsz.height = height;
     1928                                event->data.resize.width = (width >= 20) ? width - 20 : 0;;
     1929                                event->data.resize.height = height;
    18471930                                break;
    18481931                        case KC_N:
    1849                                 event->data.rsz.width = width + 20;
    1850                                 event->data.rsz.height = height;
     1932                                event->data.resize.width = width + 20;
     1933                                event->data.resize.height = height;
    18511934                                break;
    18521935                        default:
    1853                                 event->data.rsz.width = 0;
    1854                                 event->data.rsz.height = 0;
    1855                                 break;
    1856                         }
    1857 
     1936                                event->data.resize.width = 0;
     1937                                event->data.resize.height = 0;
     1938                                break;
     1939                        }
     1940                       
     1941                        event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
     1942                       
    18581943                        fibril_mutex_unlock(&window_list_mtx);
    18591944                        comp_post_event_top(event);
     
    20232108                fibril_mutex_unlock(&viewport_list_mtx);
    20242109        } else if (kconsole_switch) {
    2025                 __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
    2026         } else if (compositor_test) {
    2027                 fibril_mutex_lock(&window_list_mtx);
    2028 
    2029                 window_t *red_win = window_create(0, 0);
    2030                 red_win->surface = surface_create(250, 150, NULL, 0);
    2031                 pixel_t red_pix = PIXEL(255, 240, 0, 0);
    2032                 for (sysarg_t y = 0; y <  150; ++y) {
    2033                         for (sysarg_t x = 0; x < 250; ++x) {
    2034                                 surface_put_pixel(red_win->surface, x, y, red_pix);
    2035                         }
    2036                 }
    2037                 list_prepend(&red_win->link, &window_list);
    2038 
    2039                 window_t *blue_win = window_create(0, 0);
    2040                 blue_win->surface = surface_create(200, 100, NULL, 0);
    2041                 pixel_t blue_pix = PIXEL(255, 0, 0, 240);
    2042                 for (sysarg_t y = 0; y <  100; ++y) {
    2043                         for (sysarg_t x = 0; x < 200; ++x) {
    2044                                 surface_put_pixel(blue_win->surface, x, y, blue_pix);
    2045                         }
    2046                 }
    2047                 list_prepend(&blue_win->link, &window_list);
    2048                
    2049                 window_t *nameic_win = window_create(0, 0);
    2050                 nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
    2051                 list_prepend(&nameic_win->link, &window_list);
    2052 
    2053                 fibril_mutex_unlock(&window_list_mtx);
     2110                if (console_kcon())
     2111                        active = false;
     2112        } else if (filter_switch) {
     2113                filter_index++;
     2114                if (filter_index > 1)
     2115                        filter_index = 0;
     2116                if (filter_index == 0) {
     2117                        filter = filter_nearest;
     2118                }
     2119                else {
     2120                        filter = filter_bilinear;
     2121                }
    20542122                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    20552123        } else {
     
    20822150        }
    20832151
    2084         sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0);
     2152        sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
    20852153        if (sess == NULL) {
    20862154                printf("%s: Unable to connect to input service %s\n", NAME,
     
    21212189}
    21222190
    2123 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    2124 {
    2125         comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
     2191static void discover_viewports(void)
     2192{
     2193        fibril_mutex_lock(&discovery_mtx);
     2194       
     2195        /* Create viewports and connect them to visualizers. */
     2196        category_id_t cat_id;
     2197        int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
     2198        if (rc != EOK)
     2199                goto ret;
     2200       
     2201        service_id_t *svcs;
     2202        size_t svcs_cnt = 0;
     2203        rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
     2204        if (rc != EOK)
     2205                goto ret;
     2206       
     2207        fibril_mutex_lock(&viewport_list_mtx);
     2208        for (size_t i = 0; i < svcs_cnt; ++i) {
     2209                bool exists = false;
     2210                list_foreach(viewport_list, link, viewport_t, vp) {
     2211                        if (vp->dsid == svcs[i]) {
     2212                                exists = true;
     2213                                break;
     2214                        }
     2215                }
     2216               
     2217                if (exists)
     2218                        continue;
     2219               
     2220                viewport_t *vp = viewport_create(svcs[i]);
     2221                if (vp != NULL)
     2222                        list_append(&vp->link, &viewport_list);
     2223        }
     2224        fibril_mutex_unlock(&viewport_list_mtx);
     2225       
     2226        if (!list_empty(&viewport_list))
     2227                input_activate(input);
     2228       
     2229ret:
     2230        fibril_mutex_unlock(&discovery_mtx);
     2231}
     2232
     2233static void category_change_cb(void)
     2234{
     2235        discover_viewports();
    21262236}
    21272237
     
    21322242       
    21332243        /* Color of the viewport background. Must be opaque. */
    2134         bg_color = PIXEL(255, 75, 70, 75);
     2244        bg_color = PIXEL(255, 69, 51, 103);
    21352245       
    21362246        /* Register compositor server. */
    2137         async_set_client_connection(client_connection);
     2247        async_set_fallback_port_handler(client_connection, NULL);
     2248       
    21382249        int rc = loc_server_register(NAME);
    21392250        if (rc != EOK) {
    21402251                printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
    21412252                return -1;
    2142         }
    2143        
    2144         /* Register interrupt handler to switch back from kconsole. */
    2145         async_set_interrupt_received(interrupt_received);
    2146         rc = event_subscribe(EVENT_KCONSOLE, 0);
    2147         if (rc != EOK) {
    2148                 printf("%s: Failed to register kconsole notifications (%s)\n",
    2149                     NAME, str_error(rc));
    21502253        }
    21512254       
     
    21692272                return -1;
    21702273        }
    2171 
     2274       
    21722275        /* Establish input bidirectional connection. */
    21732276        rc = input_connect(input_svc);
    2174         if (rc != EOK)
     2277        if (rc != EOK) {
     2278                printf("%s: Failed to connect to input service.\n", NAME);
    21752279                return rc;
    2176 
    2177         /* Create viewports and connect them to visualizers. */
    2178         category_id_t cat_id;
    2179         rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
     2280        }
     2281       
     2282        rc = loc_register_cat_change_cb(category_change_cb);
    21802283        if (rc != EOK) {
     2284                printf("%s: Failed to register category change callback\n", NAME);
    21812285                input_disconnect();
    2182                 return -1;
    2183         }
    2184        
    2185         service_id_t *svcs;
    2186         size_t svcs_cnt = 0;
    2187         rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
    2188         if (rc != EOK || svcs_cnt == 0) {
    2189                 input_disconnect();
    2190                 return -1;
    2191         }
    2192        
    2193         for (size_t i = 0; i < svcs_cnt; ++i) {
    2194                 char *svc_name;
    2195                 rc = loc_service_get_name(svcs[i], &svc_name);
    2196                 if (rc == EOK) {
    2197                         viewport_t *vp = viewport_create(svc_name);
    2198                         if (vp != NULL) {
    2199                                 list_append(&vp->link, &viewport_list);
    2200                         }
    2201                 }
    2202         }
    2203        
    2204         if (list_empty(&viewport_list)) {
    2205                 input_disconnect();
    2206                 return -1;
    2207         }
    2208 
     2286                return rc;
     2287        }
     2288       
     2289        discover_viewports();
     2290       
    22092291        comp_restrict_pointers();
    22102292        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
Note: See TracChangeset for help on using the changeset viewer.