Ignore:
File:
1 edited

Legend:

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

    r071fefec r3b98311  
    5858
    5959#include <event.h>
    60 #include <graph_iface.h>
     60#include <device/graph_dev.h>
    6161#include <io/keycode.h>
    6262#include <io/mode.h>
     
    7272#include <codec/tga.h>
    7373
     74#include "images.h"
    7475#include "compositor.h"
    7576
     
    142143static LIST_INITIALIZE(viewport_list);
    143144
    144 static FIBRIL_MUTEX_INITIALIZE(discovery_mtx);
    145 
    146145/** Input server proxy */
    147146static input_t *input;
     
    161160static void input_disconnect(void);
    162161
     162
    163163static pointer_t *input_pointer(input_t *input)
    164164{
     
    166166}
    167167
    168 static pointer_t *pointer_create(void)
     168static pointer_t *pointer_create()
    169169{
    170170        pointer_t *p = (pointer_t *) malloc(sizeof(pointer_t));
    171         if (!p)
     171        if (!p) {
    172172                return NULL;
    173        
     173        }
     174
    174175        link_initialize(&p->link);
    175176        p->pos.x = coord_origin;
     
    183184        p->state = 0;
    184185        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    185        
     186
    186187        /* Ghost window for transformation animation. */
    187188        transform_identity(&p->ghost.transform);
     
    196197        p->accum_ghost.x = 0;
    197198        p->accum_ghost.y = 0;
    198        
     199
    199200        return p;
    200201}
     
    208209}
    209210
    210 static window_t *window_create(void)
     211static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
    211212{
    212213        window_t *win = (window_t *) malloc(sizeof(window_t));
    213         if (!win)
     214        if (!win) {
    214215                return NULL;
    215        
     216        }
     217
    216218        link_initialize(&win->link);
    217219        atomic_set(&win->ref_cnt, 0);
    218220        prodcons_initialize(&win->queue);
    219221        transform_identity(&win->transform);
    220         transform_translate(&win->transform, coord_origin, coord_origin);
    221         win->dx = coord_origin;
    222         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;
    223226        win->fx = 1;
    224227        win->fy = 1;
     
    226229        win->opacity = 255;
    227230        win->surface = NULL;
    228        
     231
    229232        return win;
    230233}
     
    289292    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    290293{
    291         if ((w_in > 0) && (h_in > 0)) {
     294        if (w_in > 0 && h_in > 0) {
    292295                sysarg_t x[4];
    293296                sysarg_t y[4];
    294                
    295297                comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
    296298                comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
    297299                comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
    298300                comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
    299                
    300301                (*x_out) = x[0];
    301302                (*y_out) = y[0];
    302303                (*w_out) = x[0];
    303304                (*h_out) = y[0];
    304                
    305                 for (unsigned int i = 1; i < 4; ++i) {
     305                for (int i = 1; i < 4; ++i) {
    306306                        (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
    307307                        (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
     
    309309                        (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
    310310                }
    311                
    312311                (*w_out) = (*w_out) - (*x_out) + 1;
    313312                (*h_out) = (*h_out) - (*y_out) + 1;
     
    320319}
    321320
    322 static void comp_update_viewport_bound_rect(void)
     321static void comp_restrict_pointers(void)
    323322{
    324323        fibril_mutex_lock(&viewport_list_mtx);
    325        
     324
    326325        sysarg_t x_res = coord_origin;
    327326        sysarg_t y_res = coord_origin;
    328327        sysarg_t w_res = 0;
    329328        sysarg_t h_res = 0;
    330        
     329
    331330        if (!list_empty(&viewport_list)) {
    332331                viewport_t *vp = (viewport_t *) list_first(&viewport_list);
     
    335334                surface_get_resolution(vp->surface, &w_res, &h_res);
    336335        }
    337        
    338         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);
    339339                sysarg_t w_vp, h_vp;
    340340                surface_get_resolution(vp->surface, &w_vp, &h_vp);
    341                 rectangle_union(x_res, y_res, w_res, h_res,
     341                rectangle_union(
     342                    x_res, y_res, w_res, h_res,
    342343                    vp->pos.x, vp->pos.y, w_vp, h_vp,
    343344                    &x_res, &y_res, &w_res, &h_res);
    344345        }
    345        
     346
    346347        viewport_bound_rect.x = x_res;
    347348        viewport_bound_rect.y = y_res;
    348349        viewport_bound_rect.w = w_res;
    349350        viewport_bound_rect.h = h_res;
    350        
     351
    351352        fibril_mutex_unlock(&viewport_list_mtx);
    352 }
    353 
    354 static void comp_restrict_pointers(void)
    355 {
    356         comp_update_viewport_bound_rect();
    357        
     353
    358354        fibril_mutex_lock(&pointer_list_mtx);
    359        
    360         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);
    361358                ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
    362359                ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
     
    366363                    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
    367364        }
    368        
     365
    369366        fibril_mutex_unlock(&pointer_list_mtx);
    370367}
     
    377374        fibril_mutex_lock(&pointer_list_mtx);
    378375
    379         list_foreach(viewport_list, link, viewport_t, vp) {
     376        list_foreach(viewport_list, link) {
     377
    380378                /* Determine what part of the viewport must be updated. */
     379                viewport_t *vp = list_get_instance(link, viewport_t, link);
    381380                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    382381                surface_get_resolution(vp->surface, &w_dmg_vp, &h_dmg_vp);
     
    447446                        }
    448447
    449                         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);
    450451                                if (ptr->ghost.surface) {
    451452
     
    521522                        }
    522523
    523                         list_foreach(pointer_list, link, pointer_t, ptr) {
     524                        list_foreach(pointer_list, link) {
    524525
    525526                                /* Determine what part of the pointer intersects with the
    526527                                 * updated area of the current viewport. */
     528                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
    527529                                sysarg_t x_dmg_ptr, y_dmg_ptr, w_dmg_ptr, h_dmg_ptr;
    528530                                surface_t *sf_ptr = ptr->cursor.states[ptr->state];
     
    567569
    568570        /* Notify visualizers about updated regions. */
    569         list_foreach(viewport_list, link, viewport_t, vp) {
     571        list_foreach(viewport_list, link) {
     572                viewport_t *vp = list_get_instance(link, viewport_t, link);
    570573                sysarg_t x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp;
    571574                surface_get_damaged_region(vp->surface, &x_dmg_vp, &y_dmg_vp, &w_dmg_vp, &h_dmg_vp);
     
    628631
    629632        fibril_mutex_lock(&pointer_list_mtx);
    630         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);
    631635                if (pointer->id == pos_id) {
    632636                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     
    645649}
    646650
    647 static void comp_recalc_transform(window_t *win)
    648 {
    649         transform_t translate;
    650         transform_identity(&translate);
    651         transform_translate(&translate, win->dx, win->dy);
    652        
    653         transform_t scale;
    654         transform_identity(&scale);
    655         if ((win->fx != 1) || (win->fy != 1))
    656                 transform_scale(&scale, win->fx, win->fy);
    657        
    658         transform_t rotate;
    659         transform_identity(&rotate);
    660         if (win->angle != 0)
    661                 transform_rotate(&rotate, win->angle);
    662        
    663         transform_t transform;
    664         transform_t temp;
    665         transform_identity(&transform);
    666         temp = transform;
    667         transform_product(&transform, &temp, &translate);
    668         temp = transform;
    669         transform_product(&transform, &temp, &rotate);
    670         temp = transform;
    671         transform_product(&transform, &temp, &scale);
    672        
    673         win->transform = transform;
    674 }
    675 
    676651static void comp_window_resize(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    677652{
     653        int rc;
     654
    678655        ipc_callid_t callid;
    679656        size_t size;
    680657        unsigned int flags;
    681        
     658
    682659        /* Start sharing resized window with client. */
    683660        if (!async_share_out_receive(&callid, &size, &flags)) {
     
    685662                return;
    686663        }
    687        
    688664        void *new_cell_storage;
    689         int rc = async_share_out_finalize(callid, &new_cell_storage);
     665        rc = async_share_out_finalize(callid, &new_cell_storage);
    690666        if ((rc != EOK) || (new_cell_storage == AS_MAP_FAILED)) {
    691667                async_answer_0(iid, ENOMEM);
    692668                return;
    693669        }
    694        
     670
    695671        /* Create new surface for the resized window. */
    696         surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
    697             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);
    698675        if (!new_surface) {
    699676                as_area_destroy(new_cell_storage);
     
    701678                return;
    702679        }
    703        
    704         sysarg_t offset_x = IPC_GET_ARG1(*icall);
    705         sysarg_t offset_y = IPC_GET_ARG2(*icall);
    706         window_placement_flags_t placement_flags =
    707             (window_placement_flags_t) IPC_GET_ARG5(*icall);
    708        
    709         comp_update_viewport_bound_rect();
    710        
     680
    711681        /* Switch new surface with old surface and calculate damage. */
    712682        fibril_mutex_lock(&window_list_mtx);
    713        
     683
    714684        sysarg_t old_width = 0;
    715685        sysarg_t old_height = 0;
    716        
    717686        if (win->surface) {
    718687                surface_get_resolution(win->surface, &old_width, &old_height);
    719688                surface_destroy(win->surface);
    720689        }
    721        
     690
    722691        win->surface = new_surface;
    723        
     692
    724693        sysarg_t new_width = 0;
    725694        sysarg_t new_height = 0;
    726695        surface_get_resolution(win->surface, &new_width, &new_height);
    727        
    728         if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
    729                 win->dx = viewport_bound_rect.x + viewport_bound_rect.w / 2 -
    730                     new_width / 2;
    731        
    732         if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
    733                 win->dy = viewport_bound_rect.y + viewport_bound_rect.h / 2 -
    734                     new_height / 2;
    735        
    736         if (placement_flags & WINDOW_PLACEMENT_LEFT)
    737                 win->dx = viewport_bound_rect.x;
    738        
    739         if (placement_flags & WINDOW_PLACEMENT_TOP)
    740                 win->dy = viewport_bound_rect.y;
    741        
    742         if (placement_flags & WINDOW_PLACEMENT_RIGHT)
    743                 win->dx = viewport_bound_rect.x + viewport_bound_rect.w -
    744                     new_width;
    745        
    746         if (placement_flags & WINDOW_PLACEMENT_BOTTOM)
    747                 win->dy = viewport_bound_rect.y + viewport_bound_rect.h -
    748                     new_height;
    749        
    750         if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_X)
    751                 win->dx = coord_origin + offset_x;
    752        
    753         if (placement_flags & WINDOW_PLACEMENT_ABSOLUTE_Y)
    754                 win->dy = coord_origin + offset_y;
    755        
    756         /* Transform the window and calculate damage. */
    757         sysarg_t x1;
    758         sysarg_t y1;
    759         sysarg_t width1;
    760         sysarg_t height1;
    761        
    762         comp_coord_bounding_rect(0, 0, old_width, old_height, win->transform,
    763             &x1, &y1, &width1, &height1);
    764        
    765         comp_recalc_transform(win);
    766        
    767         sysarg_t x2;
    768         sysarg_t y2;
    769         sysarg_t width2;
    770         sysarg_t height2;
    771        
    772         comp_coord_bounding_rect(0, 0, new_width, new_height, win->transform,
    773             &x2, &y2, &width2, &height2);
    774        
    775         sysarg_t x;
    776         sysarg_t y;
    777         sysarg_t width;
    778         sysarg_t height;
    779        
    780         rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
    781             &x, &y, &width, &height);
    782        
     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
    783702        fibril_mutex_unlock(&window_list_mtx);
    784        
     703
    785704        comp_damage(x, y, width, height);
    786        
     705
    787706        async_answer_0(iid, EOK);
    788707}
     
    791710{
    792711        fibril_mutex_lock(&window_list_mtx);
    793        
    794         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);
    795715                if (window == target) {
    796716                        prodcons_produce(&window->queue, &event->link);
    797                         fibril_mutex_unlock(&window_list_mtx);
    798                         return;
    799                 }
    800         }
    801        
     717                }
     718        }
     719        if (!window) {
     720                free(event);
     721        }
    802722        fibril_mutex_unlock(&window_list_mtx);
    803         free(event);
    804723}
    805724
     
    807726{
    808727        fibril_mutex_lock(&window_list_mtx);
    809        
    810728        window_t *win = (window_t *) list_first(&window_list);
    811         if (win)
     729        if (win) {
    812730                prodcons_produce(&win->queue, &event->link);
    813         else
     731        } else {
    814732                free(event);
    815        
     733        }
    816734        fibril_mutex_unlock(&window_list_mtx);
    817735}
     
    890808                        fibril_mutex_lock(&window_list_mtx);
    891809
    892                         window_t *win = window_create();
     810                        window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    893811                        if (!win) {
    894812                                async_answer_2(callid, ENOMEM, 0, 0);
     
    945863        window_t *win = NULL;
    946864        fibril_mutex_lock(&window_list_mtx);
    947         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);
    948867                if (cur->in_dsid == service_id || cur->out_dsid == service_id) {
    949868                        win = cur;
     
    10881007                /* Close all clients and their windows. */
    10891008                fibril_mutex_lock(&window_list_mtx);
    1090                 list_foreach(window_list, link, window_t, win) {
     1009                list_foreach(window_list, link) {
     1010                        window_t *win = list_get_instance(link, window_t, link);
    10911011                        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    10921012                        if (event) {
     
    11141034        viewport_t *vp = NULL;
    11151035        fibril_mutex_lock(&viewport_list_mtx);
    1116         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);
    11171038                if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
    11181039                        vp = cur;
     
    12621183}
    12631184
     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;
     1215}
     1216
    12641217static void comp_window_animate(pointer_t *pointer, window_t *win,
    12651218    sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
     
    12831236                double cx = 0;
    12841237                double cy = 0;
    1285                
    1286                 if (pointer->grab_flags & GF_MOVE_X)
     1238                if (pointer->grab_flags & GF_MOVE_X) {
    12871239                        cx = 1;
    1288                
    1289                 if (pointer->grab_flags & GF_MOVE_Y)
     1240                }
     1241                if (pointer->grab_flags & GF_MOVE_Y) {
    12901242                        cy = 1;
    1291                
    1292                 if (((scale) || (resize)) && (win->angle != 0)) {
     1243                }
     1244
     1245                if ((scale || resize) && (win->angle != 0)) {
    12931246                        transform_t rotate;
    12941247                        transform_identity(&rotate);
    1295                        
    12961248                        transform_rotate(&rotate, win->angle);
    12971249                        transform_apply_linear(&rotate, &cx, &cy);
    12981250                }
    12991251               
    1300                 cx = (cx < 0) ? (-1 * cx) : cx;
     1252                cx = (cx < 0) ? (-1 * cx) : cx; 
    13011253                cy = (cy < 0) ? (-1 * cy) : cy;
    1302                
     1254
    13031255                win->dx += (cx * dx);
    13041256                win->dy += (cy * dy);
    13051257        }
    13061258
    1307         if ((scale) || (resize)) {
     1259        if (scale || resize) {
    13081260                double _dx = dx;
    13091261                double _dy = dy;
     
    13211273                        if (fx > 0) {
    13221274#if ANIMATE_WINDOW_TRANSFORMS == 0
    1323                                 if (scale)
    1324                                         win->fx *= fx;
     1275                                if (scale) win->fx *= fx;
    13251276#endif
    13261277#if ANIMATE_WINDOW_TRANSFORMS == 1
     
    15031454{
    15041455        pointer_t *pointer = input_pointer(input);
    1505        
    1506         comp_update_viewport_bound_rect();
    1507        
     1456
    15081457        /* Update pointer position. */
    15091458        fibril_mutex_lock(&pointer_list_mtx);
    1510        
    15111459        desktop_point_t old_pos = pointer->pos;
    1512        
    15131460        sysarg_t cursor_width;
    15141461        sysarg_t cursor_height;
    1515         surface_get_resolution(pointer->cursor.states[pointer->state],
     1462        surface_get_resolution(pointer->cursor.states[pointer->state], 
    15161463             &cursor_width, &cursor_height);
    1517        
    1518         if (pointer->pos.x + dx < viewport_bound_rect.x)
     1464        if (pointer->pos.x + dx < viewport_bound_rect.x) {
    15191465                dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
    1520        
    1521         if (pointer->pos.y + dy < viewport_bound_rect.y)
     1466        }
     1467        if (pointer->pos.y + dy < viewport_bound_rect.y) {
    15221468                dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
    1523        
    1524         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) {
    15251471                dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
    1526        
    1527         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) {
    15281474                dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
    1529        
     1475        }
    15301476        pointer->pos.x += dx;
    15311477        pointer->pos.y += dy;
     
    15331479        comp_damage(old_pos.x, old_pos.y, cursor_width, cursor_height);
    15341480        comp_damage(old_pos.x + dx, old_pos.y + dy, cursor_width, cursor_height);
    1535        
     1481
    15361482        fibril_mutex_lock(&window_list_mtx);
    15371483        fibril_mutex_lock(&pointer_list_mtx);
     
    16251571
    16261572        /* Determine the window which the mouse click belongs to. */
    1627         list_foreach(window_list, link, window_t, cw) {
    1628                 win = cw;
     1573        list_foreach(window_list, link) {
     1574                win = list_get_instance(link, window_t, link);
    16291575                if (win->surface) {
    16301576                        surface_get_resolution(win->surface, &width, &height);
     
    16941640
    16951641#if ANIMATE_WINDOW_TRANSFORMS == 0
    1696                 sysarg_t pre_x = 0;
     1642                sysarg_t pre_x = 0; 
    16971643                sysarg_t pre_y = 0;
    16981644                sysarg_t pre_width = 0;
     
    17261672                                link_initialize(&event_top->link);
    17271673                                event_top->type = ET_WINDOW_RESIZE;
    1728                                
    1729                                 event_top->data.resize.offset_x = 0;
    1730                                 event_top->data.resize.offset_y = 0;
    1731                                
     1674
    17321675                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
    17331676                                int dy = (int) (((double) height) * (scale_back_y - 1.0));
    1734                                
    1735                                 if (pointer->grab_flags & GF_RESIZE_X)
    1736                                         event_top->data.resize.width =
    1737                                             ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    1738                                 else
    1739                                         event_top->data.resize.width = width;
    1740                                
    1741                                 if (pointer->grab_flags & GF_RESIZE_Y)
    1742                                         event_top->data.resize.height =
    1743                                             ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    1744                                 else
    1745                                         event_top->data.resize.height = height;
    1746                                
    1747                                 event_top->data.resize.placement_flags =
    1748                                     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                                }
    17491691                        }
    17501692
     
    18141756            key == KC_O || key == KC_P);
    18151757        bool kconsole_switch = (mods & KM_ALT) && (key == KC_M);
     1758        bool compositor_test = (mods & KM_ALT) && (key == KC_H);
    18161759
    18171760        bool filter = (type == KEY_RELEASE) && (win_transform || win_resize ||
    18181761            win_opacity || win_close || win_switch || viewport_move ||
    1819             viewport_change || kconsole_switch);
     1762            viewport_change || kconsole_switch || compositor_test);
    18201763
    18211764        if (filter) {
     
    18391782                                break;
    18401783                        case KC_Q:
    1841                                 win->angle += 0.1;
     1784                                win->angle += (PI / 2);
    18421785                                break;
    18431786                        case KC_E:
    1844                                 win->angle -= 0.1;
     1787                                win->angle += -(PI / 2);
    18451788                                break;
    18461789                        case KC_R:
     
    18831826                                return ENOMEM;
    18841827                        }
    1885                        
     1828
    18861829                        sysarg_t width, height;
    18871830                        surface_get_resolution(win->surface, &width, &height);
    1888                        
     1831
    18891832                        link_initialize(&event->link);
    18901833                        event->type = ET_WINDOW_RESIZE;
    1891                        
    1892                         event->data.resize.offset_x = 0;
    1893                         event->data.resize.offset_y = 0;
    1894                        
     1834
    18951835                        switch (key) {
    18961836                        case KC_T:
    1897                                 event->data.resize.width = width;
    1898                                 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;
    18991839                                break;
    19001840                        case KC_G:
    1901                                 event->data.resize.width = width;
    1902                                 event->data.resize.height = height + 20;
     1841                                event->data.rsz.width = width;
     1842                                event->data.rsz.height = height + 20;
    19031843                                break;
    19041844                        case KC_B:
    1905                                 event->data.resize.width = (width >= 20) ? width - 20 : 0;;
    1906                                 event->data.resize.height = height;
     1845                                event->data.rsz.width = (width >= 20) ? width - 20 : 0;;
     1846                                event->data.rsz.height = height;
    19071847                                break;
    19081848                        case KC_N:
    1909                                 event->data.resize.width = width + 20;
    1910                                 event->data.resize.height = height;
     1849                                event->data.rsz.width = width + 20;
     1850                                event->data.rsz.height = height;
    19111851                                break;
    19121852                        default:
    1913                                 event->data.resize.width = 0;
    1914                                 event->data.resize.height = 0;
    1915                                 break;
    1916                         }
    1917                        
    1918                         event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
    1919                        
     1853                                event->data.rsz.width = 0;
     1854                                event->data.rsz.height = 0;
     1855                                break;
     1856                        }
     1857
    19201858                        fibril_mutex_unlock(&window_list_mtx);
    19211859                        comp_post_event_top(event);
     
    20862024        } else if (kconsole_switch) {
    20872025                __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);
     2054                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    20882055        } else {
    20892056                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     
    21592126}
    21602127
    2161 static int discover_viewports(void)
    2162 {
     2128static int compositor_srv_init(char *input_svc, char *name)
     2129{
     2130        /* Coordinates of the central pixel. */
     2131        coord_origin = UINT32_MAX / 4;
     2132       
     2133        /* Color of the viewport background. Must be opaque. */
     2134        bg_color = PIXEL(255, 75, 70, 75);
     2135       
     2136        /* Register compositor server. */
     2137        async_set_client_connection(client_connection);
     2138        int rc = loc_server_register(NAME);
     2139        if (rc != EOK) {
     2140                printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
     2141                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));
     2150        }
     2151       
     2152        server_name = name;
     2153       
     2154        char svc[LOC_NAME_MAXLEN + 1];
     2155        snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);
     2156       
     2157        service_id_t service_id;
     2158        rc = loc_service_register(svc, &service_id);
     2159        if (rc != EOK) {
     2160                printf("%s: Unable to register service %s\n", NAME, svc);
     2161                return rc;
     2162        }
     2163       
     2164        /* Prepare window registrator (entrypoint for clients). */
     2165        char winreg[LOC_NAME_MAXLEN + 1];
     2166        snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);
     2167        if (loc_service_register(winreg, &winreg_id) != EOK) {
     2168                printf("%s: Unable to register service %s\n", NAME, winreg);
     2169                return -1;
     2170        }
     2171
     2172        /* Establish input bidirectional connection. */
     2173        rc = input_connect(input_svc);
     2174        if (rc != EOK)
     2175                return rc;
     2176
    21632177        /* Create viewports and connect them to visualizers. */
    21642178        category_id_t cat_id;
    2165         int rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
     2179        rc = loc_category_get_id("visualizer", &cat_id, IPC_FLAG_BLOCKING);
    21662180        if (rc != EOK) {
    2167                 printf("%s: Failed to get visualizer category.\n", NAME);
     2181                input_disconnect();
    21682182                return -1;
    21692183        }
     
    21732187        rc = loc_category_get_svcs(cat_id, &svcs, &svcs_cnt);
    21742188        if (rc != EOK || svcs_cnt == 0) {
    2175                 printf("%s: Failed to get visualizer category services.\n", NAME);
     2189                input_disconnect();
    21762190                return -1;
    21772191        }
    2178 
    2179         fibril_mutex_lock(&viewport_list_mtx); 
     2192       
    21802193        for (size_t i = 0; i < svcs_cnt; ++i) {
    2181                 bool exists = false;
    2182                 list_foreach(viewport_list, link, viewport_t, vp) {
    2183                         if (vp->dsid == svcs[i]) {
    2184                                 exists = true;
    2185                                 break;
    2186                         }
    2187                 }
    2188                
    2189                 if (exists)
    2190                         continue;
    2191                
    21922194                char *svc_name;
    21932195                rc = loc_service_get_name(svcs[i], &svc_name);
     
    21992201                }
    22002202        }
    2201         fibril_mutex_unlock(&viewport_list_mtx);
    2202        
    2203         /* TODO damage only newly added viewports */
    2204         comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2205         return EOK;
    2206 }
    2207 
    2208 static void category_change_cb(void)
    2209 {
    2210         fibril_mutex_lock(&discovery_mtx);
    2211         discover_viewports();
    2212         fibril_mutex_unlock(&discovery_mtx);
    2213 }
    2214 
    2215 static int compositor_srv_init(char *input_svc, char *name)
    2216 {
    2217         /* Coordinates of the central pixel. */
    2218         coord_origin = UINT32_MAX / 4;
    2219        
    2220         /* Color of the viewport background. Must be opaque. */
    2221         bg_color = PIXEL(255, 69, 51, 103);
    2222        
    2223         /* Register compositor server. */
    2224         async_set_client_connection(client_connection);
    2225         int rc = loc_server_register(NAME);
    2226         if (rc != EOK) {
    2227                 printf("%s: Unable to register server (%s)\n", NAME, str_error(rc));
    2228                 return -1;
    2229         }
    2230        
    2231         /* Register interrupt handler to switch back from kconsole. */
    2232         async_set_interrupt_received(interrupt_received);
    2233         rc = event_subscribe(EVENT_KCONSOLE, 0);
    2234         if (rc != EOK) {
    2235                 printf("%s: Failed to register kconsole notifications (%s)\n",
    2236                     NAME, str_error(rc));
    2237         }
    2238        
    2239         server_name = name;
    2240        
    2241         char svc[LOC_NAME_MAXLEN + 1];
    2242         snprintf(svc, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, server_name);
    2243        
    2244         service_id_t service_id;
    2245         rc = loc_service_register(svc, &service_id);
    2246         if (rc != EOK) {
    2247                 printf("%s: Unable to register service %s\n", NAME, svc);
    2248                 return rc;
    2249         }
    2250        
    2251         /* Prepare window registrator (entrypoint for clients). */
    2252         char winreg[LOC_NAME_MAXLEN + 1];
    2253         snprintf(winreg, LOC_NAME_MAXLEN, "%s%s/winreg", NAMESPACE, server_name);
    2254         if (loc_service_register(winreg, &winreg_id) != EOK) {
    2255                 printf("%s: Unable to register service %s\n", NAME, winreg);
    2256                 return -1;
    2257         }
    2258 
    2259         /* Establish input bidirectional connection. */
    2260         rc = input_connect(input_svc);
    2261         if (rc != EOK) {
    2262                 printf("%s: Failed to connect to input service.\n", NAME);
    2263                 return rc;
    2264         }
    2265 
    2266         rc = loc_register_cat_change_cb(category_change_cb);
    2267         if (rc != EOK) {
    2268                 printf("%s: Failed to register category change callback\n", NAME);
    2269                 input_disconnect();
    2270                 return rc;
    2271         }       
    2272 
    2273         rc = discover_viewports();
    2274         if (rc != EOK) {
    2275                 input_disconnect();
    2276                 return rc;
    2277         }
    22782203       
    22792204        if (list_empty(&viewport_list)) {
    2280                 printf("%s: Failed to get viewports.\n", NAME);
    22812205                input_disconnect();
    22822206                return -1;
     
    22852209        comp_restrict_pointers();
    22862210        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    2287        
    22882211       
    22892212        return EOK;
Note: See TracChangeset for help on using the changeset viewer.