Ignore:
File:
1 edited

Legend:

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

    r3e6a98c5 rd17a4a9  
    3434
    3535#include <sys/types.h>
    36 #include <stdbool.h>
     36#include <bool.h>
    3737#include <errno.h>
    3838#include <str_error.h>
     
    8787static sysarg_t coord_origin;
    8888static pixel_t bg_color;
     89
     90typedef struct {
     91        link_t link;
     92        sysarg_t id;
     93        uint8_t state;
     94        desktop_point_t pos;
     95        sysarg_t btn_num;
     96        desktop_point_t btn_pos;
     97        desktop_vector_t accum;
     98        sysarg_t grab_flags;
     99        bool pressed;
     100        cursor_t cursor;
     101} pointer_t;
     102
     103static sysarg_t pointer_id = 0;
     104static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
     105static LIST_INITIALIZE(pointer_list);
    89106
    90107typedef struct {
     
    112129typedef struct {
    113130        link_t link;
    114         sysarg_t id;
    115         uint8_t state;
    116         desktop_point_t pos;
    117         sysarg_t btn_num;
    118         desktop_point_t btn_pos;
    119         desktop_vector_t accum;
    120         sysarg_t grab_flags;
    121         bool pressed;
    122         cursor_t cursor;
    123         window_t ghost;
    124         desktop_vector_t accum_ghost;
    125 } pointer_t;
    126 
    127 static sysarg_t pointer_id = 0;
    128 static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
    129 static LIST_INITIALIZE(pointer_list);
    130 
    131 typedef struct {
    132         link_t link;
    133131        service_id_t dsid;
    134132        vslmode_t mode;
     
    183181        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    184182
    185         /* Ghost window for transformation animation. */
    186         transform_identity(&p->ghost.transform);
    187         transform_translate(&p->ghost.transform, coord_origin, coord_origin);
    188         p->ghost.dx = coord_origin;
    189         p->ghost.dy = coord_origin;
    190         p->ghost.fx = 1;
    191         p->ghost.fy = 1;
    192         p->ghost.angle = 0;
    193         p->ghost.opacity = 255;
    194         p->ghost.surface = NULL;
    195         p->accum_ghost.x = 0;
    196         p->accum_ghost.y = 0;
    197 
    198183        return p;
    199184}
     
    207192}
    208193
    209 static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
     194static window_t *window_create()
    210195{
    211196        window_t *win = (window_t *) malloc(sizeof(window_t));
     
    217202        prodcons_initialize(&win->queue);
    218203        transform_identity(&win->transform);
    219         transform_translate(&win->transform,
    220             coord_origin + x_offset, coord_origin + y_offset);
    221         win->dx = coord_origin + x_offset;
    222         win->dy = coord_origin + y_offset;
     204        transform_translate(&win->transform, coord_origin, coord_origin);
     205        win->dx = coord_origin;
     206        win->dy = coord_origin;
    223207        win->fx = 1;
    224208        win->fy = 1;
     
    266250}
    267251
    268 static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans,
     252static void comp_coord_from_client(sysarg_t x_in, sysarg_t y_in, transform_t win_trans,
    269253    sysarg_t *x_out, sysarg_t *y_out)
    270254{
     
    279263}
    280264
    281 static void comp_coord_bounding_rect(double x_in, double y_in,
    282     double w_in, double h_in, transform_t win_trans,
     265static void comp_coord_bounding_rect(sysarg_t x_in, sysarg_t y_in,
     266    sysarg_t w_in, sysarg_t h_in, transform_t win_trans,
    283267    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    284268{
    285         if (w_in > 0 && h_in > 0) {
    286                 sysarg_t x[4];
    287                 sysarg_t y[4];
    288                 comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
    289                 comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
    290                 comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
    291                 comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
    292                 (*x_out) = x[0];
    293                 (*y_out) = y[0];
    294                 (*w_out) = x[0];
    295                 (*h_out) = y[0];
    296                 for (int i = 1; i < 4; ++i) {
    297                         (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
    298                         (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
    299                         (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out);
    300                         (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
    301                 }
    302                 (*w_out) = (*w_out) - (*x_out) + 1;
    303                 (*h_out) = (*h_out) - (*y_out) + 1;
    304         } else {
    305                 (*x_out) = 0;
    306                 (*y_out) = 0;
    307                 (*w_out) = 0;
    308                 (*h_out) = 0;
    309         }
     269        sysarg_t x[4];
     270        sysarg_t y[4];
     271        comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
     272        comp_coord_from_client(x_in + w_in, y_in, win_trans, &x[1], &y[1]);
     273        comp_coord_from_client(x_in + w_in, y_in + h_in, win_trans, &x[2], &y[2]);
     274        comp_coord_from_client(x_in, y_in + h_in, win_trans, &x[3], &y[3]);
     275        (*x_out) = x[0];
     276        (*y_out) = y[0];
     277        (*w_out) = x[0];
     278        (*h_out) = y[0];
     279        for (int i = 1; i < 4; ++i) {
     280                (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
     281                (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
     282                (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out);
     283                (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
     284        }
     285        (*w_out) -= (*x_out);
     286        (*h_out) -= (*y_out);
    310287}
    311288
     
    332309                        /* Paint background color. */
    333310                        for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
    334                                 pixel_t *dst = pixelmap_pixel_at(
    335                                     surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y);
    336                                 sysarg_t count = w_dmg_vp;
    337                                 while (count-- != 0) {
    338                                         *dst++ = bg_color;
     311                                for (sysarg_t x = x_dmg_vp - vp->pos.x; x < x_dmg_vp - vp->pos.x + w_dmg_vp; ++x) {
     312                                        surface_put_pixel(vp->surface, x, y, bg_color);
    339313                                }
    340314                        }
    341                         surface_add_damaged_region(vp->surface,
    342                             x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp);
    343315
    344316                        transform_t transform;
     
    391363                        list_foreach(pointer_list, link) {
    392364
    393                                 pointer_t *ptr = list_get_instance(link, pointer_t, link);
    394                                 if (ptr->ghost.surface) {
    395 
    396                                         sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost;
    397                                         sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost;
    398                                         surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost);
    399                                         comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform,
    400                                             &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost);
    401                                         bool isec_ghost = rectangle_intersect(
    402                                             x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
    403                                             x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost,
    404                                             &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost);
    405 
    406                                         if (isec_ghost) {
    407                                                 /* FIXME: Ghost is currently drawn based on the bounding
    408                                                  * rectangle of the window, which is sufficient as long
    409                                                  * as the windows can be rotated only by 90 degrees.
    410                                                  * For ghost to be compatible with arbitrary-angle
    411                                                  * rotation, it should be drawn as four lines adjusted
    412                                                  * by the transformation matrix. That would however
    413                                                  * require to equip libdraw with line drawing functionality. */
    414 
    415                                                 transform_t transform = ptr->ghost.transform;
    416                                                 double_point_t pos;
    417                                                 pos.x = vp->pos.x;
    418                                                 pos.y = vp->pos.y;
    419                                                 transform_translate(&transform, -pos.x, -pos.y);
    420 
    421                                                 pixel_t ghost_color;
    422 
    423                                                 if (y_bnd_ghost == y_dmg_ghost) {
    424                                                         for (sysarg_t x = x_dmg_ghost - vp->pos.x;
    425                                                                     x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
    426                                                                 ghost_color = surface_get_pixel(vp->surface,
    427                                                                     x, y_dmg_ghost - vp->pos.y);
    428                                                                 surface_put_pixel(vp->surface,
    429                                                                     x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color));
    430                                                         }
    431                                                 }
    432 
    433                                                 if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) {
    434                                                         for (sysarg_t x = x_dmg_ghost - vp->pos.x;
    435                                                                     x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
    436                                                                 ghost_color = surface_get_pixel(vp->surface,
    437                                                                     x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1);
    438                                                                 surface_put_pixel(vp->surface,
    439                                                                     x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color));
    440                                                         }
    441                                                 }
    442 
    443                                                 if (x_bnd_ghost == x_dmg_ghost) {
    444                                                         for (sysarg_t y = y_dmg_ghost - vp->pos.y;
    445                                                                     y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
    446                                                                 ghost_color = surface_get_pixel(vp->surface,
    447                                                                     x_dmg_ghost - vp->pos.x, y);
    448                                                                 surface_put_pixel(vp->surface,
    449                                                                     x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color));
    450                                                         }
    451                                                 }
    452 
    453                                                 if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) {
    454                                                         for (sysarg_t y = y_dmg_ghost - vp->pos.y;
    455                                                                     y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
    456                                                                 ghost_color = surface_get_pixel(vp->surface,
    457                                                                     x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y);
    458                                                                 surface_put_pixel(vp->surface,
    459                                                                     x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color));
    460                                                         }
    461                                                 }
    462                                         }
    463 
    464                                 }
    465                         }
    466 
    467                         list_foreach(pointer_list, link) {
    468 
    469365                                /* Determine what part of the pointer intersects with the
    470366                                 * updated area of the current viewport. */
     
    480376                                if (isec_ptr) {
    481377                                        /* Pointer is currently painted directly by copying pixels.
    482                                          * However, it is possible to draw the pointer similarly
     378                                         * However, it is possible to draw the painter similarly
    483379                                         * as window by using drawctx_transfer. It would allow
    484380                                         * more sophisticated control over drawing, but would also
    485381                                         * cost more regarding the performance. */
    486382
     383                                        pixel_t pix = 0;
    487384                                        sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
    488385                                        sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
     
    491388
    492389                                        for (sysarg_t y = 0; y < h_dmg_ptr; ++y) {
    493                                                 pixel_t *src = pixelmap_pixel_at(
    494                                                     surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y);
    495                                                 pixel_t *dst = pixelmap_pixel_at(
    496                                                     surface_pixmap_access(vp->surface), x_vp, y_vp + y);
    497                                                 sysarg_t count = w_dmg_ptr;
    498                                                 while (count-- != 0) {
    499                                                         *dst = (*src & 0xff000000) ? *src : *dst;
    500                                                         ++dst; ++src;
     390                                                for (sysarg_t x = 0; x < w_dmg_ptr; ++x) {
     391                                                        pix = surface_get_pixel(sf_ptr, x_ptr + x, y_ptr + y);
     392                                                        if (ALPHA(pix) == 255) {
     393                                                                surface_put_pixel(vp->surface, x_vp + x, y_vp + y, pix);
     394                                                        }
    501395                                                }
    502396                                        }
    503                                         surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
    504397                                }
    505 
    506398                        }
    507399                }
     
    549441static void comp_window_damage(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    550442{
    551         double x = IPC_GET_ARG1(*icall);
    552         double y = IPC_GET_ARG2(*icall);
    553         double width = IPC_GET_ARG3(*icall);
    554         double height = IPC_GET_ARG4(*icall);
     443        sysarg_t x = IPC_GET_ARG1(*icall);
     444        sysarg_t y = IPC_GET_ARG2(*icall);
     445        sysarg_t width = IPC_GET_ARG3(*icall);
     446        sysarg_t height = IPC_GET_ARG4(*icall);
    555447
    556448        if (width == 0 || height == 0) {
     
    558450        } else {
    559451                fibril_mutex_lock(&window_list_mtx);
    560                 sysarg_t x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob;
    561                 comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2,
    562                     win->transform, &x_dmg_glob, &y_dmg_glob, &w_dmg_glob, &h_dmg_glob);
     452                comp_coord_bounding_rect(x, y, width, height,
     453                    win->transform, &x, &y, &width, &height);
    563454                fibril_mutex_unlock(&window_list_mtx);
    564                 comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob);
     455                comp_damage(x, y, width, height);
    565456        }
    566457
     
    577468                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    578469                if (pointer->id == pos_id) {
    579                         pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     470                        pointer->grab_flags = grab_flags;
    580471                        // TODO change pointer->state according to grab_flags
    581472                        break;
     
    650541}
    651542
    652 static void comp_post_event_win(window_event_t *event, window_t *target)
    653 {
    654         fibril_mutex_lock(&window_list_mtx);
    655         window_t *window = NULL;
    656         list_foreach(window_list, link) {
    657                 window = list_get_instance(link, window_t, link);
    658                 if (window == target) {
    659                         prodcons_produce(&window->queue, &event->link);
    660                 }
    661         }
    662         if (!window) {
    663                 free(event);
    664         }
    665         fibril_mutex_unlock(&window_list_mtx);
    666 }
    667 
    668 static void comp_post_event_top(window_event_t *event)
    669 {
    670         fibril_mutex_lock(&window_list_mtx);
    671         window_t *win = (window_t *) list_first(&window_list);
    672         if (win) {
    673                 prodcons_produce(&win->queue, &event->link);
    674         } else {
    675                 free(event);
    676         }
    677         fibril_mutex_unlock(&window_list_mtx);
    678 }
    679 
    680543static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    681544{
     
    683546        fibril_mutex_lock(&window_list_mtx);
    684547        list_remove(&win->link);
    685         window_t *win_focus = (window_t *) list_first(&window_list);
    686         window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t));
    687         if (event_focus) {
    688                 link_initialize(&event_focus->link);
    689                 event_focus->type = ET_WINDOW_FOCUS;
    690         }
    691548        fibril_mutex_unlock(&window_list_mtx);
    692 
    693         if (event_focus && win_focus) {
    694                 comp_post_event_win(event_focus, win_focus);
    695         }
    696549
    697550        /* Calculate damage. */
     
    748601                        fibril_mutex_lock(&window_list_mtx);
    749602
    750                         window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
     603                        window_t *win = window_create();
    751604                        if (!win) {
    752605                                async_answer_2(callid, ENOMEM, 0, 0);
     
    777630                        }
    778631
    779                         window_t *win_unfocus = (window_t *) list_first(&window_list);
    780632                        list_prepend(&win->link, &window_list);
    781 
    782                         window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
    783                         if (event_unfocus) {
    784                                 link_initialize(&event_unfocus->link);
    785                                 event_unfocus->type = ET_WINDOW_UNFOCUS;
    786                         }
    787633                       
    788634                        async_answer_2(callid, EOK, win->in_dsid, win->out_dsid);
    789635                        fibril_mutex_unlock(&window_list_mtx);
    790                        
    791                         if (event_unfocus && win_unfocus) {
    792                                 comp_post_event_win(event_unfocus, win_unfocus);
    793                         }
    794 
    795636                        return;
    796637                } else {
     
    1112953}
    1113954
     955static void comp_post_event(window_event_t *event)
     956{
     957        fibril_mutex_lock(&window_list_mtx);
     958        window_t *win = (window_t *) list_first(&window_list);
     959        if (win) {
     960                prodcons_produce(&win->queue, &event->link);
     961        } else {
     962                free(event);
     963        }
     964        fibril_mutex_unlock(&window_list_mtx);
     965}
     966
    1114967static void comp_recalc_transform(window_t *win)
    1115968{
     
    1120973        transform_t scale;
    1121974        transform_identity(&scale);
    1122         if (win->fx != 1 || win->fy != 1) {
    1123                 transform_scale(&scale, win->fx, win->fy);
    1124         }
     975        transform_scale(&scale, win->fx, win->fy);
    1125976
    1126977        transform_t rotate;
    1127978        transform_identity(&rotate);
    1128         if (win->angle != 0) {
    1129                 transform_rotate(&rotate, win->angle);
    1130         }
     979        transform_rotate(&rotate, win->angle);
    1131980
    1132981        transform_t transform;
     
    1145994
    1146995static void comp_window_animate(pointer_t *pointer, window_t *win,
    1147     sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
     996     sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
    1148997{
    1149998        /* window_list_mtx locked by caller */
    1150         /* pointer_list_mtx locked by caller */
    1151999
    11521000        int dx = pointer->accum.x;
     
    11721020                }
    11731021
    1174                 if ((scale || resize) && (win->angle != 0)) {
     1022                if (scale || resize) {
    11751023                        transform_t rotate;
    11761024                        transform_identity(&rotate);
     
    11891037                double _dx = dx;
    11901038                double _dy = dy;
    1191                 if (win->angle != 0) {
    1192                         transform_t unrotate;
    1193                         transform_identity(&unrotate);
    1194                         transform_rotate(&unrotate, -win->angle);
    1195                         transform_apply_linear(&unrotate, &_dx, &_dy);
    1196                 }
     1039                transform_t unrotate;
     1040                transform_identity(&unrotate);
     1041                transform_rotate(&unrotate, -win->angle);
     1042                transform_apply_linear(&unrotate, &_dx, &_dy);
    11971043                _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    11981044                _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    11991045
    12001046                if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1201                         double fx = 1.0 + (_dx / ((width - 1) * win->fx));
     1047                        double fx = 1.0 + (_dx / (width * win->fx));
    12021048                        if (fx > 0) {
    1203 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1204                                 if (scale) win->fx *= fx;
    1205 #endif
    1206 #if ANIMATE_WINDOW_TRANSFORMS == 1
    12071049                                win->fx *= fx;
    1208 #endif
    12091050                                scale_back_x *= fx;
    12101051                        }
     
    12121053
    12131054                if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1214                         double fy = 1.0 + (_dy / ((height - 1) * win->fy));
     1055                        double fy = 1.0 + (_dy / (height * win->fy));
    12151056                        if (fy > 0) {
    1216 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1217                                 if (scale) win->fy *= fy;
    1218 #endif
    1219 #if ANIMATE_WINDOW_TRANSFORMS == 1
    12201057                                win->fy *= fy;
    1221 #endif
    12221058                                scale_back_y *= fy;
    12231059                        }
     
    12351071            dmg_x, dmg_y, dmg_width, dmg_height);
    12361072}
    1237 
    1238 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1239 static void comp_ghost_animate(pointer_t *pointer,
    1240     desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4)
    1241 {
    1242         /* window_list_mtx locked by caller */
    1243         /* pointer_list_mtx locked by caller */
    1244 
    1245         int dx = pointer->accum_ghost.x;
    1246         int dy = pointer->accum_ghost.y;
    1247         pointer->accum_ghost.x = 0;
    1248         pointer->accum_ghost.y = 0;
    1249 
    1250         bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
    1251         bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y);
    1252         bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y);
    1253 
    1254         sysarg_t width, height;
    1255         surface_get_resolution(pointer->ghost.surface, &width, &height);
    1256 
    1257         if (move) {
    1258                 double cx = 0;
    1259                 double cy = 0;
    1260                 if (pointer->grab_flags & GF_MOVE_X) {
    1261                         cx = 1;
    1262                 }
    1263                 if (pointer->grab_flags & GF_MOVE_Y) {
    1264                         cy = 1;
    1265                 }
    1266 
    1267                 if (scale || resize) {
    1268                         transform_t rotate;
    1269                         transform_identity(&rotate);
    1270                         transform_rotate(&rotate, pointer->ghost.angle);
    1271                         transform_apply_linear(&rotate, &cx, &cy);
    1272                 }
    1273 
    1274                 cx = (cx < 0) ? (-1 * cx) : cx;
    1275                 cy = (cy < 0) ? (-1 * cy) : cy;
    1276 
    1277                 pointer->ghost.dx += (cx * dx);
    1278                 pointer->ghost.dy += (cy * dy);
    1279         }
    1280 
    1281         if (scale || resize) {
    1282                 double _dx = dx;
    1283                 double _dy = dy;
    1284                 transform_t unrotate;
    1285                 transform_identity(&unrotate);
    1286                 transform_rotate(&unrotate, -pointer->ghost.angle);
    1287                 transform_apply_linear(&unrotate, &_dx, &_dy);
    1288                 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    1289                 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    1290 
    1291                 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1292                         double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx));
    1293                         pointer->ghost.fx *= fx;
    1294                 }
    1295 
    1296                 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1297                         double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy));
    1298                         pointer->ghost.fy *= fy;
    1299                 }
    1300         }
    1301 
    1302         sysarg_t x1, y1, width1, height1;
    1303         sysarg_t x2, y2, width2, height2;
    1304         comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
    1305             &x1, &y1, &width1, &height1);
    1306         comp_recalc_transform(&pointer->ghost);
    1307         comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
    1308             &x2, &y2, &width2, &height2);
    1309 
    1310         sysarg_t x_u, y_u, w_u, h_u;
    1311         rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
    1312             &x_u, &y_u, &w_u, &h_u);
    1313 
    1314         sysarg_t x_i, y_i, w_i, h_i;
    1315         rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2,
    1316             &x_i, &y_i, &w_i, &h_i);
    1317 
    1318         if (w_i == 0 || h_i == 0) {
    1319                 rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0;
    1320                 rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0;
    1321                 rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0;
    1322                 rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0;
    1323         } else {
    1324                 rect1->x = x_u;
    1325                 rect1->y = y_u;
    1326                 rect1->w = x_i - x_u + 1;
    1327                 rect1->h = h_u;
    1328 
    1329                 rect2->x = x_u;
    1330                 rect2->y = y_u;
    1331                 rect2->w = w_u;
    1332                 rect2->h = y_i - y_u + 1;
    1333 
    1334                 rect3->x = x_i + w_i - 1;
    1335                 rect3->y = y_u;
    1336                 rect3->w = w_u - w_i - x_i + x_u + 1;
    1337                 rect3->h = h_u;
    1338                
    1339                 rect4->x = x_u;
    1340                 rect4->y = y_i + h_i - 1;
    1341                 rect4->w = w_u;
    1342                 rect4->h = h_u - h_i - y_i + y_u + 1;
    1343         }
    1344 }
    1345 #endif
    13461073
    13471074static int comp_abs_move(input_t *input, unsigned x , unsigned y,
     
    13981125
    13991126        fibril_mutex_lock(&window_list_mtx);
    1400         fibril_mutex_lock(&pointer_list_mtx);
    14011127        window_t *top = (window_t *) list_first(&window_list);
    14021128        if (top && top->surface) {
     
    14101136                        within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    14111137                            top->transform, width, height, &point_x, &point_y);
    1412 
    1413                         window_event_t *event = NULL;
     1138                        fibril_mutex_unlock(&window_list_mtx);
     1139
    14141140                        if (within_client) {
    1415                                 event = (window_event_t *) malloc(sizeof(window_event_t));
     1141                                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    14161142                                if (event) {
    14171143                                        link_initialize(&event->link);
     
    14221148                                        event->data.pos.hpos = point_x;
    14231149                                        event->data.pos.vpos = point_y;
     1150                                        comp_post_event(event);
    14241151                                }
    14251152                        }
    1426 
    1427                         fibril_mutex_unlock(&pointer_list_mtx);
    1428                         fibril_mutex_unlock(&window_list_mtx);
    1429 
    1430                         if (event) {
    1431                                 comp_post_event_top(event);
    1432                         }
    1433 
    14341153                } else {
    14351154                        /* Pointer is grabbed by top-level window action. */
    14361155                        pointer->accum.x += dx;
    14371156                        pointer->accum.y += dy;
    1438                         pointer->accum_ghost.x += dx;
    1439                         pointer->accum_ghost.y += dy;
    1440 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1441                         if (pointer->ghost.surface == NULL) {
    1442                                 pointer->ghost.surface = top->surface;
    1443                                 pointer->ghost.dx = top->dx;
    1444                                 pointer->ghost.dy = top->dy;
    1445                                 pointer->ghost.fx = top->fx;
    1446                                 pointer->ghost.fy = top->fy;
    1447                                 pointer->ghost.angle = top->angle;
    1448                                 pointer->ghost.transform = top->transform;
    1449                         }
    1450                         desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
    1451                         comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
    1452 #endif
    14531157#if ANIMATE_WINDOW_TRANSFORMS == 1
    14541158                        sysarg_t x, y, width, height;
    14551159                        comp_window_animate(pointer, top, &x, &y, &width, &height);
    14561160#endif
    1457                         fibril_mutex_unlock(&pointer_list_mtx);
    14581161                        fibril_mutex_unlock(&window_list_mtx);
    1459 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1460                         comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
    1461                         comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
    1462                         comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
    1463                         comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
    1464 #endif
    14651162#if ANIMATE_WINDOW_TRANSFORMS == 1
    14661163                        comp_damage(x, y, width, height);
     
    14681165                }
    14691166        } else {
    1470                 fibril_mutex_unlock(&pointer_list_mtx);
    14711167                fibril_mutex_unlock(&window_list_mtx);
    14721168        }
     
    14781174{
    14791175        pointer_t *pointer = input_pointer(input);
    1480 
    1481         fibril_mutex_lock(&window_list_mtx);
    1482         fibril_mutex_lock(&pointer_list_mtx);
    1483         window_t *win = NULL;
    1484         sysarg_t point_x = 0;
    1485         sysarg_t point_y = 0;
    1486         sysarg_t width, height;
    1487         bool within_client = false;
    1488 
    1489         /* Determine the window which the mouse click belongs to. */
    1490         list_foreach(window_list, link) {
    1491                 win = list_get_instance(link, window_t, link);
    1492                 if (win->surface) {
    1493                         surface_get_resolution(win->surface, &width, &height);
    1494                         within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    1495                             win->transform, width, height, &point_x, &point_y);
    1496                 }
    1497                 if (within_client) {
    1498                         break;
    1499                 }
    1500         }
    1501 
    1502         /* Check whether the window is top-level window. */
    1503         window_t *top = (window_t *) list_first(&window_list);
    1504         if (!win || !top) {
    1505                 fibril_mutex_unlock(&pointer_list_mtx);
    1506                 fibril_mutex_unlock(&window_list_mtx);
    1507                 return EOK;
    1508         }
    1509 
    1510         window_event_t *event_top = NULL;
    1511         window_event_t *event_unfocus = NULL;
    1512         window_t *win_unfocus = NULL;
    1513         sysarg_t dmg_x, dmg_y;
    1514         sysarg_t dmg_width = 0;
    1515         sysarg_t dmg_height = 0;
    1516        
    1517 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1518         desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
    1519 #endif
    15201176
    15211177        if (bpress) {
     
    15241180                pointer->pressed = true;
    15251181
    1526                 /* Bring the window to the foreground. */
    1527                 if ((win != top) && within_client) {
    1528                         win_unfocus = (window_t *) list_first(&window_list);
    1529                         list_remove(&win->link);
    1530                         list_prepend(&win->link, &window_list);
    1531                         event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
    1532                         if (event_unfocus) {
    1533                                 link_initialize(&event_unfocus->link);
    1534                                 event_unfocus->type = ET_WINDOW_UNFOCUS;
    1535                         }
    1536                         comp_coord_bounding_rect(0, 0, width, height, win->transform,
    1537                             &dmg_x, &dmg_y, &dmg_width, &dmg_height);
    1538                 }
    1539 
    1540                 /* Notify top-level window about mouse press. */
     1182                /* Check whether mouse press belongs to the top-level window. */
     1183                fibril_mutex_lock(&window_list_mtx);
     1184                window_t *win = (window_t *) list_first(&window_list);
     1185                if (!win || !win->surface) {
     1186                        fibril_mutex_unlock(&window_list_mtx);
     1187                        return EOK;
     1188                }
     1189                sysarg_t x, y, width, height;
     1190                surface_get_resolution(win->surface, &width, &height);
     1191                bool within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1192                    win->transform, width, height, &x, &y);
     1193                fibril_mutex_unlock(&window_list_mtx);
     1194
     1195                /* Send mouse press to the top-level window. */
    15411196                if (within_client) {
    1542                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1543                         if (event_top) {
    1544                                 link_initialize(&event_top->link);
    1545                                 event_top->type = ET_POSITION_EVENT;
    1546                                 event_top->data.pos.pos_id = pointer->id;
    1547                                 event_top->data.pos.type = POS_PRESS;
    1548                                 event_top->data.pos.btn_num = bnum;
    1549                                 event_top->data.pos.hpos = point_x;
    1550                                 event_top->data.pos.vpos = point_y;
    1551                         }
    1552                         pointer->grab_flags = GF_EMPTY;
    1553                 }
    1554 
     1197                        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     1198                        if (event) {
     1199                                link_initialize(&event->link);
     1200                                event->type = ET_POSITION_EVENT;
     1201                                event->data.pos.pos_id = pointer->id;
     1202                                event->data.pos.type = POS_PRESS;
     1203                                event->data.pos.btn_num = bnum;
     1204                                event->data.pos.hpos = x;
     1205                                event->data.pos.vpos = y;
     1206                                comp_post_event(event);
     1207                        } else {
     1208                                return ENOMEM;
     1209                        }
     1210                }
    15551211        } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
    15561212                pointer->pressed = false;
    15571213
    1558 #if ANIMATE_WINDOW_TRANSFORMS == 0
     1214                fibril_mutex_lock(&window_list_mtx);
     1215                window_t *win = NULL;
     1216                sysarg_t point_x = 0;
     1217                sysarg_t point_y = 0;
     1218                sysarg_t width, height;
     1219                bool within_client = false;
     1220
     1221                /* Determine the window which the mouse release belongs to. */
     1222                list_foreach(window_list, link) {
     1223                        win = list_get_instance(link, window_t, link);
     1224                        if (win->surface) {
     1225                                surface_get_resolution(win->surface, &width, &height);
     1226                                within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1227                                    win->transform, width, height, &point_x, &point_y);
     1228                        }
     1229                        if (within_client) {
     1230                                break;
     1231                        }
     1232                }
     1233
     1234                /* Check whether the window is top-level window. */
     1235                window_t *top = (window_t *) list_first(&window_list);
     1236                if (!win || !top) {
     1237                        pointer->grab_flags = GF_EMPTY;
     1238                        fibril_mutex_unlock(&window_list_mtx);
     1239                        return EOK;
     1240                }
     1241
     1242                window_event_t *event = NULL;
     1243                sysarg_t dmg_x, dmg_y;
     1244                sysarg_t dmg_width = 0;
     1245                sysarg_t dmg_height = 0;
     1246
    15591247                sysarg_t pre_x = 0;
    15601248                sysarg_t pre_y = 0;
     
    15621250                sysarg_t pre_height = 0;
    15631251
     1252#if ANIMATE_WINDOW_TRANSFORMS == 0
    15641253                if (pointer->grab_flags != GF_EMPTY) {
    1565                         if (pointer->ghost.surface) {
    1566                                 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
    1567                                 pointer->ghost.surface = NULL;
    1568                         }
    15691254                        comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height);
    15701255                        dmg_x = pre_x;
     
    15781263
    15791264                        surface_get_resolution(top->surface, &width, &height);
    1580 #if ANIMATE_WINDOW_TRANSFORMS == 1
    15811265                        top->fx *= (1.0 / scale_back_x);
    15821266                        top->fy *= (1.0 / scale_back_y);
    15831267                        comp_recalc_transform(top);
    1584 #endif
    15851268
    15861269                        /* Commit proper resize action. */
    1587                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1588                         if (event_top) {
    1589                                 link_initialize(&event_top->link);
    1590                                 event_top->type = ET_WINDOW_RESIZE;
     1270                        event = (window_event_t *) malloc(sizeof(window_event_t));
     1271                        if (event) {
     1272                                link_initialize(&event->link);
     1273                                event->type = ET_WINDOW_RESIZE;
    15911274
    15921275                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
     
    15941277
    15951278                                if (pointer->grab_flags & GF_RESIZE_X) {
    1596                                         event_top->data.rsz.width =
     1279                                        event->data.rsz.width =
    15971280                                                ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    15981281                                } else {
    1599                                         event_top->data.rsz.width = width;
     1282                                        event->data.rsz.width = width;
    16001283                                }
    16011284
    16021285                                if (pointer->grab_flags & GF_RESIZE_Y) {
    1603                                         event_top->data.rsz.height =
     1286                                        event->data.rsz.height =
    16041287                                                ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    16051288                                } else {
    1606                                         event_top->data.rsz.height = height;
     1289                                        event->data.rsz.height = height;
    16071290                                }
    16081291                        }
     
    16131296                       
    16141297                        /* Notify top-level window about mouse release. */
    1615                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1616                         if (event_top) {
    1617                                 link_initialize(&event_top->link);
    1618                                 event_top->type = ET_POSITION_EVENT;
    1619                                 event_top->data.pos.pos_id = pointer->id;
    1620                                 event_top->data.pos.type = POS_RELEASE;
    1621                                 event_top->data.pos.btn_num = bnum;
    1622                                 event_top->data.pos.hpos = point_x;
    1623                                 event_top->data.pos.vpos = point_y;
     1298                        event = (window_event_t *) malloc(sizeof(window_event_t));
     1299                        if (event) {
     1300                                link_initialize(&event->link);
     1301                                event->type = ET_POSITION_EVENT;
     1302                                event->data.pos.pos_id = pointer->id;
     1303                                event->data.pos.type = POS_RELEASE;
     1304                                event->data.pos.btn_num = bnum;
     1305                                event->data.pos.hpos = point_x;
     1306                                event->data.pos.vpos = point_y;
    16241307                        }
    16251308                        pointer->grab_flags = GF_EMPTY;
     1309                       
     1310                } else if (within_client && (pointer->grab_flags == GF_EMPTY) && (bnum == 1)) {
     1311
     1312                        /* Bring the window to the foreground. */
     1313                        list_remove(&win->link);
     1314                        list_prepend(&win->link, &window_list);
     1315                        comp_coord_bounding_rect(0, 0, width, height, win->transform,
     1316                            &dmg_x, &dmg_y, &dmg_width, &dmg_height);
    16261317                       
    16271318                } else {
     
    16291320                }
    16301321
    1631         }
    1632 
    1633         fibril_mutex_unlock(&pointer_list_mtx);
    1634         fibril_mutex_unlock(&window_list_mtx);
    1635 
    1636 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1637                 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
    1638                 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
    1639                 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
    1640                 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
    1641 #endif
    1642 
    1643         if (dmg_width > 0 && dmg_height > 0) {
    1644                 comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
    1645         }
    1646 
    1647         if (event_unfocus && win_unfocus) {
    1648                 comp_post_event_win(event_unfocus, win_unfocus);
    1649         }
    1650 
    1651         if (event_top) {
    1652                 comp_post_event_top(event_top);
     1322                fibril_mutex_unlock(&window_list_mtx);
     1323
     1324                if (dmg_width > 0 && dmg_height > 0) {
     1325                        comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
     1326                }
     1327
     1328                if (event) {
     1329                        comp_post_event(event);
     1330                }
    16531331        }
    16541332
     
    17741452
    17751453                        fibril_mutex_unlock(&window_list_mtx);
    1776                         comp_post_event_top(event);
     1454                        comp_post_event(event);
    17771455                } else {
    17781456                        fibril_mutex_unlock(&window_list_mtx);
     
    18161494                event->type = ET_WINDOW_CLOSE;
    18171495
    1818                 comp_post_event_top(event);
     1496                comp_post_event(event);
    18191497        } else if (win_switch) {
    18201498                fibril_mutex_lock(&window_list_mtx);
     
    18241502                        list_append(&win1->link, &window_list);
    18251503                        window_t *win2 = (window_t *) list_first(&window_list);
    1826 
    1827                         window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t));
    1828                         if (event1) {
    1829                                 link_initialize(&event1->link);
    1830                                 event1->type = ET_WINDOW_UNFOCUS;
    1831                         }
    1832 
    1833                         window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t));
    1834                         if (event2) {
    1835                                 link_initialize(&event2->link);
    1836                                 event2->type = ET_WINDOW_FOCUS;
    1837                         }
    18381504
    18391505                        sysarg_t x1 = 0;
     
    18641530
    18651531                        fibril_mutex_unlock(&window_list_mtx);
    1866 
    1867                         if (event1 && win1) {
    1868                                 comp_post_event_win(event1, win1);
    1869                         }
    1870 
    1871                         if (event2 && win2) {
    1872                                 comp_post_event_win(event2, win2);
    1873                         }
    1874 
    18751532                        comp_damage(x, y, width, height);
    18761533                } else {
     
    19431600                fibril_mutex_lock(&window_list_mtx);
    19441601
    1945                 window_t *red_win = window_create(0, 0);
     1602                window_t *red_win = window_create();
    19461603                red_win->surface = surface_create(250, 150, NULL, 0);
    19471604                pixel_t red_pix = PIXEL(255, 240, 0, 0);
     
    19531610                list_prepend(&red_win->link, &window_list);
    19541611
    1955                 window_t *blue_win = window_create(0, 0);
     1612                window_t *blue_win = window_create();
    19561613                blue_win->surface = surface_create(200, 100, NULL, 0);
    19571614                pixel_t blue_pix = PIXEL(255, 0, 0, 240);
     
    19631620                list_prepend(&blue_win->link, &window_list);
    19641621
    1965                 window_t *helenos_win = window_create(0, 0);
     1622                window_t *helenos_win = window_create();
    19661623                helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
    19671624                list_prepend(&helenos_win->link, &window_list);
    19681625
    1969                 window_t *nameic_win = window_create(0, 0);
     1626                window_t *nameic_win = window_create();
    19701627                nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
    19711628                list_prepend(&nameic_win->link, &window_list);
     
    19851642                event->data.kbd.c = c;
    19861643
    1987                 comp_post_event_top(event);
     1644                comp_post_event(event);
    19881645        }
    19891646
     
    20361693static void input_disconnect(void)
    20371694{
    2038         pointer_t *pointer = input->user;
     1695        pointer_t *pointer = input->user;
    20391696        input_close(input);
    20401697        pointer_destroy(pointer);
     
    20491706{
    20501707        /* Coordinates of the central pixel. */
    2051         coord_origin = UINT32_MAX / 4;
     1708        coord_origin = UINT32_MAX / 2;
    20521709       
    20531710        /* Color of the viewport background. Must be opaque. */
Note: See TracChangeset for help on using the changeset viewer.