Ignore:
File:
1 edited

Legend:

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

    r82edef2 rd17a4a9  
    9090typedef struct {
    9191        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);
     106
     107typedef struct {
     108        link_t link;
    92109        service_id_t in_dsid;
    93110        service_id_t out_dsid;
     
    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;
     
    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                 (*w_out) = 0;
    306                 (*h_out) = 0;
    307         }
     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);
    308287}
    309288
     
    330309                        /* Paint background color. */
    331310                        for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
    332                                 pixel_t *dst = pixelmap_pixel_at(
    333                                     surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y);
    334                                 sysarg_t count = w_dmg_vp;
    335                                 while (count-- != 0) {
    336                                         *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);
    337313                                }
    338314                        }
    339                         surface_add_damaged_region(vp->surface,
    340                             x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp);
    341315
    342316                        transform_t transform;
     
    389363                        list_foreach(pointer_list, link) {
    390364
    391                                 pointer_t *ptr = list_get_instance(link, pointer_t, link);
    392                                 if (ptr->ghost.surface) {
    393 
    394                                         sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost;
    395                                         sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost;
    396                                         surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost);
    397                                         comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform,
    398                                             &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost);
    399                                         bool isec_ghost = rectangle_intersect(
    400                                             x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
    401                                             x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost,
    402                                             &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost);
    403 
    404                                         if (isec_ghost) {
    405                                                 /* FIXME: Ghost is currently drawn based on the bounding
    406                                                  * rectangle of the window, which is sufficient as long
    407                                                  * as the windows can be rotated only by 90 degrees.
    408                                                  * For ghost to be compatible with arbitrary-angle
    409                                                  * rotation, it should be drawn as four lines adjusted
    410                                                  * by the transformation matrix. That would however
    411                                                  * require to equip libdraw with line drawing functionality. */
    412 
    413                                                 transform_t transform = ptr->ghost.transform;
    414                                                 double_point_t pos;
    415                                                 pos.x = vp->pos.x;
    416                                                 pos.y = vp->pos.y;
    417                                                 transform_translate(&transform, -pos.x, -pos.y);
    418 
    419                                                 pixel_t ghost_color;
    420 
    421                                                 if (y_bnd_ghost == y_dmg_ghost) {
    422                                                         for (sysarg_t x = x_dmg_ghost - vp->pos.x;
    423                                                                     x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
    424                                                                 ghost_color = surface_get_pixel(vp->surface,
    425                                                                     x, y_dmg_ghost - vp->pos.y);
    426                                                                 surface_put_pixel(vp->surface,
    427                                                                     x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color));
    428                                                         }
    429                                                 }
    430 
    431                                                 if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) {
    432                                                         for (sysarg_t x = x_dmg_ghost - vp->pos.x;
    433                                                                     x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
    434                                                                 ghost_color = surface_get_pixel(vp->surface,
    435                                                                     x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1);
    436                                                                 surface_put_pixel(vp->surface,
    437                                                                     x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color));
    438                                                         }
    439                                                 }
    440 
    441                                                 if (x_bnd_ghost == x_dmg_ghost) {
    442                                                         for (sysarg_t y = y_dmg_ghost - vp->pos.y;
    443                                                                     y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
    444                                                                 ghost_color = surface_get_pixel(vp->surface,
    445                                                                     x_dmg_ghost - vp->pos.x, y);
    446                                                                 surface_put_pixel(vp->surface,
    447                                                                     x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color));
    448                                                         }
    449                                                 }
    450 
    451                                                 if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) {
    452                                                         for (sysarg_t y = y_dmg_ghost - vp->pos.y;
    453                                                                     y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
    454                                                                 ghost_color = surface_get_pixel(vp->surface,
    455                                                                     x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y);
    456                                                                 surface_put_pixel(vp->surface,
    457                                                                     x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color));
    458                                                         }
    459                                                 }
    460                                         }
    461 
    462                                 }
    463                         }
    464 
    465                         list_foreach(pointer_list, link) {
    466 
    467365                                /* Determine what part of the pointer intersects with the
    468366                                 * updated area of the current viewport. */
     
    478376                                if (isec_ptr) {
    479377                                        /* Pointer is currently painted directly by copying pixels.
    480                                          * However, it is possible to draw the pointer similarly
     378                                         * However, it is possible to draw the painter similarly
    481379                                         * as window by using drawctx_transfer. It would allow
    482380                                         * more sophisticated control over drawing, but would also
    483381                                         * cost more regarding the performance. */
    484382
     383                                        pixel_t pix = 0;
    485384                                        sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
    486385                                        sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
     
    489388
    490389                                        for (sysarg_t y = 0; y < h_dmg_ptr; ++y) {
    491                                                 pixel_t *src = pixelmap_pixel_at(
    492                                                     surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y);
    493                                                 pixel_t *dst = pixelmap_pixel_at(
    494                                                     surface_pixmap_access(vp->surface), x_vp, y_vp + y);
    495                                                 sysarg_t count = w_dmg_ptr;
    496                                                 while (count-- != 0) {
    497                                                         *dst = (*src & 0xff000000) ? *src : *dst;
    498                                                         ++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                                                        }
    499395                                                }
    500396                                        }
    501                                         surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
    502397                                }
    503 
    504398                        }
    505399                }
     
    556450        } else {
    557451                fibril_mutex_lock(&window_list_mtx);
    558                 comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2,
     452                comp_coord_bounding_rect(x, y, width, height,
    559453                    win->transform, &x, &y, &width, &height);
    560454                fibril_mutex_unlock(&window_list_mtx);
     
    574468                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    575469                if (pointer->id == pos_id) {
    576                         pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
     470                        pointer->grab_flags = grab_flags;
    577471                        // TODO change pointer->state according to grab_flags
    578472                        break;
     
    647541}
    648542
    649 static void comp_post_event_win(window_event_t *event, window_t *target)
    650 {
    651         fibril_mutex_lock(&window_list_mtx);
    652         window_t *window = NULL;
    653         list_foreach(window_list, link) {
    654                 window = list_get_instance(link, window_t, link);
    655                 if (window == target) {
    656                         prodcons_produce(&window->queue, &event->link);
    657                 }
    658         }
    659         if (!window) {
    660                 free(event);
    661         }
    662         fibril_mutex_unlock(&window_list_mtx);
    663 }
    664 
    665 static void comp_post_event_top(window_event_t *event)
    666 {
    667         fibril_mutex_lock(&window_list_mtx);
    668         window_t *win = (window_t *) list_first(&window_list);
    669         if (win) {
    670                 prodcons_produce(&win->queue, &event->link);
    671         } else {
    672                 free(event);
    673         }
    674         fibril_mutex_unlock(&window_list_mtx);
    675 }
    676 
    677543static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    678544{
     
    680546        fibril_mutex_lock(&window_list_mtx);
    681547        list_remove(&win->link);
    682         window_t *win_focus = (window_t *) list_first(&window_list);
    683         window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t));
    684         if (event_focus) {
    685                 link_initialize(&event_focus->link);
    686                 event_focus->type = ET_WINDOW_FOCUS;
    687         }
    688548        fibril_mutex_unlock(&window_list_mtx);
    689 
    690         if (event_focus && win_focus) {
    691                 comp_post_event_win(event_focus, win_focus);
    692         }
    693549
    694550        /* Calculate damage. */
     
    745601                        fibril_mutex_lock(&window_list_mtx);
    746602
    747                         window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
     603                        window_t *win = window_create();
    748604                        if (!win) {
    749605                                async_answer_2(callid, ENOMEM, 0, 0);
     
    774630                        }
    775631
    776                         window_t *win_unfocus = (window_t *) list_first(&window_list);
    777632                        list_prepend(&win->link, &window_list);
    778 
    779                         window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
    780                         if (event_unfocus) {
    781                                 link_initialize(&event_unfocus->link);
    782                                 event_unfocus->type = ET_WINDOW_UNFOCUS;
    783                         }
    784633                       
    785634                        async_answer_2(callid, EOK, win->in_dsid, win->out_dsid);
    786635                        fibril_mutex_unlock(&window_list_mtx);
    787                        
    788                         if (event_unfocus && win_unfocus) {
    789                                 comp_post_event_win(event_unfocus, win_unfocus);
    790                         }
    791 
    792636                        return;
    793637                } else {
     
    1109953}
    1110954
     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
    1111967static void comp_recalc_transform(window_t *win)
    1112968{
     
    1117973        transform_t scale;
    1118974        transform_identity(&scale);
    1119         if (win->fx != 1 || win->fy != 1) {
    1120                 transform_scale(&scale, win->fx, win->fy);
    1121         }
     975        transform_scale(&scale, win->fx, win->fy);
    1122976
    1123977        transform_t rotate;
    1124978        transform_identity(&rotate);
    1125         if (win->angle != 0) {
    1126                 transform_rotate(&rotate, win->angle);
    1127         }
     979        transform_rotate(&rotate, win->angle);
    1128980
    1129981        transform_t transform;
     
    1142994
    1143995static void comp_window_animate(pointer_t *pointer, window_t *win,
    1144     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)
    1145997{
    1146998        /* window_list_mtx locked by caller */
    1147         /* pointer_list_mtx locked by caller */
    1148999
    11491000        int dx = pointer->accum.x;
     
    11691020                }
    11701021
    1171                 if ((scale || resize) && (win->angle != 0)) {
     1022                if (scale || resize) {
    11721023                        transform_t rotate;
    11731024                        transform_identity(&rotate);
     
    11861037                double _dx = dx;
    11871038                double _dy = dy;
    1188                 if (win->angle != 0) {
    1189                         transform_t unrotate;
    1190                         transform_identity(&unrotate);
    1191                         transform_rotate(&unrotate, -win->angle);
    1192                         transform_apply_linear(&unrotate, &_dx, &_dy);
    1193                 }
     1039                transform_t unrotate;
     1040                transform_identity(&unrotate);
     1041                transform_rotate(&unrotate, -win->angle);
     1042                transform_apply_linear(&unrotate, &_dx, &_dy);
    11941043                _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    11951044                _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    11961045
    11971046                if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1198                         double fx = 1.0 + (_dx / ((width - 1) * win->fx));
     1047                        double fx = 1.0 + (_dx / (width * win->fx));
    11991048                        if (fx > 0) {
    1200 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1201                                 if (scale) win->fx *= fx;
    1202 #endif
    1203 #if ANIMATE_WINDOW_TRANSFORMS == 1
    12041049                                win->fx *= fx;
    1205 #endif
    12061050                                scale_back_x *= fx;
    12071051                        }
     
    12091053
    12101054                if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1211                         double fy = 1.0 + (_dy / ((height - 1) * win->fy));
     1055                        double fy = 1.0 + (_dy / (height * win->fy));
    12121056                        if (fy > 0) {
    1213 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1214                                 if (scale) win->fy *= fy;
    1215 #endif
    1216 #if ANIMATE_WINDOW_TRANSFORMS == 1
    12171057                                win->fy *= fy;
    1218 #endif
    12191058                                scale_back_y *= fy;
    12201059                        }
     
    12321071            dmg_x, dmg_y, dmg_width, dmg_height);
    12331072}
    1234 
    1235 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1236 static void comp_ghost_animate(pointer_t *pointer,
    1237     desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4)
    1238 {
    1239         /* window_list_mtx locked by caller */
    1240         /* pointer_list_mtx locked by caller */
    1241 
    1242         int dx = pointer->accum_ghost.x;
    1243         int dy = pointer->accum_ghost.y;
    1244         pointer->accum_ghost.x = 0;
    1245         pointer->accum_ghost.y = 0;
    1246 
    1247         bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
    1248         bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y);
    1249         bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y);
    1250 
    1251         sysarg_t width, height;
    1252         surface_get_resolution(pointer->ghost.surface, &width, &height);
    1253 
    1254         if (move) {
    1255                 double cx = 0;
    1256                 double cy = 0;
    1257                 if (pointer->grab_flags & GF_MOVE_X) {
    1258                         cx = 1;
    1259                 }
    1260                 if (pointer->grab_flags & GF_MOVE_Y) {
    1261                         cy = 1;
    1262                 }
    1263 
    1264                 if (scale || resize) {
    1265                         transform_t rotate;
    1266                         transform_identity(&rotate);
    1267                         transform_rotate(&rotate, pointer->ghost.angle);
    1268                         transform_apply_linear(&rotate, &cx, &cy);
    1269                 }
    1270 
    1271                 cx = (cx < 0) ? (-1 * cx) : cx;
    1272                 cy = (cy < 0) ? (-1 * cy) : cy;
    1273 
    1274                 pointer->ghost.dx += (cx * dx);
    1275                 pointer->ghost.dy += (cy * dy);
    1276         }
    1277 
    1278         if (scale || resize) {
    1279                 double _dx = dx;
    1280                 double _dy = dy;
    1281                 transform_t unrotate;
    1282                 transform_identity(&unrotate);
    1283                 transform_rotate(&unrotate, -pointer->ghost.angle);
    1284                 transform_apply_linear(&unrotate, &_dx, &_dy);
    1285                 _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    1286                 _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    1287 
    1288                 if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1289                         double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx));
    1290                         pointer->ghost.fx *= fx;
    1291                 }
    1292 
    1293                 if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1294                         double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy));
    1295                         pointer->ghost.fy *= fy;
    1296                 }
    1297         }
    1298 
    1299         sysarg_t x1, y1, width1, height1;
    1300         sysarg_t x2, y2, width2, height2;
    1301         comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
    1302             &x1, &y1, &width1, &height1);
    1303         comp_recalc_transform(&pointer->ghost);
    1304         comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
    1305             &x2, &y2, &width2, &height2);
    1306 
    1307         sysarg_t x_u, y_u, w_u, h_u;
    1308         rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
    1309             &x_u, &y_u, &w_u, &h_u);
    1310 
    1311         sysarg_t x_i, y_i, w_i, h_i;
    1312         rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2,
    1313             &x_i, &y_i, &w_i, &h_i);
    1314 
    1315         if (w_i == 0 || h_i == 0) {
    1316                 rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0;
    1317                 rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0;
    1318                 rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0;
    1319                 rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0;
    1320         } else {
    1321                 rect1->x = x_u;
    1322                 rect1->y = y_u;
    1323                 rect1->w = x_i - x_u + 1;
    1324                 rect1->h = h_u;
    1325 
    1326                 rect2->x = x_u;
    1327                 rect2->y = y_u;
    1328                 rect2->w = w_u;
    1329                 rect2->h = y_i - y_u + 1;
    1330 
    1331                 rect3->x = x_i + w_i - 1;
    1332                 rect3->y = y_u;
    1333                 rect3->w = w_u - w_i - x_i + x_u + 1;
    1334                 rect3->h = h_u;
    1335                
    1336                 rect4->x = x_u;
    1337                 rect4->y = y_i + h_i - 1;
    1338                 rect4->w = w_u;
    1339                 rect4->h = h_u - h_i - y_i + y_u + 1;
    1340         }
    1341 }
    1342 #endif
    13431073
    13441074static int comp_abs_move(input_t *input, unsigned x , unsigned y,
     
    13951125
    13961126        fibril_mutex_lock(&window_list_mtx);
    1397         fibril_mutex_lock(&pointer_list_mtx);
    13981127        window_t *top = (window_t *) list_first(&window_list);
    13991128        if (top && top->surface) {
     
    14071136                        within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    14081137                            top->transform, width, height, &point_x, &point_y);
    1409 
    1410                         window_event_t *event = NULL;
     1138                        fibril_mutex_unlock(&window_list_mtx);
     1139
    14111140                        if (within_client) {
    1412                                 event = (window_event_t *) malloc(sizeof(window_event_t));
     1141                                window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    14131142                                if (event) {
    14141143                                        link_initialize(&event->link);
     
    14191148                                        event->data.pos.hpos = point_x;
    14201149                                        event->data.pos.vpos = point_y;
     1150                                        comp_post_event(event);
    14211151                                }
    14221152                        }
    1423 
    1424                         fibril_mutex_unlock(&pointer_list_mtx);
    1425                         fibril_mutex_unlock(&window_list_mtx);
    1426 
    1427                         if (event) {
    1428                                 comp_post_event_top(event);
    1429                         }
    1430 
    14311153                } else {
    14321154                        /* Pointer is grabbed by top-level window action. */
    14331155                        pointer->accum.x += dx;
    14341156                        pointer->accum.y += dy;
    1435                         pointer->accum_ghost.x += dx;
    1436                         pointer->accum_ghost.y += dy;
    1437 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1438                         if (pointer->ghost.surface == NULL) {
    1439                                 pointer->ghost.surface = top->surface;
    1440                                 pointer->ghost.dx = top->dx;
    1441                                 pointer->ghost.dy = top->dy;
    1442                                 pointer->ghost.fx = top->fx;
    1443                                 pointer->ghost.fy = top->fy;
    1444                                 pointer->ghost.angle = top->angle;
    1445                                 pointer->ghost.transform = top->transform;
    1446                         }
    1447                         desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
    1448                         comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
    1449 #endif
    14501157#if ANIMATE_WINDOW_TRANSFORMS == 1
    14511158                        sysarg_t x, y, width, height;
    14521159                        comp_window_animate(pointer, top, &x, &y, &width, &height);
    14531160#endif
    1454                         fibril_mutex_unlock(&pointer_list_mtx);
    14551161                        fibril_mutex_unlock(&window_list_mtx);
    1456 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1457                         comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
    1458                         comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
    1459                         comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
    1460                         comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
    1461 #endif
    14621162#if ANIMATE_WINDOW_TRANSFORMS == 1
    14631163                        comp_damage(x, y, width, height);
     
    14651165                }
    14661166        } else {
    1467                 fibril_mutex_unlock(&pointer_list_mtx);
    14681167                fibril_mutex_unlock(&window_list_mtx);
    14691168        }
     
    14751174{
    14761175        pointer_t *pointer = input_pointer(input);
    1477 
    1478         fibril_mutex_lock(&window_list_mtx);
    1479         fibril_mutex_lock(&pointer_list_mtx);
    1480         window_t *win = NULL;
    1481         sysarg_t point_x = 0;
    1482         sysarg_t point_y = 0;
    1483         sysarg_t width, height;
    1484         bool within_client = false;
    1485 
    1486         /* Determine the window which the mouse click belongs to. */
    1487         list_foreach(window_list, link) {
    1488                 win = list_get_instance(link, window_t, link);
    1489                 if (win->surface) {
    1490                         surface_get_resolution(win->surface, &width, &height);
    1491                         within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    1492                             win->transform, width, height, &point_x, &point_y);
    1493                 }
    1494                 if (within_client) {
    1495                         break;
    1496                 }
    1497         }
    1498 
    1499         /* Check whether the window is top-level window. */
    1500         window_t *top = (window_t *) list_first(&window_list);
    1501         if (!win || !top) {
    1502                 fibril_mutex_unlock(&pointer_list_mtx);
    1503                 fibril_mutex_unlock(&window_list_mtx);
    1504                 return EOK;
    1505         }
    1506 
    1507         window_event_t *event_top = NULL;
    1508         window_event_t *event_unfocus = NULL;
    1509         window_t *win_unfocus = NULL;
    1510         sysarg_t dmg_x, dmg_y;
    1511         sysarg_t dmg_width = 0;
    1512         sysarg_t dmg_height = 0;
    1513        
    1514 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1515         desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
    1516 #endif
    15171176
    15181177        if (bpress) {
     
    15211180                pointer->pressed = true;
    15221181
    1523                 /* Bring the window to the foreground. */
    1524                 if ((win != top) && within_client) {
    1525                         win_unfocus = (window_t *) list_first(&window_list);
    1526                         list_remove(&win->link);
    1527                         list_prepend(&win->link, &window_list);
    1528                         event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
    1529                         if (event_unfocus) {
    1530                                 link_initialize(&event_unfocus->link);
    1531                                 event_unfocus->type = ET_WINDOW_UNFOCUS;
    1532                         }
    1533                         comp_coord_bounding_rect(0, 0, width, height, win->transform,
    1534                             &dmg_x, &dmg_y, &dmg_width, &dmg_height);
    1535                 }
    1536 
    1537                 /* 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. */
    15381196                if (within_client) {
    1539                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1540                         if (event_top) {
    1541                                 link_initialize(&event_top->link);
    1542                                 event_top->type = ET_POSITION_EVENT;
    1543                                 event_top->data.pos.pos_id = pointer->id;
    1544                                 event_top->data.pos.type = POS_PRESS;
    1545                                 event_top->data.pos.btn_num = bnum;
    1546                                 event_top->data.pos.hpos = point_x;
    1547                                 event_top->data.pos.vpos = point_y;
    1548                         }
    1549                         pointer->grab_flags = GF_EMPTY;
    1550                 }
    1551 
     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                }
    15521211        } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
    15531212                pointer->pressed = false;
    15541213
    1555 #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
    15561247                sysarg_t pre_x = 0;
    15571248                sysarg_t pre_y = 0;
     
    15591250                sysarg_t pre_height = 0;
    15601251
     1252#if ANIMATE_WINDOW_TRANSFORMS == 0
    15611253                if (pointer->grab_flags != GF_EMPTY) {
    1562                         if (pointer->ghost.surface) {
    1563                                 comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
    1564                                 pointer->ghost.surface = NULL;
    1565                         }
    15661254                        comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height);
    15671255                        dmg_x = pre_x;
     
    15751263
    15761264                        surface_get_resolution(top->surface, &width, &height);
    1577 #if ANIMATE_WINDOW_TRANSFORMS == 1
    15781265                        top->fx *= (1.0 / scale_back_x);
    15791266                        top->fy *= (1.0 / scale_back_y);
    15801267                        comp_recalc_transform(top);
    1581 #endif
    15821268
    15831269                        /* Commit proper resize action. */
    1584                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1585                         if (event_top) {
    1586                                 link_initialize(&event_top->link);
    1587                                 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;
    15881274
    15891275                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
     
    15911277
    15921278                                if (pointer->grab_flags & GF_RESIZE_X) {
    1593                                         event_top->data.rsz.width =
     1279                                        event->data.rsz.width =
    15941280                                                ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    15951281                                } else {
    1596                                         event_top->data.rsz.width = width;
     1282                                        event->data.rsz.width = width;
    15971283                                }
    15981284
    15991285                                if (pointer->grab_flags & GF_RESIZE_Y) {
    1600                                         event_top->data.rsz.height =
     1286                                        event->data.rsz.height =
    16011287                                                ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    16021288                                } else {
    1603                                         event_top->data.rsz.height = height;
     1289                                        event->data.rsz.height = height;
    16041290                                }
    16051291                        }
     
    16101296                       
    16111297                        /* Notify top-level window about mouse release. */
    1612                         event_top = (window_event_t *) malloc(sizeof(window_event_t));
    1613                         if (event_top) {
    1614                                 link_initialize(&event_top->link);
    1615                                 event_top->type = ET_POSITION_EVENT;
    1616                                 event_top->data.pos.pos_id = pointer->id;
    1617                                 event_top->data.pos.type = POS_RELEASE;
    1618                                 event_top->data.pos.btn_num = bnum;
    1619                                 event_top->data.pos.hpos = point_x;
    1620                                 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;
    16211307                        }
    16221308                        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);
    16231317                       
    16241318                } else {
     
    16261320                }
    16271321
    1628         }
    1629 
    1630         fibril_mutex_unlock(&pointer_list_mtx);
    1631         fibril_mutex_unlock(&window_list_mtx);
    1632 
    1633 #if ANIMATE_WINDOW_TRANSFORMS == 0
    1634                 comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
    1635                 comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
    1636                 comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
    1637                 comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
    1638 #endif
    1639 
    1640         if (dmg_width > 0 && dmg_height > 0) {
    1641                 comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
    1642         }
    1643 
    1644         if (event_unfocus && win_unfocus) {
    1645                 comp_post_event_win(event_unfocus, win_unfocus);
    1646         }
    1647 
    1648         if (event_top) {
    1649                 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                }
    16501331        }
    16511332
     
    17711452
    17721453                        fibril_mutex_unlock(&window_list_mtx);
    1773                         comp_post_event_top(event);
     1454                        comp_post_event(event);
    17741455                } else {
    17751456                        fibril_mutex_unlock(&window_list_mtx);
     
    18131494                event->type = ET_WINDOW_CLOSE;
    18141495
    1815                 comp_post_event_top(event);
     1496                comp_post_event(event);
    18161497        } else if (win_switch) {
    18171498                fibril_mutex_lock(&window_list_mtx);
     
    18211502                        list_append(&win1->link, &window_list);
    18221503                        window_t *win2 = (window_t *) list_first(&window_list);
    1823 
    1824                         window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t));
    1825                         if (event1) {
    1826                                 link_initialize(&event1->link);
    1827                                 event1->type = ET_WINDOW_UNFOCUS;
    1828                         }
    1829 
    1830                         window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t));
    1831                         if (event2) {
    1832                                 link_initialize(&event2->link);
    1833                                 event2->type = ET_WINDOW_FOCUS;
    1834                         }
    18351504
    18361505                        sysarg_t x1 = 0;
     
    18611530
    18621531                        fibril_mutex_unlock(&window_list_mtx);
    1863 
    1864                         if (event1 && win1) {
    1865                                 comp_post_event_win(event1, win1);
    1866                         }
    1867 
    1868                         if (event2 && win2) {
    1869                                 comp_post_event_win(event2, win2);
    1870                         }
    1871 
    18721532                        comp_damage(x, y, width, height);
    18731533                } else {
     
    19401600                fibril_mutex_lock(&window_list_mtx);
    19411601
    1942                 window_t *red_win = window_create(0, 0);
     1602                window_t *red_win = window_create();
    19431603                red_win->surface = surface_create(250, 150, NULL, 0);
    19441604                pixel_t red_pix = PIXEL(255, 240, 0, 0);
     
    19501610                list_prepend(&red_win->link, &window_list);
    19511611
    1952                 window_t *blue_win = window_create(0, 0);
     1612                window_t *blue_win = window_create();
    19531613                blue_win->surface = surface_create(200, 100, NULL, 0);
    19541614                pixel_t blue_pix = PIXEL(255, 0, 0, 240);
     
    19601620                list_prepend(&blue_win->link, &window_list);
    19611621
    1962                 window_t *helenos_win = window_create(0, 0);
     1622                window_t *helenos_win = window_create();
    19631623                helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
    19641624                list_prepend(&helenos_win->link, &window_list);
    19651625
    1966                 window_t *nameic_win = window_create(0, 0);
     1626                window_t *nameic_win = window_create();
    19671627                nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
    19681628                list_prepend(&nameic_win->link, &window_list);
     
    19821642                event->data.kbd.c = c;
    19831643
    1984                 comp_post_event_top(event);
     1644                comp_post_event(event);
    19851645        }
    19861646
     
    20331693static void input_disconnect(void)
    20341694{
    2035         pointer_t *pointer = input->user;
     1695        pointer_t *pointer = input->user;
    20361696        input_close(input);
    20371697        pointer_destroy(pointer);
     
    20461706{
    20471707        /* Coordinates of the central pixel. */
    2048         coord_origin = UINT32_MAX / 4;
     1708        coord_origin = UINT32_MAX / 2;
    20491709       
    20501710        /* Color of the viewport background. Must be opaque. */
Note: See TracChangeset for help on using the changeset viewer.