Changes in / [ce60be1:69c1995] in mainline


Ignore:
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/fpu_context.c

    rce60be1 r69c1995  
    5757{
    5858        /* TODO: Zero all SSE, MMX etc. registers */
     59        /* Default value of SCR register is 0x1f80,
     60         * it masks all FPU exceptions*/
    5961        asm volatile (
    6062                "fninit\n"
  • kernel/arch/ia32/src/fpu_context.c

    rce60be1 r69c1995  
    3737#include <arch.h>
    3838#include <cpu.h>
     39
     40
     41/** x87 FPU scr values (P3+ MMX2) */
     42enum {
     43        X87_FLUSH_ZERO_FLAG = (1 << 15),
     44        X87_ROUND_CONTROL_MASK = (0x3 << 13),
     45        x87_ROUND_TO_NEAREST_EVEN = (0x0 << 13),
     46        X87_ROUND_DOWN_TO_NEG_INF = (0x1 << 13),
     47        X87_ROUND_UP_TO_POS_INF = (0x2 << 13),
     48        X87_ROUND_TO_ZERO = (0x3 << 13),
     49        X87_PRECISION_MASK = (1 << 12),
     50        X87_UNDERFLOW_MASK = (1 << 11),
     51        X87_OVERFLOW_MASK = (1 << 10),
     52        X87_ZERO_DIV_MASK = (1 << 9),
     53        X87_DENORMAL_OP_MASK = (1 << 8),
     54        X87_INVALID_OP_MASK = (1 << 7),
     55        X87_DENOM_ZERO_FLAG = (1 << 6),
     56        X87_PRECISION_EXC_FLAG = (1 << 5),
     57        X87_UNDERFLOW_EXC_FLAG = (1 << 4),
     58        X87_OVERFLOW_EXC_FLAG = (1 << 3),
     59        X87_ZERO_DIV_EXC_FLAG = (1 << 2),
     60        X87_DENORMAL_EXC_FLAG = (1 << 1),
     61        X87_INVALID_OP_EXC_FLAG = (1 << 0),
     62
     63        X87_ALL_MASK = X87_PRECISION_MASK | X87_UNDERFLOW_MASK | X87_OVERFLOW_MASK | X87_ZERO_DIV_MASK | X87_DENORMAL_OP_MASK | X87_INVALID_OP_MASK,
     64};
     65
    3966
    4067typedef void (*fpu_context_function)(fpu_context_t *fctx);
     
    98125}
    99126
     127/** Initialize x87 FPU. Mask all exceptions. */
    100128void fpu_init()
    101129{
     
    111139                "ldmxcsr %[help0]\n"
    112140                : [help0] "+m" (help0), [help1] "+r" (help1)
    113                 : [magic] "i" (0x1f80)
     141                : [magic] "i" (X87_ALL_MASK)
    114142        );
    115143}
  • uspace/app/vdemo/vdemo.c

    rce60be1 r69c1995  
    110110{
    111111        if (argc >= 2) {
    112                 window_t *main_window = window_open(argv[1], true, true, "vdemo");
     112                window_t *main_window = window_open(argv[1], true, true, "vdemo", 0, 0);
    113113                if (!main_window) {
    114114                        printf("Cannot open main window.\n");
  • uspace/app/vlaunch/vlaunch.c

    rce60be1 r69c1995  
    9898       
    9999        winreg = argv[1];
    100         window_t *main_window = window_open(argv[1], true, true, "vlaunch");
     100        window_t *main_window = window_open(argv[1], true, true, "vlaunch", 0, 0);
    101101        if (!main_window) {
    102102                printf("Cannot open main window.\n");
  • uspace/app/vterm/vterm.c

    rce60be1 r69c1995  
    4949        }
    5050       
    51         window_t *main_window = window_open(argv[1], true, true, "vterm");
     51        window_t *main_window = window_open(argv[1], true, true, "vterm", 0, 0);
    5252        if (!main_window) {
    5353                printf("%s: Cannot open main window.\n", NAME);
  • uspace/drv/fb/kfb/port.c

    rce60be1 r69c1995  
    163163                /* Faster damage routine ignoring offsets. */
    164164                for (sysarg_t y = y0; y < height + y0; ++y) {
     165                        pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
    165166                        for (sysarg_t x = x0; x < width + x0; ++x) {
    166                                 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
    167                                     *pixelmap_pixel_at(map, x, y));
     167                                kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
    168168                        }
    169169                }
  • uspace/lib/c/generic/io/window.c

    rce60be1 r69c1995  
    4040#include <stdio.h>
    4141
    42 int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
     42int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out,
     43    sysarg_t x_offset, sysarg_t y_offset)
    4344{
    4445        async_exch_t *exch = async_exchange_begin(sess);
    45         int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
     46        int ret = async_req_2_2(exch, WINDOW_REGISTER, x_offset, y_offset, in, out);
    4647        async_exchange_end(exch);
    4748
  • uspace/lib/c/generic/stdlib.c

    rce60be1 r69c1995  
    3939long int random(void)
    4040{
    41         return glbl_seed = ((1366*glbl_seed + 150889) % RAND_MAX);
     41        return glbl_seed = ((1366 * glbl_seed + 150889) % RAND_MAX);
    4242}
    4343
    4444void srandom(unsigned int seed)
    4545{
    46         glbl_seed = seed;
     46        glbl_seed = seed % RAND_MAX;
    4747}
    4848
  • uspace/lib/c/include/io/pixel.h

    rce60be1 r69c1995  
    4242        ((channel) >> (8 - (bits)))
    4343
     44#define INVERT(pixel) ((pixel) ^ 0x00ffffff)
     45
    4446#define ALPHA(pixel)  ((pixel) >> 24)
    4547#define RED(pixel)    (((pixel) & 0x00ff0000) >> 16)
  • uspace/lib/c/include/io/pixelmap.h

    rce60be1 r69c1995  
    5252    sysarg_t y)
    5353{
    54         size_t offset = y * pixelmap->width + x;
    55         pixel_t *pixel = pixelmap->data + offset;
    56         return pixel;
     54        if (x < pixelmap->width && y < pixelmap->height) {
     55                size_t offset = y * pixelmap->width + x;
     56                pixel_t *pixel = pixelmap->data + offset;
     57                return pixel;
     58        } else {
     59                return NULL;
     60        }
    5761}
    5862
  • uspace/lib/c/include/io/window.h

    rce60be1 r69c1995  
    7171        ET_POSITION_EVENT,
    7272        ET_SIGNAL_EVENT,
     73        ET_WINDOW_FOCUS,
     74        ET_WINDOW_UNFOCUS,
    7375        ET_WINDOW_RESIZE,
    7476        ET_WINDOW_REFRESH,
     
    100102} window_grab_flags_t;
    101103
    102 extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
     104extern int win_register(async_sess_t *, service_id_t *, service_id_t *, sysarg_t, sysarg_t);
    103105
    104106extern int win_get_event(async_sess_t *, window_event_t *);
  • uspace/lib/draw/drawctx.c

    rce60be1 r69c1995  
    129129        }
    130130
    131         bool clipped = false;
    132         bool masked = false;
    133 
    134         for (sysarg_t _y = y; _y < y + height; ++_y) {
    135                 for (sysarg_t _x = x; _x < x + width; ++_x) {
    136                         if (context->shall_clip) {
    137                                 clipped = _x < context->clip_x && _x >= context->clip_width
    138                                     && _y < context->clip_y && _y >= context->clip_height;
    139                         }
    140                        
    141                         if (context->mask) {
    142                                 pixel_t p = surface_get_pixel(context->mask, _x, _y);
    143                                 masked = p > 0 ? false : true;
    144                         }
    145 
    146                         if (!clipped && !masked) {
    147                                 pixel_t p_src = source_determine_pixel(context->source, _x, _y);
    148                                 pixel_t p_dst = surface_get_pixel(context->surface, _x, _y);
    149                                 pixel_t p_res = context->compose(p_src, p_dst);
    150                                 surface_put_pixel(context->surface, _x, _y, p_res);
     131        bool transfer_fast = source_is_fast(context->source)
     132            && (context->shall_clip == false)
     133            && (context->mask == NULL)
     134            && (context->compose == compose_src || context->compose == compose_over);
     135
     136        if (transfer_fast) {
     137
     138                for (sysarg_t _y = y; _y < y + height; ++_y) {
     139                        pixel_t *src = source_direct_access(context->source, x, _y);
     140                        pixel_t *dst = pixelmap_pixel_at(surface_pixmap_access(context->surface), x, _y);
     141                        if (src && dst) {
     142                                sysarg_t count = width;
     143                                while (count-- != 0) {
     144                                        *dst++ = *src++;
     145                                }
    151146                        }
    152147                }
     148                surface_add_damaged_region(context->surface, x, y, width, height);
     149
     150        } else {
     151
     152                bool clipped = false;
     153                bool masked = false;
     154                for (sysarg_t _y = y; _y < y + height; ++_y) {
     155                        for (sysarg_t _x = x; _x < x + width; ++_x) {
     156                                if (context->shall_clip) {
     157                                        clipped = _x < context->clip_x && _x >= context->clip_width
     158                                            && _y < context->clip_y && _y >= context->clip_height;
     159                                }
     160
     161                                if (context->mask) {
     162                                        pixel_t p = surface_get_pixel(context->mask, _x, _y);
     163                                        masked = p > 0 ? false : true;
     164                                }
     165
     166                                if (!clipped && !masked) {
     167                                        pixel_t p_src = source_determine_pixel(context->source, _x, _y);
     168                                        pixel_t p_dst = surface_get_pixel(context->surface, _x, _y);
     169                                        pixel_t p_res = context->compose(p_src, p_dst);
     170                                        surface_put_pixel(context->surface, _x, _y, p_res);
     171                                }
     172                        }
     173                }
     174
    153175        }
    154176}
  • uspace/lib/draw/source.c

    rce60be1 r69c1995  
    9090}
    9191
     92bool source_is_fast(source_t *source)
     93{
     94        return (source->mask == NULL)
     95            && (source->alpha == (pixel_t) PIXEL(255, 0, 0, 0))
     96            && (source->texture != NULL)
     97            && (source->texture_tile == false)
     98            && transform_is_fast(&source->transform);
     99}
     100
     101pixel_t *source_direct_access(source_t *source, double x, double y)
     102{
     103        assert(source_is_fast(source));
     104
     105        long _x = (long) (x + source->transform.m[0][2]);
     106        long _y = (long) (y + source->transform.m[1][2]);
     107
     108        return pixelmap_pixel_at(
     109            surface_pixmap_access(source->texture), (sysarg_t) _x, (sysarg_t) _y);
     110}
     111
    92112pixel_t source_determine_pixel(source_t *source, double x, double y)
    93113{
  • uspace/lib/draw/source.h

    rce60be1 r69c1995  
    7171extern void source_set_mask(source_t *, surface_t *, bool);
    7272
     73extern bool source_is_fast(source_t *);
     74extern pixel_t *source_direct_access(source_t *, double, double);
    7375extern pixel_t source_determine_pixel(source_t *, double, double);
    7476
  • uspace/lib/draw/surface.c

    rce60be1 r69c1995  
    143143}
    144144
     145void surface_add_damaged_region(surface_t *surface, surface_coord_t x, surface_coord_t y,
     146    surface_coord_t width, surface_coord_t height)
     147{
     148        surface->dirty_x_lo = surface->dirty_x_lo > x ? x : surface->dirty_x_lo;
     149        surface->dirty_y_lo = surface->dirty_y_lo > y ? y : surface->dirty_y_lo;
     150
     151        surface_coord_t x_hi = x + width - 1;
     152        surface_coord_t y_hi = y + height - 1;
     153
     154        surface->dirty_x_hi = surface->dirty_x_hi < x_hi ? x_hi : surface->dirty_x_hi;
     155        surface->dirty_y_hi = surface->dirty_y_hi < y_hi ? y_hi : surface->dirty_y_hi;
     156}
     157
    145158void surface_reset_damaged_region(surface_t *surface)
    146159{
     
    158171        surface->dirty_y_hi = surface->dirty_y_hi < y ? y : surface->dirty_y_hi;
    159172
    160         if (x < surface->pixmap.width && y < surface->pixmap.height) {
    161                 pixelmap_put_pixel(&surface->pixmap, x, y, pixel);
    162         }
     173        pixelmap_put_pixel(&surface->pixmap, x, y, pixel);
    163174}
    164175
    165176pixel_t surface_get_pixel(surface_t *surface, surface_coord_t x, surface_coord_t y)
    166177{
    167         if (x < surface->pixmap.width && y < surface->pixmap.height) {
    168                 return pixelmap_get_pixel(&surface->pixmap, x, y);
    169         } else {
    170                 return 0;
    171         }
     178        return pixelmap_get_pixel(&surface->pixmap, x, y);
    172179}
    173180
  • uspace/lib/draw/surface.h

    rce60be1 r69c1995  
    6161extern void surface_get_damaged_region(surface_t *, surface_coord_t *, surface_coord_t *,
    6262    surface_coord_t *, surface_coord_t *);
     63extern void surface_add_damaged_region(surface_t *, surface_coord_t , surface_coord_t ,
     64    surface_coord_t , surface_coord_t );
    6365extern void surface_reset_damaged_region(surface_t *);
    6466
  • uspace/lib/gui/terminal.c

    rce60be1 r69c1995  
    196196        uint16_t glyph = fb_font_glyph(field->ch);
    197197       
    198         // FIXME: This font drawing routine is shamelessly
    199         //        suboptimal. It should be optimized for
    200         //        aligned memory transfers, etc.
    201        
    202198        for (unsigned int y = 0; y < FONT_SCANLINES; y++) {
    203                 for (unsigned int x = 0; x < FONT_WIDTH; x++) {
    204                         pixel_t pixel =
    205                             (fb_font[glyph][y] & (1 << (7 - x))) ? fgcolor : bgcolor;
    206                         surface_put_pixel(surface, bx + x, by + y, pixel);
     199                pixel_t *dst = pixelmap_pixel_at(
     200                    surface_pixmap_access(surface), bx, by + y);
     201                pixel_t *dst_max = pixelmap_pixel_at(
     202                    surface_pixmap_access(surface), bx + FONT_WIDTH - 1, by + y);
     203                if (!dst || !dst_max) continue;
     204                int count = FONT_WIDTH;
     205                while (count-- != 0) {
     206                        *dst++ = (fb_font[glyph][y] & (1 << count)) ? fgcolor : bgcolor;
    207207                }
    208208        }
     209        surface_add_damaged_region(surface, bx, by, FONT_WIDTH, FONT_SCANLINES);
    209210}
    210211
  • uspace/lib/gui/window.c

    rce60be1 r69c1995  
    6666
    6767static pixel_t border_color = PIXEL(255, 0, 0, 0);
    68 static pixel_t header_bgcolor = PIXEL(255, 25, 25, 112);
    69 static pixel_t header_fgcolor = PIXEL(255, 255, 255, 255);
     68static pixel_t header_bg_focus_color = PIXEL(255, 25, 25, 112);
     69static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
     70static pixel_t header_bg_unfocus_color = PIXEL(255, 70, 130, 180);
     71static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
    7072
    7173static void paint_internal(widget_t *w)
     
    9496            w->vpos + w->height - border_thickness, w->width, border_thickness);
    9597
    96         source_set_color(&source, header_bgcolor);
     98        source_set_color(&source,
     99            w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
    97100        drawctx_transfer(&drawctx,
    98101            w->hpos + border_thickness, w->vpos + border_thickness,
     
    106109        char cls_pict[] = "x";
    107110        font_get_box(&font, cls_pict, &cls_width, &cls_height);
    108         source_set_color(&source, header_fgcolor);
     111        source_set_color(&source,
     112            w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
    109113        sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
    110114            border_thickness - close_width;
     
    447451                        break;
    448452                case ET_POSITION_EVENT:
     453                        if (!win->is_focused) {
     454                                win->is_focused = true;
     455                                handle_refresh(win);
     456                        }
    449457                        deliver_position_event(win, event->data.pos);
    450458                        break;
     
    454462                case ET_WINDOW_RESIZE:
    455463                        handle_resize(win, event->data.rsz.width, event->data.rsz.height);
     464                        break;
     465                case ET_WINDOW_FOCUS:
     466                        if (!win->is_focused) {
     467                                win->is_focused = true;
     468                                handle_refresh(win);
     469                        }
     470                        break;
     471                case ET_WINDOW_UNFOCUS:
     472                        if (win->is_focused) {
     473                                win->is_focused = false;
     474                                handle_refresh(win);
     475                        }
    456476                        break;
    457477                case ET_WINDOW_REFRESH:
     
    514534}
    515535
    516 window_t *window_open(char *winreg, bool is_main, bool is_decorated, const char *caption)
     536window_t *window_open(char *winreg, bool is_main, bool is_decorated,
     537    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
    517538{
    518539        int rc;
     
    525546        win->is_main = is_main;
    526547        win->is_decorated = is_decorated;
     548        win->is_focused = true;
    527549        prodcons_initialize(&win->events);
    528550        fibril_mutex_initialize(&win->guard);
     
    557579        service_id_t out_dsid;
    558580       
    559         rc = win_register(reg_sess, &in_dsid, &out_dsid);
     581        rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
    560582        async_hangup(reg_sess);
    561583        if (rc != EOK) {
  • uspace/lib/gui/window.h

    rce60be1 r69c1995  
    5050        bool is_main; /**< True for the main window of the application. */
    5151        bool is_decorated; /**< True if the window decorations should be rendered. */
     52        bool is_focused; /**< True for the top level window of the desktop. */
    5253        char *caption; /**< Text title of the window header. */
    5354        async_sess_t *isess; /**< Input events from compositor. */
     
    6566 * If the window is declared as main, its closure causes termination of the
    6667 * whole application. Note that opened window does not have any surface yet. */
    67 extern window_t *window_open(char *, bool, bool, const char *);
     68extern window_t *window_open(char *, bool, bool, const char *, sysarg_t, sysarg_t);
    6869
    6970/**
  • uspace/lib/softrend/filter.c

    rce60be1 r69c1995  
    4444                _x %= pixmap->width;
    4545                _y %= pixmap->height;
    46         } else if (_x < 0 || _x >= (long) pixmap->width || _y < 0 || _y >= (long) pixmap->height) {
    47                 return 0;
    4846        }
    4947
  • uspace/lib/softrend/transform.c

    rce60be1 r69c1995  
    136136}
    137137
     138bool transform_is_fast(transform_t *t)
     139{
     140        return (t->m[0][0] == 1) && (t->m[0][1] == 0)
     141            && (t->m[1][0] == 0) && (t->m[1][1] == 1)
     142            && ((t->m[0][2] - ((long) t->m[0][2])) == 0.0)
     143            && ((t->m[1][2] - ((long) t->m[1][2])) == 0.0);
     144}
     145
    138146void transform_apply_linear(const transform_t *t, double *x, double *y)
    139147{
  • uspace/lib/softrend/transform.h

    rce60be1 r69c1995  
    3737#define SOFTREND_TRANSFORM_H_
    3838
     39#include <bool.h>
     40
    3941#ifndef PI
    4042#define PI 3.141592653589793
     
    5355extern void transform_rotate(transform_t *, double);
    5456
     57extern bool transform_is_fast(transform_t *);
     58
    5559extern void transform_apply_linear(const transform_t *, double *, double *);
    5660extern void transform_apply_affine(const transform_t *, double *, double *);
  • uspace/srv/hid/compositor/compositor.c

    rce60be1 r69c1995  
    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;
    10992        service_id_t in_dsid;
    11093        service_id_t out_dsid;
     
    129112typedef struct {
    130113        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
     127static sysarg_t pointer_id = 0;
     128static FIBRIL_MUTEX_INITIALIZE(pointer_list_mtx);
     129static LIST_INITIALIZE(pointer_list);
     130
     131typedef struct {
     132        link_t link;
    131133        service_id_t dsid;
    132134        vslmode_t mode;
     
    181183        cursor_init(&p->cursor, CURSOR_DECODER_EMBEDDED, NULL);
    182184
     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
    183198        return p;
    184199}
     
    192207}
    193208
    194 static window_t *window_create()
     209static window_t *window_create(sysarg_t x_offset, sysarg_t y_offset)
    195210{
    196211        window_t *win = (window_t *) malloc(sizeof(window_t));
     
    202217        prodcons_initialize(&win->queue);
    203218        transform_identity(&win->transform);
    204         transform_translate(&win->transform, coord_origin, coord_origin);
    205         win->dx = coord_origin;
    206         win->dy = coord_origin;
     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;
    207223        win->fx = 1;
    208224        win->fy = 1;
     
    267283    sysarg_t *x_out, sysarg_t *y_out, sysarg_t *w_out, sysarg_t *h_out)
    268284{
    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);
     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        }
    287308}
    288309
     
    309330                        /* Paint background color. */
    310331                        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);
     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;
    313337                                }
    314338                        }
     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);
    315341
    316342                        transform_t transform;
     
    363389                        list_foreach(pointer_list, link) {
    364390
     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
    365467                                /* Determine what part of the pointer intersects with the
    366468                                 * updated area of the current viewport. */
     
    376478                                if (isec_ptr) {
    377479                                        /* Pointer is currently painted directly by copying pixels.
    378                                          * However, it is possible to draw the painter similarly
     480                                         * However, it is possible to draw the pointer similarly
    379481                                         * as window by using drawctx_transfer. It would allow
    380482                                         * more sophisticated control over drawing, but would also
    381483                                         * cost more regarding the performance. */
    382484
    383                                         pixel_t pix = 0;
    384485                                        sysarg_t x_vp = x_dmg_ptr - vp->pos.x;
    385486                                        sysarg_t y_vp = y_dmg_ptr - vp->pos.y;
     
    388489
    389490                                        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                                                         }
     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;
    395499                                                }
    396500                                        }
     501                                        surface_add_damaged_region(vp->surface, x_vp, y_vp, w_dmg_ptr, h_dmg_ptr);
    397502                                }
     503
    398504                        }
    399505                }
     
    450556        } else {
    451557                fibril_mutex_lock(&window_list_mtx);
    452                 comp_coord_bounding_rect(x, y, width, height,
     558                comp_coord_bounding_rect(x - 1, y - 1, width + 2, height + 2,
    453559                    win->transform, &x, &y, &width, &height);
    454560                fibril_mutex_unlock(&window_list_mtx);
     
    468574                pointer_t *pointer = list_get_instance(link, pointer_t, link);
    469575                if (pointer->id == pos_id) {
    470                         pointer->grab_flags = grab_flags;
     576                        pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
    471577                        // TODO change pointer->state according to grab_flags
    472578                        break;
     
    541647}
    542648
     649static 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
     665static 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
    543677static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
    544678{
     
    546680        fibril_mutex_lock(&window_list_mtx);
    547681        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        }
    548688        fibril_mutex_unlock(&window_list_mtx);
     689
     690        if (event_focus && win_focus) {
     691                comp_post_event_win(event_focus, win_focus);
     692        }
    549693
    550694        /* Calculate damage. */
     
    601745                        fibril_mutex_lock(&window_list_mtx);
    602746
    603                         window_t *win = window_create();
     747                        window_t *win = window_create(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
    604748                        if (!win) {
    605749                                async_answer_2(callid, ENOMEM, 0, 0);
     
    630774                        }
    631775
     776                        window_t *win_unfocus = (window_t *) list_first(&window_list);
    632777                        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                        }
    633784                       
    634785                        async_answer_2(callid, EOK, win->in_dsid, win->out_dsid);
    635786                        fibril_mutex_unlock(&window_list_mtx);
     787                       
     788                        if (event_unfocus && win_unfocus) {
     789                                comp_post_event_win(event_unfocus, win_unfocus);
     790                        }
     791
    636792                        return;
    637793                } else {
     
    9531109}
    9541110
    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 
    9671111static void comp_recalc_transform(window_t *win)
    9681112{
     
    9731117        transform_t scale;
    9741118        transform_identity(&scale);
    975         transform_scale(&scale, win->fx, win->fy);
     1119        if (win->fx != 1 || win->fy != 1) {
     1120                transform_scale(&scale, win->fx, win->fy);
     1121        }
    9761122
    9771123        transform_t rotate;
    9781124        transform_identity(&rotate);
    979         transform_rotate(&rotate, win->angle);
     1125        if (win->angle != 0) {
     1126                transform_rotate(&rotate, win->angle);
     1127        }
    9801128
    9811129        transform_t transform;
     
    9941142
    9951143static 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)
     1144    sysarg_t *dmg_x, sysarg_t *dmg_y, sysarg_t *dmg_width, sysarg_t *dmg_height)
    9971145{
    9981146        /* window_list_mtx locked by caller */
     1147        /* pointer_list_mtx locked by caller */
    9991148
    10001149        int dx = pointer->accum.x;
     
    10201169                }
    10211170
    1022                 if (scale || resize) {
     1171                if ((scale || resize) && (win->angle != 0)) {
    10231172                        transform_t rotate;
    10241173                        transform_identity(&rotate);
     
    10371186                double _dx = dx;
    10381187                double _dy = dy;
    1039                 transform_t unrotate;
    1040                 transform_identity(&unrotate);
    1041                 transform_rotate(&unrotate, -win->angle);
    1042                 transform_apply_linear(&unrotate, &_dx, &_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                }
    10431194                _dx = (pointer->grab_flags & GF_MOVE_X) ? -_dx : _dx;
    10441195                _dy = (pointer->grab_flags & GF_MOVE_Y) ? -_dy : _dy;
    10451196
    10461197                if ((pointer->grab_flags & GF_SCALE_X) || (pointer->grab_flags & GF_RESIZE_X)) {
    1047                         double fx = 1.0 + (_dx / (width * win->fx));
     1198                        double fx = 1.0 + (_dx / ((width - 1) * win->fx));
    10481199                        if (fx > 0) {
     1200#if ANIMATE_WINDOW_TRANSFORMS == 0
     1201                                if (scale) win->fx *= fx;
     1202#endif
     1203#if ANIMATE_WINDOW_TRANSFORMS == 1
    10491204                                win->fx *= fx;
     1205#endif
    10501206                                scale_back_x *= fx;
    10511207                        }
     
    10531209
    10541210                if ((pointer->grab_flags & GF_SCALE_Y) || (pointer->grab_flags & GF_RESIZE_Y)) {
    1055                         double fy = 1.0 + (_dy / (height * win->fy));
     1211                        double fy = 1.0 + (_dy / ((height - 1) * win->fy));
    10561212                        if (fy > 0) {
     1213#if ANIMATE_WINDOW_TRANSFORMS == 0
     1214                                if (scale) win->fy *= fy;
     1215#endif
     1216#if ANIMATE_WINDOW_TRANSFORMS == 1
    10571217                                win->fy *= fy;
     1218#endif
    10581219                                scale_back_y *= fy;
    10591220                        }
     
    10711232            dmg_x, dmg_y, dmg_width, dmg_height);
    10721233}
     1234
     1235#if ANIMATE_WINDOW_TRANSFORMS == 0
     1236static 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
    10731343
    10741344static int comp_abs_move(input_t *input, unsigned x , unsigned y,
     
    11251395
    11261396        fibril_mutex_lock(&window_list_mtx);
     1397        fibril_mutex_lock(&pointer_list_mtx);
    11271398        window_t *top = (window_t *) list_first(&window_list);
    11281399        if (top && top->surface) {
     
    11361407                        within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
    11371408                            top->transform, width, height, &point_x, &point_y);
    1138                         fibril_mutex_unlock(&window_list_mtx);
    1139 
     1409
     1410                        window_event_t *event = NULL;
    11401411                        if (within_client) {
    1141                                 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     1412                                event = (window_event_t *) malloc(sizeof(window_event_t));
    11421413                                if (event) {
    11431414                                        link_initialize(&event->link);
     
    11481419                                        event->data.pos.hpos = point_x;
    11491420                                        event->data.pos.vpos = point_y;
    1150                                         comp_post_event(event);
    11511421                                }
    11521422                        }
     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
    11531431                } else {
    11541432                        /* Pointer is grabbed by top-level window action. */
    11551433                        pointer->accum.x += dx;
    11561434                        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
    11571450#if ANIMATE_WINDOW_TRANSFORMS == 1
    11581451                        sysarg_t x, y, width, height;
    11591452                        comp_window_animate(pointer, top, &x, &y, &width, &height);
    11601453#endif
     1454                        fibril_mutex_unlock(&pointer_list_mtx);
    11611455                        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
    11621462#if ANIMATE_WINDOW_TRANSFORMS == 1
    11631463                        comp_damage(x, y, width, height);
     
    11651465                }
    11661466        } else {
     1467                fibril_mutex_unlock(&pointer_list_mtx);
    11671468                fibril_mutex_unlock(&window_list_mtx);
    11681469        }
     
    11741475{
    11751476        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
    11761517
    11771518        if (bpress) {
     
    11801521                pointer->pressed = true;
    11811522
    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. */
     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. */
    11961538                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                 }
     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
    12111552        } else if (pointer->pressed && pointer->btn_num == (unsigned)bnum) {
    12121553                pointer->pressed = false;
    12131554
    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 
     1555#if ANIMATE_WINDOW_TRANSFORMS == 0
    12471556                sysarg_t pre_x = 0;
    12481557                sysarg_t pre_y = 0;
     
    12501559                sysarg_t pre_height = 0;
    12511560
    1252 #if ANIMATE_WINDOW_TRANSFORMS == 0
    12531561                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                        }
    12541566                        comp_window_animate(pointer, top, &pre_x, &pre_y, &pre_width, &pre_height);
    12551567                        dmg_x = pre_x;
     
    12631575
    12641576                        surface_get_resolution(top->surface, &width, &height);
     1577#if ANIMATE_WINDOW_TRANSFORMS == 1
    12651578                        top->fx *= (1.0 / scale_back_x);
    12661579                        top->fy *= (1.0 / scale_back_y);
    12671580                        comp_recalc_transform(top);
     1581#endif
    12681582
    12691583                        /* 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;
     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;
    12741588
    12751589                                int dx = (int) (((double) width) * (scale_back_x - 1.0));
     
    12771591
    12781592                                if (pointer->grab_flags & GF_RESIZE_X) {
    1279                                         event->data.rsz.width =
     1593                                        event_top->data.rsz.width =
    12801594                                                ((((int) width) + dx) >= 0) ? (width + dx) : 0;
    12811595                                } else {
    1282                                         event->data.rsz.width = width;
     1596                                        event_top->data.rsz.width = width;
    12831597                                }
    12841598
    12851599                                if (pointer->grab_flags & GF_RESIZE_Y) {
    1286                                         event->data.rsz.height =
     1600                                        event_top->data.rsz.height =
    12871601                                                ((((int) height) + dy) >= 0) ? (height + dy) : 0;
    12881602                                } else {
    1289                                         event->data.rsz.height = height;
     1603                                        event_top->data.rsz.height = height;
    12901604                                }
    12911605                        }
     
    12961610                       
    12971611                        /* 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;
     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;
    13071621                        }
    13081622                        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);
    13171623                       
    13181624                } else {
     
    13201626                }
    13211627
    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                 }
     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);
    13311650        }
    13321651
     
    14521771
    14531772                        fibril_mutex_unlock(&window_list_mtx);
    1454                         comp_post_event(event);
     1773                        comp_post_event_top(event);
    14551774                } else {
    14561775                        fibril_mutex_unlock(&window_list_mtx);
     
    14941813                event->type = ET_WINDOW_CLOSE;
    14951814
    1496                 comp_post_event(event);
     1815                comp_post_event_top(event);
    14971816        } else if (win_switch) {
    14981817                fibril_mutex_lock(&window_list_mtx);
     
    15021821                        list_append(&win1->link, &window_list);
    15031822                        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                        }
    15041835
    15051836                        sysarg_t x1 = 0;
     
    15301861
    15311862                        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
    15321872                        comp_damage(x, y, width, height);
    15331873                } else {
     
    16001940                fibril_mutex_lock(&window_list_mtx);
    16011941
    1602                 window_t *red_win = window_create();
     1942                window_t *red_win = window_create(0, 0);
    16031943                red_win->surface = surface_create(250, 150, NULL, 0);
    16041944                pixel_t red_pix = PIXEL(255, 240, 0, 0);
     
    16101950                list_prepend(&red_win->link, &window_list);
    16111951
    1612                 window_t *blue_win = window_create();
     1952                window_t *blue_win = window_create(0, 0);
    16131953                blue_win->surface = surface_create(200, 100, NULL, 0);
    16141954                pixel_t blue_pix = PIXEL(255, 0, 0, 240);
     
    16201960                list_prepend(&blue_win->link, &window_list);
    16211961
    1622                 window_t *helenos_win = window_create();
     1962                window_t *helenos_win = window_create(0, 0);
    16231963                helenos_win->surface = decode_tga((void *) helenos_tga, helenos_tga_size, 0);
    16241964                list_prepend(&helenos_win->link, &window_list);
    16251965
    1626                 window_t *nameic_win = window_create();
     1966                window_t *nameic_win = window_create(0, 0);
    16271967                nameic_win->surface = decode_tga((void *) nameic_tga, nameic_tga_size, 0);
    16281968                list_prepend(&nameic_win->link, &window_list);
     
    16421982                event->data.kbd.c = c;
    16431983
    1644                 comp_post_event(event);
     1984                comp_post_event_top(event);
    16451985        }
    16461986
     
    16932033static void input_disconnect(void)
    16942034{
    1695         pointer_t *pointer = input->user;
     2035        pointer_t *pointer = input->user;
    16962036        input_close(input);
    16972037        pointer_destroy(pointer);
     
    17062046{
    17072047        /* Coordinates of the central pixel. */
    1708         coord_origin = UINT32_MAX / 2;
     2048        coord_origin = UINT32_MAX / 4;
    17092049       
    17102050        /* Color of the viewport background. Must be opaque. */
  • uspace/srv/hid/compositor/compositor.h

    rce60be1 r69c1995  
    4343typedef desktop_point_t desktop_vector_t;
    4444
     45typedef struct {
     46        desktop_coord_t x;
     47        desktop_coord_t y;
     48        desktop_coord_t w;
     49        desktop_coord_t h;
     50} desktop_rect_t;
     51
    4552/* TODO remove? */
    4653typedef struct {
Note: See TracChangeset for help on using the changeset viewer.