Ignore:
File:
1 edited

Legend:

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

    r2f6ad06 r3b98311  
    5555#include <async.h>
    5656#include <loc.h>
    57 #include <task.h>
    58 
     57#include <devman.h>
     58
     59#include <event.h>
     60#include <device/graph_dev.h>
    5961#include <io/keycode.h>
    6062#include <io/mode.h>
    6163#include <io/visualizer.h>
    6264#include <io/window.h>
    63 #include <io/console.h>
    6465
    6566#include <transform.h>
     
    7172#include <codec/tga.h>
    7273
     74#include "images.h"
    7375#include "compositor.h"
    7476
     
    8587static sysarg_t coord_origin;
    8688static pixel_t bg_color;
    87 static filter_t filter = filter_bilinear;
    88 static unsigned int filter_index = 1;
    8989
    9090typedef struct {
    9191        link_t link;
    9292        atomic_t ref_cnt;
    93         window_flags_t flags;
    9493        service_id_t in_dsid;
    9594        service_id_t out_dsid;
     
    144143static LIST_INITIALIZE(viewport_list);
    145144
    146 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);
    147 
    148145/** Input server proxy */
    149146static input_t *input;
    150 static bool active = false;
    151 
    152 static int comp_active(input_t *);
    153 static int comp_deactive(input_t *);
     147
    154148static int comp_key_press(input_t *, kbd_event_type_t, keycode_t, keymod_t, wchar_t);
    155149static int comp_mouse_move(input_t *, int, int);
     
    158152
    159153static input_ev_ops_t input_ev_ops = {
    160         .active = comp_active,
    161         .deactive = comp_deactive,
    162154        .key = comp_key_press,
    163155        .move = comp_mouse_move,
     
    166158};
    167159
     160static void input_disconnect(void);
     161
     162
    168163static pointer_t *input_pointer(input_t *input)
    169164{
     
    171166}
    172167
    173 static pointer_t *pointer_create(void)
     168static pointer_t *pointer_create()
    174169{
    175170        pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
    176         if (!p)
     171        if (!p) {
    177172                return NULL;
    178        
     173        }
     174
    179175        link_initialize(&p->link);
    180176        p->pos.x = coord_origin;
     
    188184        p->state = 0;
    189185        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    190        
     186
    191187        /* Ghost window for transformation animation. */
    192188        transform_identity(&p->ghost.transform);
     
    201197        p->accum_ghost.x = 0;
    202198        p->accum_ghost.y = 0;
    203        
     199
    204200        return p;
    205201}
     
    213209}
    214210
    215 static window_t *window_create(void)
     211static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
    216212{
    217213        window_t *win = (window_t *) malloc(sizeof(window_t));
    218         if (!win)
     214        if (!win) {
    219215                return NULL;
    220        
     216        }
     217
    221218        link_initialize(&win->link);
    222219        atomic_set(&win->ref_cnt, 0);
    223220        prodcons_initialize(&win->queue);
    224221        transform_identity(&win->transform);
    225         transform_translate(&win->transform, coord_origin, coord_origin);
    226         win->dx = coord_origin;
    227         win->dy = coord_origin;
     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;
    228226        win->fx = 1;
    229227        win->fy = 1;
     
    231229        win->opacity = 255;
    232230        win->surface = NULL;
    233        
     231
    234232        return win;
    235233}
     
    237235static void window_destroy(window_t *win)
    238236{
    239         if ((win) && (atomic_get(&win->ref_cnt) == 0)) {
     237        if (win && atomic_get(&win->ref_cnt) == 0) {
    240238                while (!list_empty(&win->queue.list)) {
    241239                        window_event_t *event = (window_event_t *) list_first(&win->queue.list);
     
    243241                        free(event);
    244242                }
    245                
    246                 if (win->surface)
     243
     244                if (win->surface) {
    247245                        surface_destroy(win->surface);
    248                
     246                }
    249247                free(win);
    250248        }
     
    258256        transform_invert(&win_trans);
    259257        transform_apply_affine(&win_trans, &x, &y);
    260        
    261         /*
    262          * Since client coordinate origin is (0, 0), it is necessary to check
     258
     259        /* Since client coordinate origin is (0, 0), it is necessary to check
    263260         * coordinates to avoid underflow. Moreover, it is convenient to also
    264261         * check against provided upper limits to determine whether the converted
    265          * coordinates are within the client window.
    266          */
    267         if ((x < 0) || (y < 0))
     262         * coordinates are within the client window.  */
     263        if (x < 0 || y < 0) {
    268264                return false;
    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;
     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        }
    277275}
    278276
     
    284282        transform_apply_affine(&win_trans, &x, &y);
    285283       
    286         /*
    287          * It is assumed that compositor coordinate origin is chosen in such way,
    288          * that underflow/overflow here would be unlikely.
    289          */
     284        /* It is assumed that compositor coordinate origin is chosen in such way,
     285         * that underflow/overflow here would be unlikely. */
    290286        (*x_out) = (sysarg_t) (x + 0.5);
    291287        (*y_out) = (sysarg_t) (y + 0.5);
     
    296292    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    297293{
    298         if ((w_in > 0) && (h_in > 0)) {
     294        if (w_in > 0 && h_in > 0) {
    299295                sysarg_t x[4];
    300296                sysarg_t y[4];
    301                
    302297                comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
    303298                comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
    304299                comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
    305300                comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
    306                
    307301                (*x_out) = x[0];
    308302                (*y_out) = y[0];
    309303                (*w_out) = x[0];
    310304                (*h_out) = y[0];
    311                
    312                 for (unsigned int i = 1; i < 4; ++i) {
     305                for (int i = 1; i < 4; ++i) {
    313306                        (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
    314307                        (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
     
    316309                        (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
    317310                }
    318                
    319311                (*w_out) = (*w_out) - (*x_out) + 1;
    320312                (*h_out) = (*h_out) - (*y_out) + 1;
     
    327319}
    328320
    329 static void comp_update_viewport_bound_rect(void)
     321static void comp_restrict_pointers(void)
    330322{
    331323        fibril_mutex_lock(&viewport_list_mtx);
    332        
     324
    333325        sysarg_t x_res = coord_origin;
    334326        sysarg_t y_res = coord_origin;
    335327        sysarg_t w_res = 0;
    336328        sysarg_t h_res = 0;
    337        
     329
    338330        if (!list_empty(&viewport_list)) {
    339331                viewport_t *vp = (viewport_t *) list_first(&viewport_list);
     
    342334                surface_get_resolution(vp->surface, &w_res, &h_res);
    343335        }
    344        
    345         list_foreach(viewport_list, link, viewport_t, vp) {
     336
     337        list_foreach(viewport_list, link) {
     338                viewport_t *vp = list_get_instance(link, viewport_t, link);
    346339                sysarg_t w_vp, h_vp;
    347340                surface_get_resolution(vp->surface, &w_vp, &h_vp);
    348                 rectangle_union(x_res, y_res, w_res, h_res,
     341                rectangle_union(
     342                    x_res, y_res, w_res, h_res,
    349343                    vp->pos.x, vp->pos.y, w_vp, h_vp,
    350344                    &x_res, &y_res, &w_res, &h_res);
    351345        }
    352        
     346
    353347        viewport_bound_rect.x = x_res;
    354348        viewport_bound_rect.y = y_res;
    355349        viewport_bound_rect.w = w_res;
    356350        viewport_bound_rect.h = h_res;
    357        
     351
    358352        fibril_mutex_unlock(&viewport_list_mtx);
    359 }
    360 
    361 static void comp_restrict_pointers(void)
    362 {
    363         comp_update_viewport_bound_rect();
    364        
     353
    365354        fibril_mutex_lock(&pointer_list_mtx);
    366        
    367         list_foreach(pointer_list, link, pointer_t, ptr) {
     355
     356        list_foreach(pointer_list, link) {
     357                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    368358                ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
    369359                ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
     
    373363                    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
    374364        }
    375        
     365
    376366        fibril_mutex_unlock(&pointer_list_mtx);
    377367}
     
    384374        fibril_mutex_lock(&pointer_list_mtx);
    385375
    386         list_foreach(viewport_list, link, viewport_t, vp) {
     376        list_foreach(viewport_list, link) {
     377
    387378                /* Determine what part of the viewport must be updated. */
     379                viewport_t *vp = list_get_instance(link, viewport_t, link);
    388380                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    389381                surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
     
    412404
    413405                        source_init(&source);
    414                         source_set_filter(&source, filter);
     406                        source_set_filter(&source, filter_nearest);
    415407                        drawctx_init(&context, vp->surface);
    416408                        drawctx_set_compose(&context, compose_over);
     
    445437                                        transform_translate(&transform, -pos.x, -pos.y);
    446438
    447                                         source_set_transform(&source, transform);
    448                                         source_set_texture(&source, win->surface,
    449                                             PIXELMAP_EXTEND_TRANSPARENT_SIDES);
     439                                        source_set_transform(&source, transform);                               
     440                                        source_set_texture(&source, win->surface, false);
    450441                                        source_set_alpha(&source, PIXEL(win->opacity, 0, 0, 0));
    451442
     
    455446                        }
    456447
    457                         list_foreach(pointer_list, link, pointer_t, ptr) {
     448                        list_foreach(pointer_list, link) {
     449
     450                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    458451                                if (ptr->ghost.surface) {
    459452
     
    529522                        }
    530523
    531                         list_foreach(pointer_list, link, pointer_t, ptr) {
     524                        list_foreach(pointer_list, link) {
    532525
    533526                                /* Determine what part of the pointer intersects with the
    534527                                 * updated area of the current viewport. */
     528                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    535529                                sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
    536530                                surface_t *sf_ptr = ptr->cursor.states[ptr->state];
     
    575569
    576570        /* Notify visualizers about updated regions. */
    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        
     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
    587580        fibril_mutex_unlock(&viewport_list_mtx);
    588581}
     
    600593                return;
    601594        }
    602        
    603595        int rc = async_data_read_finalize(callid, event, len);
    604596        if (rc != EOK) {
     
    607599                return;
    608600        }
    609        
    610601        async_answer_0(iid, EOK);
     602       
    611603        free(event);
    612604}
     
    619611        double height = IPC_GET_ARG4(*icall);
    620612
    621         if ((width == 0) || (height == 0)) {
     613        if (width == 0 || height == 0) {
    622614                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    623615        } else {
     
    637629        sysarg_t pos_id = IPC_GET_ARG1(*icall);
    638630        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);
    646631
    647632        fibril_mutex_lock(&pointer_list_mtx);
    648         list_foreach(pointer_list, link, pointer_t, pointer) {
     633        list_foreach(pointer_list, link) {
     634                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    649635                if (pointer->id == pos_id) {
    650636                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     
    663649}
    664650
    665 static 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 
    694651static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    695652{
     653        int rc;
     654
    696655        ipc_callid_t callid;
    697656        size_t size;
    698657        unsigned int flags;
    699        
     658
    700659        /* Start sharing resized window with client. */
    701660        if (!async_share_out_receive(&callid, &size, &flags)) {
     
    703662                return;
    704663        }
    705        
    706664        void *new_cell_storage;
    707         int rc = async_share_out_finalize(callid, &new_cell_storage);
     665        rc = async_share_out_finalize(callid, &new_cell_storage);
    708666        if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
    709667                async_answer_0(iid, ENOMEM);
    710668                return;
    711669        }
    712        
     670
    713671        /* Create new surface for the resized window. */
    714         surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
    715             IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
     672        surface_t *new_surface = surface_create(
     673            IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
     674            new_cell_storage, SURFACE_FLAG_SHARED);
    716675        if (!new_surface) {
    717676                as_area_destroy(new_cell_storage);
     
    719678                return;
    720679        }
    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        
     680
    729681        /* Switch new surface with old surface and calculate damage. */
    730682        fibril_mutex_lock(&window_list_mtx);
    731        
     683
    732684        sysarg_t old_width = 0;
    733685        sysarg_t old_height = 0;
    734        
    735686        if (win->surface) {
    736687                surface_get_resolution(win->surface, &old_width, &old_height);
    737688                surface_destroy(win->surface);
    738689        }
    739        
     690
    740691        win->surface = new_surface;
    741        
     692
    742693        sysarg_t new_width = 0;
    743694        sysarg_t new_height = 0;
    744695        surface_get_resolution(win->surface, &new_width, &new_height);
    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        
     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
    801702        fibril_mutex_unlock(&window_list_mtx);
    802        
     703
    803704        comp_damage(x, y, width, height);
    804        
     705
    805706        async_answer_0(iid, EOK);
    806707}
     
    809710{
    810711        fibril_mutex_lock(&window_list_mtx);
    811        
    812         list_foreach(window_list, link, window_t, window) {
     712        window_t *window = NULL;
     713        list_foreach(window_list, link) {
     714                window = list_get_instance(link, window_t, link);
    813715                if (window == target) {
    814716                        prodcons_produce(&window->queue, &event->link);
    815                         fibril_mutex_unlock(&window_list_mtx);
    816                         return;
    817                 }
    818         }
    819        
     717                }
     718        }
     719        if (!window) {
     720                free(event);
     721        }
    820722        fibril_mutex_unlock(&window_list_mtx);
    821         free(event);
    822723}
    823724
     
    825726{
    826727        fibril_mutex_lock(&window_list_mtx);
    827        
    828728        window_t *win = (window_t *) list_first(&window_list);
    829         if (win)
     729        if (win) {
    830730                prodcons_produce(&win->queue, &event->link);
    831         else
     731        } else {
    832732                free(event);
    833        
     733        }
    834734        fibril_mutex_unlock(&window_list_mtx);
    835735}
     
    875775
    876776        comp_damage(x, y, width, height);
     777
    877778        async_answer_0(iid, EOK);
    878779}
     
    880781static void comp_window_close_request(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    881782{
    882         window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     783    window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    883784        if (event == NULL) {
    884785                async_answer_0(iid, ENOMEM);
     
    897798        ipc_call_t call;
    898799        ipc_callid_t callid;
    899         service_id_t service_id = (service_id_t) IPC_GET_ARG2(*icall);
     800        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*icall);
    900801
    901802        /* Allocate resources for new window and register it to the location service. */
     
    907808                        fibril_mutex_lock(&window_list_mtx);
    908809
    909                         window_t *win = window_create();
     810                        window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    910811                        if (!win) {
    911812                                async_answer_2(callid, ENOMEM, 0, 0);
    912813                                return;
    913814                        }
    914                        
    915                         win->flags = IPC_GET_ARG1(call);
    916815
    917816                        char name_in[LOC_NAME_MAXLEN + 1];
     
    964863        window_t *win = NULL;
    965864        fibril_mutex_lock(&window_list_mtx);
    966         list_foreach(window_list, link, window_t, cur) {
     865        list_foreach(window_list, link) {
     866                window_t *cur = list_get_instance(link, window_t, link);
    967867                if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
    968868                        win = cur;
     
    1022922                                break;
    1023923                        case WINDOW_CLOSE:
    1024                                 /*
    1025                                  * Postpone the closing until the phone is hung up to cover
    1026                                  * the case when the client is killed abruptly.
    1027                                  */
     924                                /* Postpone the closing until the phone is hung up to cover
     925                                 * the case when the client is killed abruptly. */
    1028926                                async_answer_0(callid, EOK);
    1029927                                break;
     
    1040938static void comp_mode_change(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    1041939{
     940        int rc;
    1042941        sysarg_t mode_idx = IPC_GET_ARG2(*icall);
    1043942        fibril_mutex_lock(&viewport_list_mtx);
     
    1045944        /* Retrieve the mode that shall be set. */
    1046945        vslmode_t new_mode;
    1047         int rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
     946        rc = visualizer_get_mode(vp->sess, &new_mode, mode_idx);
    1048947        if (rc != EOK) {
    1049948                fibril_mutex_unlock(&viewport_list_mtx);
     
    1063962        /* Try to set the mode and share out the surface. */
    1064963        rc = visualizer_set_mode(vp->sess,
    1065             new_mode.index, new_mode.version, surface_direct_access(new_surface));
     964                new_mode.index, new_mode.version, surface_direct_access(new_surface));
    1066965        if (rc != EOK) {
    1067966                surface_destroy(new_surface);
     
    1093992}
    1094993
    1095 #if 0
    1096 static 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 
    1119994static void comp_visualizer_disconnect(viewport_t *vp, ipc_callid_t iid, ipc_call_t *icall)
    1120995{
    1121996        /* Release viewport resources. */
    1122997        fibril_mutex_lock(&viewport_list_mtx);
    1123        
    1124998        list_remove(&vp->link);
    1125999        viewport_destroy(vp);
    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);
     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        }
    11331030}
    11341031
     
    11371034        viewport_t *vp = NULL;
    11381035        fibril_mutex_lock(&viewport_list_mtx);
    1139         list_foreach(viewport_list, link, viewport_t, cur) {
     1036        list_foreach(viewport_list, link) {
     1037                viewport_t *cur = list_get_instance(link, viewport_t, link);
    11401038                if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
    11411039                        vp = cur;
     
    11451043        fibril_mutex_unlock(&viewport_list_mtx);
    11461044
    1147         if (!vp)
     1045        if (!vp) {
    11481046                return;
     1047        }
    11491048
    11501049        /* Ignore parameters, the connection is already opened. */
     
    11711070}
    11721071
    1173 static async_sess_t *vsl_connect(service_id_t sid, const char *svc)
     1072static async_sess_t *vsl_connect(const char *svc)
    11741073{
    11751074        int rc;
    11761075        async_sess_t *sess;
    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);
     1076        service_id_t dsid;
     1077        devman_handle_t handle;
     1078
     1079        rc = loc_service_get_id(svc, &dsid, 0);
     1080        if (rc != EOK) {
    11811081                return NULL;
    11821082        }
    11831083
     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
    11841105        async_exch_t *exch = async_exchange_begin(sess);
    1185        
    1186         port_id_t port;
    1187         rc = async_create_callback_port(exch, INTERFACE_VISUALIZER_CB, 0, 0,
    1188             vsl_notifications, NULL, &port);
    1189        
     1106        rc = async_connect_to_me(exch, dsid, 0, 0, vsl_notifications, NULL);
    11901107        async_exchange_end(exch);
    11911108
     
    12001117}
    12011118
    1202 static viewport_t *viewport_create(service_id_t sid)
     1119static viewport_t *viewport_create(const char *vsl_name)
    12031120{
    12041121        int rc;
    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;
     1122
     1123        viewport_t *vp = (viewport_t *) malloc(sizeof(viewport_t));
     1124        if (!vp) {
     1125                return NULL;
     1126        }
    12161127
    12171128        link_initialize(&vp->link);
     
    12201131
    12211132        /* Establish output bidirectional connection. */
    1222         vp->dsid = sid;
    1223         vp->sess = vsl_connect(sid, vsl_name);
    1224         if (vp->sess == NULL)
    1225                 goto error;
     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        }
    12261139
    12271140        /* Claim the given visualizer. */
    12281141        rc = visualizer_claim(vp->sess, 0);
    12291142        if (rc != EOK) {
     1143                async_hangup(vp->sess);
     1144                free(vp);
    12301145                printf("%s: Unable to claim visualizer (%s)\n", NAME, str_error(rc));
    1231                 goto error;
    1232         }
    1233 
    1234         claimed = true;
     1146                return NULL;
     1147        }
    12351148
    12361149        /* Retrieve the default mode. */
    12371150        rc = visualizer_get_default_mode(vp->sess, &vp->mode);
    12381151        if (rc != EOK) {
     1152                visualizer_yield(vp->sess);
     1153                async_hangup(vp->sess);
     1154                free(vp);
    12391155                printf("%s: Unable to retrieve mode (%s)\n", NAME, str_error(rc));
    1240                 goto error;
     1156                return NULL;
    12411157        }
    12421158
     
    12451161            NULL, SURFACE_FLAG_SHARED);
    12461162        if (vp->surface == NULL) {
     1163                visualizer_yield(vp->sess);
     1164                async_hangup(vp->sess);
     1165                free(vp);
    12471166                printf("%s: Unable to create surface (%s)\n", NAME, str_error(rc));
    1248                 goto error;
     1167                return NULL;
    12491168        }
    12501169
    12511170        /* Try to set the mode and share out the surface. */
    12521171        rc = visualizer_set_mode(vp->sess,
    1253             vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
     1172                vp->mode.index, vp->mode.version, surface_direct_access(vp->surface));
    12541173        if (rc != EOK) {
     1174                visualizer_yield(vp->sess);
     1175                surface_destroy(vp->surface);
     1176                async_hangup(vp->sess);
     1177                free(vp);
    12551178                printf("%s: Unable to set mode (%s)\n", NAME, str_error(rc));
    1256                 goto error;
     1179                return NULL;
    12571180        }
    12581181
    12591182        return vp;
    1260 error:
    1261         if (claimed)
    1262                 visualizer_yield(vp->sess);
    1263        
    1264         if (vp->sess != NULL)
    1265                 async_hangup(vp->sess);
    1266        
    1267         free(vp);
    1268         free(vsl_name);
    1269         return NULL;
     1183}
     1184
     1185static 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;
    12701215}
    12711216
     
    12911236                double cx = 0;
    12921237                double cy = 0;
    1293                
    1294                 if (pointer->grab_flags & GF_MOVE_X)
     1238                if (pointer->grab_flags & GF_MOVE_X) {
    12951239                        cx = 1;
    1296                
    1297                 if (pointer->grab_flags & GF_MOVE_Y)
     1240                }
     1241                if (pointer->grab_flags & GF_MOVE_Y) {
    12981242                        cy = 1;
    1299                
    1300                 if (((scale) || (resize)) && (win->angle != 0)) {
     1243                }
     1244
     1245                if ((scale || resize) && (win->angle != 0)) {
    13011246                        transform_t rotate;
    13021247                        transform_identity(&rotate);
    1303                        
    13041248                        transform_rotate(&rotate, win->angle);
    13051249                        transform_apply_linear(&rotate, &cx, &cy);
    13061250                }
    13071251               
    1308                 cx = (cx < 0) ? (-1 * cx) : cx;
     1252                cx = (cx < 0) ? (-1 * cx) : cx; 
    13091253                cy = (cy < 0) ? (-1 * cy) : cy;
    1310                
     1254
    13111255                win->dx += (cx * dx);
    13121256                win->dy += (cy * dy);
    13131257        }
    13141258
    1315         if ((scale) || (resize)) {
     1259        if (scale || resize) {
    13161260                double _dx = dx;
    13171261                double _dy = dy;
     
    13291273                        if (fx > 0) {
    13301274#if ANIMATE_WINDOW_TRANSFORMS == 0
    1331                                 if (scale)
    1332                                         win->fx *= fx;
     1275                                if (scale) win->fx *= fx;
    13331276#endif
    13341277#if ANIMATE_WINDOW_TRANSFORMS == 1
     
    15111454{
    15121455        pointer_t *pointer = input_pointer(input);
    1513        
    1514         comp_update_viewport_bound_rect();
    1515        
     1456
    15161457        /* Update pointer position. */
    15171458        fibril_mutex_lock(&pointer_list_mtx);
    1518        
    15191459        desktop_point_t old_pos = pointer->pos;
    1520        
    15211460        sysarg_t cursor_width;
    15221461        sysarg_t cursor_height;
    1523         surface_get_resolution(pointer->cursor.states[pointer->state],
     1462        surface_get_resolution(pointer->cursor.states[pointer->state], 
    15241463             &cursor_width, &cursor_height);
    1525        
    1526         if (pointer->pos.x + dx < viewport_bound_rect.x)
     1464        if (pointer->pos.x + dx < viewport_bound_rect.x) {
    15271465                dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
    1528        
    1529         if (pointer->pos.y + dy < viewport_bound_rect.y)
     1466        }
     1467        if (pointer->pos.y + dy < viewport_bound_rect.y) {
    15301468                dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
    1531        
    1532         if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w)
     1469        }
     1470        if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
    15331471                dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
    1534        
    1535         if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h)
     1472        }
     1473        if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
    15361474                dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
    1537        
     1475        }
    15381476        pointer->pos.x += dx;
    15391477        pointer->pos.y += dy;
     
    15411479        comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
    15421480        comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
    1543        
     1481
    15441482        fibril_mutex_lock(&window_list_mtx);
    15451483        fibril_mutex_lock(&pointer_list_mtx);
     
    16331571
    16341572        /* Determine the window which the mouse click belongs to. */
    1635         list_foreach(window_list, link, window_t, cw) {
    1636                 win = cw;
     1573        list_foreach(window_list, link) {
     1574                win = list_get_instance(link, window_t, link);
    16371575                if (win->surface) {
    16381576                        surface_get_resolution(win->surface, &width, &height);
     
    17021640
    17031641#if ANIMATE_WINDOW_TRANSFORMS == 0
    1704                 sysarg_t pre_x = 0;
     1642                sysarg_t pre_x = 0; 
    17051643                sysarg_t pre_y = 0;
    17061644                sysarg_t pre_width = 0;
     
    17341672                                link_initialize(&event_top->link);
    17351673                                event_top->type = ET_WINDOW_RESIZE;
    1736                                
    1737                                 event_top->data.resize.offset_x = 0;
    1738                                 event_top->data.resize.offset_y = 0;
    1739                                
     1674
    17401675                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
    17411676                                int dy = (int) (((double) height) * (scale_back_y - 1.0));
    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;
     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                                }
    17571691                        }
    17581692
     
    18021736        }
    18031737
    1804         return EOK;
    1805 }
    1806 
    1807 static 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 
    1815 static int comp_deactive(input_t *input)
    1816 {
    1817         active = false;
    18181738        return EOK;
    18191739}
     
    18351755        bool viewport_change = (mods & KM_ALT) && (
    18361756            key == KC_O || key == KC_P);
    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 ||
     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 ||
    18411761            win_opacity || win_close || win_switch || viewport_move ||
    1842             viewport_change || kconsole_switch || filter_switch);
    1843 
    1844         if (key_filter) {
     1762            viewport_change || kconsole_switch || compositor_test);
     1763
     1764        if (filter) {
    18451765                /* no-op */
    18461766        } else if (win_transform) {
     
    18621782                                break;
    18631783                        case KC_Q:
    1864                                 win->angle += 0.1;
     1784                                win->angle += (PI / 2);
    18651785                                break;
    18661786                        case KC_E:
    1867                                 win->angle -= 0.1;
     1787                                win->angle += -(PI / 2);
    18681788                                break;
    18691789                        case KC_R:
     
    19001820                fibril_mutex_lock(&window_list_mtx);
    19011821                window_t *win = (window_t *) list_first(&window_list);
    1902                 if ((win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) {
     1822                if (win && win->surface) {
    19031823                        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    19041824                        if (event == NULL) {
     
    19061826                                return ENOMEM;
    19071827                        }
    1908                        
     1828
    19091829                        sysarg_t width, height;
    19101830                        surface_get_resolution(win->surface, &width, &height);
    1911                        
     1831
    19121832                        link_initialize(&event->link);
    19131833                        event->type = ET_WINDOW_RESIZE;
    1914                        
    1915                         event->data.resize.offset_x = 0;
    1916                         event->data.resize.offset_y = 0;
    1917                        
     1834
    19181835                        switch (key) {
    19191836                        case KC_T:
    1920                                 event->data.resize.width = width;
    1921                                 event->data.resize.height = (height >= 20) ? height - 20 : 0;
     1837                                event->data.rsz.width = width;
     1838                                event->data.rsz.height = (height >= 20) ? height - 20 : 0;
    19221839                                break;
    19231840                        case KC_G:
    1924                                 event->data.resize.width = width;
    1925                                 event->data.resize.height = height + 20;
     1841                                event->data.rsz.width = width;
     1842                                event->data.rsz.height = height + 20;
    19261843                                break;
    19271844                        case KC_B:
    1928                                 event->data.resize.width = (width >= 20) ? width - 20 : 0;;
    1929                                 event->data.resize.height = height;
     1845                                event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
     1846                                event->data.rsz.height = height;
    19301847                                break;
    19311848                        case KC_N:
    1932                                 event->data.resize.width = width + 20;
    1933                                 event->data.resize.height = height;
     1849                                event->data.rsz.width = width + 20;
     1850                                event->data.rsz.height = height;
    19341851                                break;
    19351852                        default:
    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                        
     1853                                event->data.rsz.width = 0;
     1854                                event->data.rsz.height = 0;
     1855                                break;
     1856                        }
     1857
    19431858                        fibril_mutex_unlock(&window_list_mtx);
    19441859                        comp_post_event_top(event);
     
    21082023                fibril_mutex_unlock(&viewport_list_mtx);
    21092024        } else if (kconsole_switch) {
    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                 }
     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);
    21222054                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    21232055        } else {
     
    21502082        }
    21512083
    2152         sess = loc_service_connect(dsid, INTERFACE_INPUT, 0);
     2084        sess = loc_service_connect(EXCHANGE_ATOMIC, dsid, 0);
    21532085        if (sess == NULL) {
    21542086                printf("%s: Unable to connect to input service %s\n", NAME,
     
    21892121}
    21902122
    2191 static 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        
    2229 ret:
    2230         fibril_mutex_unlock(&discovery_mtx);
    2231 }
    2232 
    2233 static void category_change_cb(void)
    2234 {
    2235         discover_viewports();
     2123static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
     2124{
     2125        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    22362126}
    22372127
     
    22422132       
    22432133        /* Color of the viewport background. Must be opaque. */
    2244         bg_color = PIXEL(255, 69, 51, 103);
     2134        bg_color = PIXEL(255, 75, 70, 75);
    22452135       
    22462136        /* Register compositor server. */
    2247         async_set_fallback_port_handler(client_connection, NULL);
    2248        
     2137        async_set_client_connection(client_connection);
    22492138        int rc = loc_server_register(NAME);
    22502139        if (rc != EOK) {
    22512140                printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
    22522141                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));
    22532150        }
    22542151       
     
    22722169                return -1;
    22732170        }
    2274        
     2171
    22752172        /* Establish input bidirectional connection. */
    22762173        rc = input_connect(input_svc);
     2174        if (rc != EOK)
     2175                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);
    22772180        if (rc != EOK) {
    2278                 printf("%s: Failed to connect to input service.\n", NAME);
    2279                 return rc;
    2280         }
    2281        
    2282         rc = loc_register_cat_change_cb(category_change_cb);
    2283         if (rc != EOK) {
    2284                 printf("%s: Failed to register category change callback\n", NAME);
    22852181                input_disconnect();
    2286                 return rc;
    2287         }
    2288        
    2289         discover_viewports();
    2290        
     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
    22912209        comp_restrict_pointers();
    22922210        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
Note: See TracChangeset for help on using the changeset viewer.