Ignore:
File:
1 edited

Legend:

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

    rd17a4a9 r3b98311  
    3434
    3535#include <sys/types.h>
    36 #include <bool.h>
     36#include <stdbool.h>
    3737#include <errno.h>
    3838#include <str_error.h>
     
    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 
    103 static sysarg_t pointer_id = 0;
    104 static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
    105 static LIST_INITIALIZE(pointer_list);
    106 
    107 typedef struct {
    108         link_t link;
     92        atomic_t ref_cnt;
    10993        service_id_t in_dsid;
    11094        service_id_t out_dsid;
     
    129113typedef struct {
    130114        link_t link;
     115        sysarg_t id;
     116        uint8_t state;
     117        desktop_point_t pos;
     118        sysarg_t btn_num;
     119        desktop_point_t btn_pos;
     120        desktop_vector_t accum;
     121        sysarg_t grab_flags;
     122        bool pressed;
     123        cursor_t cursor;
     124        window_t ghost;
     125        desktop_vector_t accum_ghost;
     126} pointer_t;
     127
     128static sysarg_t pointer_id = 0;
     129static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
     130static LIST_INITIALIZE(pointer_list);
     131
     132typedef struct {
     133        link_t link;
    131134        service_id_t dsid;
    132135        vslmode_t mode;
     
    136139} viewport_t;
    137140
     141static desktop_rect_t viewport_bound_rect;
    138142static FIBRIL_MUTEX_INITIALIZE(viewport_list_mtx);
    139143static LIST_INITIALIZE(viewport_list);
     
    181185        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    182186
     187        /* Ghost window for transformation animation. */
     188        transform_identity(&p->ghost.transform);
     189        transform_translate(&p->ghost.transform, coord_origin, coord_origin);
     190        p->ghost.dx = coord_origin;
     191        p->ghost.dy = coord_origin;
     192        p->ghost.fx = 1;
     193        p->ghost.fy = 1;
     194        p->ghost.angle = 0;
     195        p->ghost.opacity = 255;
     196        p->ghost.surface = NULL;
     197        p->accum_ghost.x = 0;
     198        p->accum_ghost.y = 0;
     199
    183200        return p;
    184201}
     
    192209}
    193210
    194 static window_t *window_create()
     211static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
    195212{
    196213        window_t *win = (window_t *) malloc(sizeof(window_t));
     
    200217
    201218        link_initialize(&win->link);
     219        atomic_set(&win->ref_cnt, 0);
    202220        prodcons_initialize(&win->queue);
    203221        transform_identity(&win->transform);
    204         transform_translate(&win->transform, coord_origin, coord_origin);
    205         win->dx = coord_origin;
    206         win->dy = coord_origin;
     222        transform_translate(&win->transform,
     223            coord_origin + x_offset, coord_origin + y_offset);
     224        win->dx = coord_origin + x_offset;
     225        win->dy = coord_origin + y_offset;
    207226        win->fx = 1;
    208227        win->fy = 1;
     
    216235static void window_destroy(window_t *win)
    217236{
    218         if (win) {
     237        if (win && atomic_get(&win->ref_cnt) == 0) {
     238                while (!list_empty(&win->queue.list)) {
     239                        window_event_t *event = (window_event_t *) list_first(&win->queue.list);
     240                        list_remove(&event->link);
     241                        free(event);
     242                }
     243
    219244                if (win->surface) {
    220245                        surface_destroy(win->surface);
     
    250275}
    251276
    252 static void comp_coord_from_client(sysarg_t x_in, sysarg_t y_in, transform_t win_trans,
     277static void comp_coord_from_client(double x_in, double y_in, transform_t win_trans,
    253278    sysarg_t *x_out, sysarg_t *y_out)
    254279{
     
    263288}
    264289
    265 static 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,
     290static void comp_coord_bounding_rect(double x_in, double y_in,
     291    double w_in, double h_in, transform_t win_trans,
    267292    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    268293{
    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);
     294        if (w_in > 0 && h_in > 0) {
     295                sysarg_t x[4];
     296                sysarg_t y[4];
     297                comp_coord_from_client(x_in, y_in, win_trans, &x[0], &y[0]);
     298                comp_coord_from_client(x_in + w_in - 1, y_in, win_trans, &x[1], &y[1]);
     299                comp_coord_from_client(x_in + w_in - 1, y_in + h_in - 1, win_trans, &x[2], &y[2]);
     300                comp_coord_from_client(x_in, y_in + h_in - 1, win_trans, &x[3], &y[3]);
     301                (*x_out) = x[0];
     302                (*y_out) = y[0];
     303                (*w_out) = x[0];
     304                (*h_out) = y[0];
     305                for (int i = 1; i < 4; ++i) {
     306                        (*x_out) = (x[i] < (*x_out)) ? x[i] : (*x_out);
     307                        (*y_out) = (y[i] < (*y_out)) ? y[i] : (*y_out);
     308                        (*w_out) = (x[i] > (*w_out)) ? x[i] : (*w_out);
     309                        (*h_out) = (y[i] > (*h_out)) ? y[i] : (*h_out);
     310                }
     311                (*w_out) = (*w_out) - (*x_out) + 1;
     312                (*h_out) = (*h_out) - (*y_out) + 1;
     313        } else {
     314                (*x_out) = 0;
     315                (*y_out) = 0;
     316                (*w_out) = 0;
     317                (*h_out) = 0;
     318        }
     319}
     320
     321static void comp_restrict_pointers(void)
     322{
     323        fibril_mutex_lock(&viewport_list_mtx);
     324
     325        sysarg_t x_res = coord_origin;
     326        sysarg_t y_res = coord_origin;
     327        sysarg_t w_res = 0;
     328        sysarg_t h_res = 0;
     329
     330        if (!list_empty(&viewport_list)) {
     331                viewport_t *vp = (viewport_t *) list_first(&viewport_list);
     332                x_res = vp->pos.x;
     333                y_res = vp->pos.y;
     334                surface_get_resolution(vp->surface, &w_res, &h_res);
     335        }
     336
     337        list_foreach(viewport_list, link) {
     338                viewport_t *vp = list_get_instance(link, viewport_t, link);
     339                sysarg_t w_vp, h_vp;
     340                surface_get_resolution(vp->surface, &w_vp, &h_vp);
     341                rectangle_union(
     342                    x_res, y_res, w_res, h_res,
     343                    vp->pos.x, vp->pos.y, w_vp, h_vp,
     344                    &x_res, &y_res, &w_res, &h_res);
     345        }
     346
     347        viewport_bound_rect.x = x_res;
     348        viewport_bound_rect.y = y_res;
     349        viewport_bound_rect.w = w_res;
     350        viewport_bound_rect.h = h_res;
     351
     352        fibril_mutex_unlock(&viewport_list_mtx);
     353
     354        fibril_mutex_lock(&pointer_list_mtx);
     355
     356        list_foreach(pointer_list, link) {
     357                pointer_t *ptr = list_get_instance(link, pointer_t, link);
     358                ptr->pos.x = ptr->pos.x > viewport_bound_rect.x ? ptr->pos.x : viewport_bound_rect.x;
     359                ptr->pos.y = ptr->pos.y > viewport_bound_rect.y ? ptr->pos.y : viewport_bound_rect.y;
     360                ptr->pos.x = ptr->pos.x < viewport_bound_rect.x + viewport_bound_rect.w ?
     361                    ptr->pos.x : viewport_bound_rect.x + viewport_bound_rect.w;
     362                ptr->pos.y = ptr->pos.y < viewport_bound_rect.y + viewport_bound_rect.h ?
     363                    ptr->pos.y : viewport_bound_rect.y + viewport_bound_rect.h;
     364        }
     365
     366        fibril_mutex_unlock(&pointer_list_mtx);
    287367}
    288368
     
    309389                        /* Paint background color. */
    310390                        for (sysarg_t y = y_dmg_vp - vp->pos.y; y <  y_dmg_vp - vp->pos.y + h_dmg_vp; ++y) {
    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);
     391                                pixel_t *dst = pixelmap_pixel_at(
     392                                    surface_pixmap_access(vp->surface), x_dmg_vp - vp->pos.x, y);
     393                                sysarg_t count = w_dmg_vp;
     394                                while (count-- != 0) {
     395                                        *dst++ = bg_color;
    313396                                }
    314397                        }
     398                        surface_add_damaged_region(vp->surface,
     399                            x_dmg_vp - vp->pos.x, y_dmg_vp - vp->pos.y, w_dmg_vp, h_dmg_vp);
    315400
    316401                        transform_t transform;
     
    363448                        list_foreach(pointer_list, link) {
    364449
     450                                pointer_t *ptr = list_get_instance(link, pointer_t, link);
     451                                if (ptr->ghost.surface) {
     452
     453                                        sysarg_t x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost;
     454                                        sysarg_t x_dmg_ghost, y_dmg_ghost, w_dmg_ghost, h_dmg_ghost;
     455                                        surface_get_resolution(ptr->ghost.surface, &w_bnd_ghost, &h_bnd_ghost);
     456                                        comp_coord_bounding_rect(0, 0, w_bnd_ghost, h_bnd_ghost, ptr->ghost.transform,
     457                                            &x_bnd_ghost, &y_bnd_ghost, &w_bnd_ghost, &h_bnd_ghost);
     458                                        bool isec_ghost = rectangle_intersect(
     459                                            x_dmg_vp, y_dmg_vp, w_dmg_vp, h_dmg_vp,
     460                                            x_bnd_ghost, y_bnd_ghost, w_bnd_ghost, h_bnd_ghost,
     461                                            &x_dmg_ghost, &y_dmg_ghost, &w_dmg_ghost, &h_dmg_ghost);
     462
     463                                        if (isec_ghost) {
     464                                                /* FIXME: Ghost is currently drawn based on the bounding
     465                                                 * rectangle of the window, which is sufficient as long
     466                                                 * as the windows can be rotated only by 90 degrees.
     467                                                 * For ghost to be compatible with arbitrary-angle
     468                                                 * rotation, it should be drawn as four lines adjusted
     469                                                 * by the transformation matrix. That would however
     470                                                 * require to equip libdraw with line drawing functionality. */
     471
     472                                                transform_t transform = ptr->ghost.transform;
     473                                                double_point_t pos;
     474                                                pos.x = vp->pos.x;
     475                                                pos.y = vp->pos.y;
     476                                                transform_translate(&transform, -pos.x, -pos.y);
     477
     478                                                pixel_t ghost_color;
     479
     480                                                if (y_bnd_ghost == y_dmg_ghost) {
     481                                                        for (sysarg_t x = x_dmg_ghost - vp->pos.x;
     482                                                                    x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
     483                                                                ghost_color = surface_get_pixel(vp->surface,
     484                                                                    x, y_dmg_ghost - vp->pos.y);
     485                                                                surface_put_pixel(vp->surface,
     486                                                                    x, y_dmg_ghost - vp->pos.y, INVERT(ghost_color));
     487                                                        }
     488                                                }
     489
     490                                                if (y_bnd_ghost + h_bnd_ghost == y_dmg_ghost + h_dmg_ghost) {
     491                                                        for (sysarg_t x = x_dmg_ghost - vp->pos.x;
     492                                                                    x < x_dmg_ghost - vp->pos.x + w_dmg_ghost; ++x) {
     493                                                                ghost_color = surface_get_pixel(vp->surface,
     494                                                                    x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1);
     495                                                                surface_put_pixel(vp->surface,
     496                                                                    x, y_dmg_ghost - vp->pos.y + h_dmg_ghost - 1, INVERT(ghost_color));
     497                                                        }
     498                                                }
     499
     500                                                if (x_bnd_ghost == x_dmg_ghost) {
     501                                                        for (sysarg_t y = y_dmg_ghost - vp->pos.y;
     502                                                                    y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
     503                                                                ghost_color = surface_get_pixel(vp->surface,
     504                                                                    x_dmg_ghost - vp->pos.x, y);
     505                                                                surface_put_pixel(vp->surface,
     506                                                                    x_dmg_ghost - vp->pos.x, y, INVERT(ghost_color));
     507                                                        }
     508                                                }
     509
     510                                                if (x_bnd_ghost + w_bnd_ghost == x_dmg_ghost + w_dmg_ghost) {
     511                                                        for (sysarg_t y = y_dmg_ghost - vp->pos.y;
     512                                                                    y < y_dmg_ghost - vp->pos.y + h_dmg_ghost; ++y) {
     513                                                                ghost_color = surface_get_pixel(vp->surface,
     514                                                                    x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y);
     515                                                                surface_put_pixel(vp->surface,
     516                                                                    x_dmg_ghost - vp->pos.x + w_dmg_ghost - 1, y, INVERT(ghost_color));
     517                                                        }
     518                                                }
     519                                        }
     520
     521                                }
     522                        }
     523
     524                        list_foreach(pointer_list, link) {
     525
    365526                                /* Determine what part of the pointer intersects with the
    366527                                 * updated area of the current viewport. */
     
    376537                                if (isec_ptr) {
    377538                                        /* Pointer is currently painted directly by copying pixels.
    378                                          * However, it is possible to draw the painter similarly
     539                                         * However, it is possible to draw the pointer similarly
    379540                                         * as window by using drawctx_transfer. It would allow
    380541                                         * more sophisticated control over drawing, but would also
    381542                                         * cost more regarding the performance. */
    382543
    383                                         pixel_t pix = 0;
    384544                                        sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
    385545                                        sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
     
    388548
    389549                                        for (sysarg_t y = 0; y < h_dmg_ptr; ++y) {
    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                                                         }
     550                                                pixel_t *src = pixelmap_pixel_at(
     551                                                    surface_pixmap_access(sf_ptr), x_ptr, y_ptr + y);
     552                                                pixel_t *dst = pixelmap_pixel_at(
     553                                                    surface_pixmap_access(vp->surface), x_vp, y_vp + y);
     554                                                sysarg_t count = w_dmg_ptr;
     555                                                while (count-- != 0) {
     556                                                        *dst = (*src & 0xff000000) ? *src : *dst;
     557                                                        ++dst; ++src;
    395558                                                }
    396559                                        }
     560                                        surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
    397561                                }
     562
    398563                        }
    399564                }
     
    441606static void comp_window_damage(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    442607{
    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);
     608        double x = IPC_GET_ARG1(*icall);
     609        double y = IPC_GET_ARG2(*icall);
     610        double width = IPC_GET_ARG3(*icall);
     611        double height = IPC_GET_ARG4(*icall);
    447612
    448613        if (width == 0 || height == 0) {
     
    450615        } else {
    451616                fibril_mutex_lock(&window_list_mtx);
    452                 comp_coord_bounding_rect(x, y, width, height,
    453                     win->transform, &x, &y, &width, &height);
     617                sysarg_t x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob;
     618                comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2,
     619                    win->transform, &x_dmg_glob, &y_dmg_glob, &w_dmg_glob, &h_dmg_glob);
    454620                fibril_mutex_unlock(&window_list_mtx);
    455                 comp_damage(x, y, width, height);
     621                comp_damage(x_dmg_glob, y_dmg_glob, w_dmg_glob, h_dmg_glob);
    456622        }
    457623
     
    468634                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    469635                if (pointer->id == pos_id) {
    470                         pointer->grab_flags = grab_flags;
     636                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
    471637                        // TODO change pointer->state according to grab_flags
    472638                        break;
     
    541707}
    542708
     709static void comp_post_event_win(window_event_t *event, window_t *target)
     710{
     711        fibril_mutex_lock(&window_list_mtx);
     712        window_t *window = NULL;
     713        list_foreach(window_list, link) {
     714                window = list_get_instance(link, window_t, link);
     715                if (window == target) {
     716                        prodcons_produce(&window->queue, &event->link);
     717                }
     718        }
     719        if (!window) {
     720                free(event);
     721        }
     722        fibril_mutex_unlock(&window_list_mtx);
     723}
     724
     725static void comp_post_event_top(window_event_t *event)
     726{
     727        fibril_mutex_lock(&window_list_mtx);
     728        window_t *win = (window_t *) list_first(&window_list);
     729        if (win) {
     730                prodcons_produce(&win->queue, &event->link);
     731        } else {
     732                free(event);
     733        }
     734        fibril_mutex_unlock(&window_list_mtx);
     735}
     736
    543737static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    544738{
     
    546740        fibril_mutex_lock(&window_list_mtx);
    547741        list_remove(&win->link);
     742        window_t *win_focus = (window_t *) list_first(&window_list);
     743        window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t));
     744        if (event_focus) {
     745                link_initialize(&event_focus->link);
     746                event_focus->type = ET_WINDOW_FOCUS;
     747        }
    548748        fibril_mutex_unlock(&window_list_mtx);
     749
     750        if (event_focus && win_focus) {
     751                comp_post_event_win(event_focus, win_focus);
     752        }
     753
     754        loc_service_unregister(win->in_dsid);
     755        loc_service_unregister(win->out_dsid);
     756
     757        /* In case the client was killed, input fibril of the window might be
     758         * still blocked on the condition within comp_window_get_event. */
     759        window_event_t *event_dummy = (window_event_t *) malloc(sizeof(window_event_t));
     760        if (event_dummy) {
     761                link_initialize(&event_dummy->link);
     762                prodcons_produce(&win->queue, &event_dummy->link);
     763        }
    549764
    550765        /* Calculate damage. */
     
    559774        }
    560775
    561         /* Release window resources. */
    562         loc_service_unregister(win->in_dsid);
    563         loc_service_unregister(win->out_dsid);
    564         while (!list_empty(&win->queue.list)) {
    565                 list_remove(list_first(&win->queue.list));
    566         }
    567         window_destroy(win);
    568 
    569776        comp_damage(x, y, width, height);
    570777
     
    601808                        fibril_mutex_lock(&window_list_mtx);
    602809
    603                         window_t *win = window_create();
     810                        window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    604811                        if (!win) {
    605812                                async_answer_2(callid, ENOMEM, 0, 0);
     
    630837                        }
    631838
     839                        window_t *win_unfocus = (window_t *) list_first(&window_list);
    632840                        list_prepend(&win->link, &window_list);
     841
     842                        window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
     843                        if (event_unfocus) {
     844                                link_initialize(&event_unfocus->link);
     845                                event_unfocus->type = ET_WINDOW_UNFOCUS;
     846                        }
    633847                       
    634848                        async_answer_2(callid, EOK, win->in_dsid, win->out_dsid);
    635849                        fibril_mutex_unlock(&window_list_mtx);
     850                       
     851                        if (event_unfocus && win_unfocus) {
     852                                comp_post_event_win(event_unfocus, win_unfocus);
     853                        }
     854
    636855                        return;
    637856                } else {
     
    654873
    655874        if (win) {
     875                atomic_inc(&win->ref_cnt);
    656876                async_answer_0(iid, EOK);
    657877        } else {
     
    666886
    667887                        if (!IPC_GET_IMETHOD(call)) {
    668                                 async_answer_0(callid, EINVAL);
     888                                async_answer_0(callid, EOK);
     889                                atomic_dec(&win->ref_cnt);
     890                                window_destroy(win);
    669891                                return;
    670892                        }
     
    683905
    684906                        if (!IPC_GET_IMETHOD(call)) {
    685                                 async_answer_0(callid, EINVAL);
     907                                comp_window_close(win, callid, &call);
     908                                atomic_dec(&win->ref_cnt);
     909                                window_destroy(win);
    686910                                return;
    687911                        }
     
    698922                                break;
    699923                        case WINDOW_CLOSE:
    700                                 comp_window_close(win, callid, &call);
     924                                /* Postpone the closing until the phone is hung up to cover
     925                                 * the case when the client is killed abruptly. */
     926                                async_answer_0(callid, EOK);
    701927                                break;
    702928                        case WINDOW_CLOSE_REQUEST:
     
    752978        async_answer_0(iid, EOK);
    753979
     980        comp_restrict_pointers();
    754981        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    755982}
     
    7971024                fibril_mutex_unlock(&viewport_list_mtx);
    7981025                async_answer_0(iid, EOK);
     1026
     1027                comp_restrict_pointers();
     1028                comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    7991029        }
    8001030}
     
    9531183}
    9541184
    955 static 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 
    9671185static void comp_recalc_transform(window_t *win)
    9681186{
     
    9731191        transform_t scale;
    9741192        transform_identity(&scale);
    975         transform_scale(&scale, win->fx, win->fy);
     1193        if (win->fx != 1 || win->fy != 1) {
     1194                transform_scale(&scale, win->fx, win->fy);
     1195        }
    9761196
    9771197        transform_t rotate;
    9781198        transform_identity(&rotate);
    979         transform_rotate(&rotate, win->angle);
     1199        if (win->angle != 0) {
     1200                transform_rotate(&rotate, win->angle);
     1201        }
    9801202
    9811203        transform_t transform;
     
    9941216
    9951217static void comp_window_animate(pointer_t *pointer, window_t *win,
    996      sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
     1218    sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
    9971219{
    9981220        /* window_list_mtx locked by caller */
     1221        /* pointer_list_mtx locked by caller */
    9991222
    10001223        int dx = pointer->accum.x;
     
    10201243                }
    10211244
    1022                 if (scale || resize) {
     1245                if ((scale || resize) && (win->angle != 0)) {
    10231246                        transform_t rotate;
    10241247                        transform_identity(&rotate);
     
    10371260                double _dx = dx;
    10381261                double _dy = dy;
    1039                 transform_t unrotate;
    1040                 transform_identity(&unrotate);
    1041                 transform_rotate(&unrotate, -win->angle);
    1042                 transform_apply_linear(&unrotate, &_dx, &_dy);
     1262                if (win->angle != 0) {
     1263                        transform_t unrotate;
     1264                        transform_identity(&unrotate);
     1265                        transform_rotate(&unrotate, -win->angle);
     1266                        transform_apply_linear(&unrotate, &_dx, &_dy);
     1267                }
    10431268                _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    10441269                _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    10451270
    10461271                if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1047                         double fx = 1.0 + (_dx / (width * win->fx));
     1272                        double fx = 1.0 + (_dx / ((width - 1) * win->fx));
    10481273                        if (fx > 0) {
     1274#if ANIMATE_WINDOW_TRANSFORMS == 0
     1275                                if (scale) win->fx *= fx;
     1276#endif
     1277#if ANIMATE_WINDOW_TRANSFORMS == 1
    10491278                                win->fx *= fx;
     1279#endif
    10501280                                scale_back_x *= fx;
    10511281                        }
     
    10531283
    10541284                if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1055                         double fy = 1.0 + (_dy / (height * win->fy));
     1285                        double fy = 1.0 + (_dy / ((height - 1) * win->fy));
    10561286                        if (fy > 0) {
     1287#if ANIMATE_WINDOW_TRANSFORMS == 0
     1288                                if (scale) win->fy *= fy;
     1289#endif
     1290#if ANIMATE_WINDOW_TRANSFORMS == 1
    10571291                                win->fy *= fy;
     1292#endif
    10581293                                scale_back_y *= fy;
    10591294                        }
     
    10721307}
    10731308
     1309#if ANIMATE_WINDOW_TRANSFORMS == 0
     1310static void comp_ghost_animate(pointer_t *pointer,
     1311    desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4)
     1312{
     1313        /* window_list_mtx locked by caller */
     1314        /* pointer_list_mtx locked by caller */
     1315
     1316        int dx = pointer->accum_ghost.x;
     1317        int dy = pointer->accum_ghost.y;
     1318        pointer->accum_ghost.x = 0;
     1319        pointer->accum_ghost.y = 0;
     1320
     1321        bool move = (pointer->grab_flags & GF_MOVE_X) || (pointer->grab_flags & GF_MOVE_Y);
     1322        bool scale = (pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_SCALE_Y);
     1323        bool resize = (pointer->grab_flags & GF_RESIZE_X) || (pointer->grab_flags & GF_RESIZE_Y);
     1324
     1325        sysarg_t width, height;
     1326        surface_get_resolution(pointer->ghost.surface, &width, &height);
     1327
     1328        if (move) {
     1329                double cx = 0;
     1330                double cy = 0;
     1331                if (pointer->grab_flags & GF_MOVE_X) {
     1332                        cx = 1;
     1333                }
     1334                if (pointer->grab_flags & GF_MOVE_Y) {
     1335                        cy = 1;
     1336                }
     1337
     1338                if (scale || resize) {
     1339                        transform_t rotate;
     1340                        transform_identity(&rotate);
     1341                        transform_rotate(&rotate, pointer->ghost.angle);
     1342                        transform_apply_linear(&rotate, &cx, &cy);
     1343                }
     1344
     1345                cx = (cx < 0) ? (-1 * cx) : cx;
     1346                cy = (cy < 0) ? (-1 * cy) : cy;
     1347
     1348                pointer->ghost.dx += (cx * dx);
     1349                pointer->ghost.dy += (cy * dy);
     1350        }
     1351
     1352        if (scale || resize) {
     1353                double _dx = dx;
     1354                double _dy = dy;
     1355                transform_t unrotate;
     1356                transform_identity(&unrotate);
     1357                transform_rotate(&unrotate, -pointer->ghost.angle);
     1358                transform_apply_linear(&unrotate, &_dx, &_dy);
     1359                _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
     1360                _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
     1361
     1362                if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
     1363                        double fx = 1.0 + (_dx / ((width - 1) * pointer->ghost.fx));
     1364                        pointer->ghost.fx *= fx;
     1365                }
     1366
     1367                if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
     1368                        double fy = 1.0 + (_dy / ((height - 1) * pointer->ghost.fy));
     1369                        pointer->ghost.fy *= fy;
     1370                }
     1371        }
     1372
     1373        sysarg_t x1, y1, width1, height1;
     1374        sysarg_t x2, y2, width2, height2;
     1375        comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
     1376            &x1, &y1, &width1, &height1);
     1377        comp_recalc_transform(&pointer->ghost);
     1378        comp_coord_bounding_rect(0, 0, width, height, pointer->ghost.transform,
     1379            &x2, &y2, &width2, &height2);
     1380
     1381        sysarg_t x_u, y_u, w_u, h_u;
     1382        rectangle_union(x1, y1, width1, height1, x2, y2, width2, height2,
     1383            &x_u, &y_u, &w_u, &h_u);
     1384
     1385        sysarg_t x_i, y_i, w_i, h_i;
     1386        rectangle_intersect(x1, y1, width1, height1, x2, y2, width2, height2,
     1387            &x_i, &y_i, &w_i, &h_i);
     1388
     1389        if (w_i == 0 || h_i == 0) {
     1390                rect1->x = x_u; rect2->x = 0; rect3->x = 0; rect4->x = 0;
     1391                rect1->y = y_u; rect2->y = 0; rect3->y = 0; rect4->y = 0;
     1392                rect1->w = w_u; rect2->w = 0; rect3->w = 0; rect4->w = 0;
     1393                rect1->h = h_u; rect2->h = 0; rect3->h = 0; rect4->h = 0;
     1394        } else {
     1395                rect1->x = x_u;
     1396                rect1->y = y_u;
     1397                rect1->w = x_i - x_u + 1;
     1398                rect1->h = h_u;
     1399
     1400                rect2->x = x_u;
     1401                rect2->y = y_u;
     1402                rect2->w = w_u;
     1403                rect2->h = y_i - y_u + 1;
     1404
     1405                rect3->x = x_i + w_i - 1;
     1406                rect3->y = y_u;
     1407                rect3->w = w_u - w_i - x_i + x_u + 1;
     1408                rect3->h = h_u;
     1409               
     1410                rect4->x = x_u;
     1411                rect4->y = y_i + h_i - 1;
     1412                rect4->w = w_u;
     1413                rect4->h = h_u - h_i - y_i + y_u + 1;
     1414        }
     1415}
     1416#endif
     1417
    10741418static int comp_abs_move(input_t *input, unsigned x , unsigned y,
    10751419    unsigned max_x, unsigned max_y)
     
    11181462        surface_get_resolution(pointer->cursor.states[pointer->state],
    11191463             &cursor_width, &cursor_height);
     1464        if (pointer->pos.x + dx < viewport_bound_rect.x) {
     1465                dx = -1 * (pointer->pos.x - viewport_bound_rect.x);
     1466        }
     1467        if (pointer->pos.y + dy < viewport_bound_rect.y) {
     1468                dy = -1 * (pointer->pos.y - viewport_bound_rect.y);
     1469        }
     1470        if (pointer->pos.x + dx > viewport_bound_rect.x + viewport_bound_rect.w) {
     1471                dx = (viewport_bound_rect.x + viewport_bound_rect.w - pointer->pos.x);
     1472        }
     1473        if (pointer->pos.y + dy > viewport_bound_rect.y + viewport_bound_rect.h) {
     1474                dy = (viewport_bound_rect.y + viewport_bound_rect.h - pointer->pos.y);
     1475        }
    11201476        pointer->pos.x += dx;
    11211477        pointer->pos.y += dy;
     
    11251481
    11261482        fibril_mutex_lock(&window_list_mtx);
     1483        fibril_mutex_lock(&pointer_list_mtx);
    11271484        window_t *top = (window_t *) list_first(&window_list);
    11281485        if (top && top->surface) {
     
    11361493                        within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    11371494                            top->transform, width, height, &point_x, &point_y);
    1138                         fibril_mutex_unlock(&window_list_mtx);
    1139 
     1495
     1496                        window_event_t *event = NULL;
    11401497                        if (within_client) {
    1141                                 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     1498                                event = (window_event_t *) malloc(sizeof(window_event_t));
    11421499                                if (event) {
    11431500                                        link_initialize(&event->link);
     
    11481505                                        event->data.pos.hpos = point_x;
    11491506                                        event->data.pos.vpos = point_y;
    1150                                         comp_post_event(event);
    11511507                                }
    11521508                        }
     1509
     1510                        fibril_mutex_unlock(&pointer_list_mtx);
     1511                        fibril_mutex_unlock(&window_list_mtx);
     1512
     1513                        if (event) {
     1514                                comp_post_event_top(event);
     1515                        }
     1516
    11531517                } else {
    11541518                        /* Pointer is grabbed by top-level window action. */
    11551519                        pointer->accum.x += dx;
    11561520                        pointer->accum.y += dy;
     1521                        pointer->accum_ghost.x += dx;
     1522                        pointer->accum_ghost.y += dy;
     1523#if ANIMATE_WINDOW_TRANSFORMS == 0
     1524                        if (pointer->ghost.surface == NULL) {
     1525                                pointer->ghost.surface = top->surface;
     1526                                pointer->ghost.dx = top->dx;
     1527                                pointer->ghost.dy = top->dy;
     1528                                pointer->ghost.fx = top->fx;
     1529                                pointer->ghost.fy = top->fy;
     1530                                pointer->ghost.angle = top->angle;
     1531                                pointer->ghost.transform = top->transform;
     1532                        }
     1533                        desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
     1534                        comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
     1535#endif
    11571536#if ANIMATE_WINDOW_TRANSFORMS == 1
    11581537                        sysarg_t x, y, width, height;
    11591538                        comp_window_animate(pointer, top, &x, &y, &width, &height);
    11601539#endif
     1540                        fibril_mutex_unlock(&pointer_list_mtx);
    11611541                        fibril_mutex_unlock(&window_list_mtx);
     1542#if ANIMATE_WINDOW_TRANSFORMS == 0
     1543                        comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
     1544                        comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
     1545                        comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
     1546                        comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
     1547#endif
    11621548#if ANIMATE_WINDOW_TRANSFORMS == 1
    11631549                        comp_damage(x, y, width, height);
     
    11651551                }
    11661552        } else {
     1553                fibril_mutex_unlock(&pointer_list_mtx);
    11671554                fibril_mutex_unlock(&window_list_mtx);
    11681555        }
     
    11741561{
    11751562        pointer_t *pointer = input_pointer(input);
     1563
     1564        fibril_mutex_lock(&window_list_mtx);
     1565        fibril_mutex_lock(&pointer_list_mtx);
     1566        window_t *win = NULL;
     1567        sysarg_t point_x = 0;
     1568        sysarg_t point_y = 0;
     1569        sysarg_t width, height;
     1570        bool within_client = false;
     1571
     1572        /* Determine the window which the mouse click belongs to. */
     1573        list_foreach(window_list, link) {
     1574                win = list_get_instance(link, window_t, link);
     1575                if (win->surface) {
     1576                        surface_get_resolution(win->surface, &width, &height);
     1577                        within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
     1578                            win->transform, width, height, &point_x, &point_y);
     1579                }
     1580                if (within_client) {
     1581                        break;
     1582                }
     1583        }
     1584
     1585        /* Check whether the window is top-level window. */
     1586        window_t *top = (window_t *) list_first(&window_list);
     1587        if (!win || !top) {
     1588                fibril_mutex_unlock(&pointer_list_mtx);
     1589                fibril_mutex_unlock(&window_list_mtx);
     1590                return EOK;
     1591        }
     1592
     1593        window_event_t *event_top = NULL;
     1594        window_event_t *event_unfocus = NULL;
     1595        window_t *win_unfocus = NULL;
     1596        sysarg_t dmg_x, dmg_y;
     1597        sysarg_t dmg_width = 0;
     1598        sysarg_t dmg_height = 0;
     1599       
     1600#if ANIMATE_WINDOW_TRANSFORMS == 0
     1601        desktop_rect_t dmg_rect1, dmg_rect2, dmg_rect3, dmg_rect4;
     1602#endif
    11761603
    11771604        if (bpress) {
     
    11801607                pointer->pressed = true;
    11811608
    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. */
     1609                /* Bring the window to the foreground. */
     1610                if ((win != top) && within_client) {
     1611                        win_unfocus = (window_t *) list_first(&window_list);
     1612                        list_remove(&win->link);
     1613                        list_prepend(&win->link, &window_list);
     1614                        event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
     1615                        if (event_unfocus) {
     1616                                link_initialize(&event_unfocus->link);
     1617                                event_unfocus->type = ET_WINDOW_UNFOCUS;
     1618                        }
     1619                        comp_coord_bounding_rect(0, 0, width, height, win->transform,
     1620                            &dmg_x, &dmg_y, &dmg_width, &dmg_height);
     1621                }
     1622
     1623                /* Notify top-level window about mouse press. */
    11961624                if (within_client) {
    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                 }
     1625                        event_top = (window_event_t *) malloc(sizeof(window_event_t));
     1626                        if (event_top) {
     1627                                link_initialize(&event_top->link);
     1628                                event_top->type = ET_POSITION_EVENT;
     1629                                event_top->data.pos.pos_id = pointer->id;
     1630                                event_top->data.pos.type = POS_PRESS;
     1631                                event_top->data.pos.btn_num = bnum;
     1632                                event_top->data.pos.hpos = point_x;
     1633                                event_top->data.pos.vpos = point_y;
     1634                        }
     1635                        pointer->grab_flags = GF_EMPTY;
     1636                }
     1637
    12111638        } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
    12121639                pointer->pressed = false;
    12131640
    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 
     1641#if ANIMATE_WINDOW_TRANSFORMS == 0
    12471642                sysarg_t pre_x = 0;
    12481643                sysarg_t pre_y = 0;
     
    12501645                sysarg_t pre_height = 0;
    12511646
    1252 #if ANIMATE_WINDOW_TRANSFORMS == 0
    12531647                if (pointer->grab_flags != GF_EMPTY) {
     1648                        if (pointer->ghost.surface) {
     1649                                comp_ghost_animate(pointer, &dmg_rect1, &dmg_rect2, &dmg_rect3, &dmg_rect4);
     1650                                pointer->ghost.surface = NULL;
     1651                        }
    12541652                        comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height);
    12551653                        dmg_x = pre_x;
     
    12631661
    12641662                        surface_get_resolution(top->surface, &width, &height);
     1663#if ANIMATE_WINDOW_TRANSFORMS == 1
    12651664                        top->fx *= (1.0 / scale_back_x);
    12661665                        top->fy *= (1.0 / scale_back_y);
    12671666                        comp_recalc_transform(top);
     1667#endif
    12681668
    12691669                        /* Commit proper resize action. */
    1270                         event = (window_event_t *) malloc(sizeof(window_event_t));
    1271                         if (event) {
    1272                                 link_initialize(&event->link);
    1273                                 event->type = ET_WINDOW_RESIZE;
     1670                        event_top = (window_event_t *) malloc(sizeof(window_event_t));
     1671                        if (event_top) {
     1672                                link_initialize(&event_top->link);
     1673                                event_top->type = ET_WINDOW_RESIZE;
    12741674
    12751675                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
     
    12771677
    12781678                                if (pointer->grab_flags & GF_RESIZE_X) {
    1279                                         event->data.rsz.width =
     1679                                        event_top->data.rsz.width =
    12801680                                                ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    12811681                                } else {
    1282                                         event->data.rsz.width = width;
     1682                                        event_top->data.rsz.width = width;
    12831683                                }
    12841684
    12851685                                if (pointer->grab_flags & GF_RESIZE_Y) {
    1286                                         event->data.rsz.height =
     1686                                        event_top->data.rsz.height =
    12871687                                                ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    12881688                                } else {
    1289                                         event->data.rsz.height = height;
     1689                                        event_top->data.rsz.height = height;
    12901690                                }
    12911691                        }
     
    12961696                       
    12971697                        /* Notify top-level window about mouse release. */
    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;
     1698                        event_top = (window_event_t *) malloc(sizeof(window_event_t));
     1699                        if (event_top) {
     1700                                link_initialize(&event_top->link);
     1701                                event_top->type = ET_POSITION_EVENT;
     1702                                event_top->data.pos.pos_id = pointer->id;
     1703                                event_top->data.pos.type = POS_RELEASE;
     1704                                event_top->data.pos.btn_num = bnum;
     1705                                event_top->data.pos.hpos = point_x;
     1706                                event_top->data.pos.vpos = point_y;
    13071707                        }
    13081708                        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);
    13171709                       
    13181710                } else {
     
    13201712                }
    13211713
    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                 }
     1714        }
     1715
     1716        fibril_mutex_unlock(&pointer_list_mtx);
     1717        fibril_mutex_unlock(&window_list_mtx);
     1718
     1719#if ANIMATE_WINDOW_TRANSFORMS == 0
     1720                comp_damage(dmg_rect1.x, dmg_rect1.y, dmg_rect1.w, dmg_rect1.h);
     1721                comp_damage(dmg_rect2.x, dmg_rect2.y, dmg_rect2.w, dmg_rect2.h);
     1722                comp_damage(dmg_rect3.x, dmg_rect3.y, dmg_rect3.w, dmg_rect3.h);
     1723                comp_damage(dmg_rect4.x, dmg_rect4.y, dmg_rect4.w, dmg_rect4.h);
     1724#endif
     1725
     1726        if (dmg_width > 0 && dmg_height > 0) {
     1727                comp_damage(dmg_x, dmg_y, dmg_width, dmg_height);
     1728        }
     1729
     1730        if (event_unfocus && win_unfocus) {
     1731                comp_post_event_win(event_unfocus, win_unfocus);
     1732        }
     1733
     1734        if (event_top) {
     1735                comp_post_event_top(event_top);
    13311736        }
    13321737
     
    14521857
    14531858                        fibril_mutex_unlock(&window_list_mtx);
    1454                         comp_post_event(event);
     1859                        comp_post_event_top(event);
    14551860                } else {
    14561861                        fibril_mutex_unlock(&window_list_mtx);
     
    14941899                event->type = ET_WINDOW_CLOSE;
    14951900
    1496                 comp_post_event(event);
     1901                comp_post_event_top(event);
    14971902        } else if (win_switch) {
    14981903                fibril_mutex_lock(&window_list_mtx);
     
    15021907                        list_append(&win1->link, &window_list);
    15031908                        window_t *win2 = (window_t *) list_first(&window_list);
     1909
     1910                        window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t));
     1911                        if (event1) {
     1912                                link_initialize(&event1->link);
     1913                                event1->type = ET_WINDOW_UNFOCUS;
     1914                        }
     1915
     1916                        window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t));
     1917                        if (event2) {
     1918                                link_initialize(&event2->link);
     1919                                event2->type = ET_WINDOW_FOCUS;
     1920                        }
    15041921
    15051922                        sysarg_t x1 = 0;
     
    15301947
    15311948                        fibril_mutex_unlock(&window_list_mtx);
     1949
     1950                        if (event1 && win1) {
     1951                                comp_post_event_win(event1, win1);
     1952                        }
     1953
     1954                        if (event2 && win2) {
     1955                                comp_post_event_win(event2, win2);
     1956                        }
     1957
    15321958                        comp_damage(x, y, width, height);
    15331959                } else {
     
    15671993                        fibril_mutex_unlock(&viewport_list_mtx);
    15681994
     1995                        comp_restrict_pointers();
    15691996                        comp_damage(x, y, width, height);
    15701997                } else {
     
    16002027                fibril_mutex_lock(&window_list_mtx);
    16012028
    1602                 window_t *red_win = window_create();
     2029                window_t *red_win = window_create(0, 0);
    16032030                red_win->surface = surface_create(250, 150, NULL, 0);
    16042031                pixel_t red_pix = PIXEL(255, 240, 0, 0);
     
    16102037                list_prepend(&red_win->link, &window_list);
    16112038
    1612                 window_t *blue_win = window_create();
     2039                window_t *blue_win = window_create(0, 0);
    16132040                blue_win->surface = surface_create(200, 100, NULL, 0);
    16142041                pixel_t blue_pix = PIXEL(255, 0, 0, 240);
     
    16192046                }
    16202047                list_prepend(&blue_win->link, &window_list);
    1621 
    1622                 window_t *helenos_win = window_create();
    1623                 helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
    1624                 list_prepend(&helenos_win->link, &window_list);
    1625 
    1626                 window_t *nameic_win = window_create();
     2048               
     2049                window_t *nameic_win = window_create(0, 0);
    16272050                nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
    16282051                list_prepend(&nameic_win->link, &window_list);
     
    16422065                event->data.kbd.c = c;
    16432066
    1644                 comp_post_event(event);
     2067                comp_post_event_top(event);
    16452068        }
    16462069
     
    16932116static void input_disconnect(void)
    16942117{
    1695         pointer_t *pointer = input->user;
     2118        pointer_t *pointer = input->user;
    16962119        input_close(input);
    16972120        pointer_destroy(pointer);
     
    17062129{
    17072130        /* Coordinates of the central pixel. */
    1708         coord_origin = UINT32_MAX / 2;
     2131        coord_origin = UINT32_MAX / 4;
    17092132       
    17102133        /* Color of the viewport background. Must be opaque. */
     
    17832206                return -1;
    17842207        }
    1785        
     2208
     2209        comp_restrict_pointers();
    17862210        comp_damage(0, 0, UINT32_MAX, UINT32_MAX);
    17872211       
Note: See TracChangeset for help on using the changeset viewer.