Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gui/window.c

    r21eeb653 r61b5b73d  
    5656#include <surface.h>
    5757
     58#include "common.h"
    5859#include "connection.h"
    5960#include "widget.h"
    6061#include "window.h"
    6162
    62 static sysarg_t border_thickness = 5;
     63static sysarg_t border_thickness = 4;
     64static sysarg_t bevel_thickness = 1;
    6365static sysarg_t header_height = 20;
    6466static sysarg_t header_min_width = 40;
    65 static sysarg_t close_width = 20;
    66 
    67 static pixel_t border_color = PIXEL(255, 0, 0, 0);
    68 static pixel_t header_bg_focus_color = PIXEL(255, 25, 25, 112);
    69 static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
    70 static pixel_t header_bg_unfocus_color = PIXEL(255, 70, 130, 180);
    71 static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
    72 
    73 static void paint_internal(widget_t *w)
    74 {
    75         surface_t *surface = window_claim(w->window);
    76         if (!surface) {
    77                 window_yield(w->window);
    78         }
    79 
     67static sysarg_t close_thickness = 20;
     68
     69static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
     70static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
     71static pixel_t color_surface = PIXEL(255, 186, 186, 186);
     72
     73static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
     74static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
     75static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
     76
     77static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
     78static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
     79static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
     80
     81static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
     82static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
     83
     84static void paint_internal(widget_t *widget)
     85{
     86        surface_t *surface = window_claim(widget->window);
     87        if (!surface)
     88                window_yield(widget->window);
     89       
    8090        source_t source;
    81         font_t font;
     91        source_init(&source);
     92       
    8293        drawctx_t drawctx;
    83 
    84         source_init(&source);
    85         font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
    8694        drawctx_init(&drawctx, surface);
    8795        drawctx_set_source(&drawctx, &source);
     96       
     97        /* Window border outer bevel */
     98       
     99        draw_bevel(&drawctx, &source, widget->vpos, widget->hpos,
     100            widget->width, widget->height, color_highlight, color_shadow);
     101       
     102        /* Window border surface */
     103       
     104        source_set_color(&source, color_surface);
     105        drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
     106            widget->width - 2, 2);
     107        drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
     108            2, widget->height - 2);
     109        drawctx_transfer(&drawctx, widget->hpos + 1,
     110            widget->vpos + widget->height - 3, widget->width - 2, 2);
     111        drawctx_transfer(&drawctx, widget->hpos + widget->width - 3,
     112            widget->vpos + 1, 2, widget->height - 4);
     113       
     114        /* Window border inner bevel */
     115       
     116        draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
     117            widget->width - 6, widget->height - 6, color_shadow,
     118            color_highlight);
     119       
     120        /* Header bevel */
     121       
     122        sysarg_t header_hpos = widget->hpos + border_thickness;
     123        sysarg_t header_vpos = widget->vpos + border_thickness;
     124        sysarg_t header_width = widget->width - 2 * border_thickness -
     125            close_thickness;
     126       
     127        draw_bevel(&drawctx, &source, header_hpos, header_vpos,
     128            header_width, header_height, widget->window->is_focused ?
     129            color_header_focus_highlight : color_header_unfocus_highlight,
     130            widget->window->is_focused ?
     131            color_header_focus_shadow : color_header_unfocus_shadow);
     132       
     133        /* Header surface */
     134       
     135        source_set_color(&source, widget->window->is_focused ?
     136            color_header_focus_surface : color_header_unfocus_surface);
     137        drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1,
     138            header_width - 2, header_height - 2);
     139       
     140        /* Close button bevel */
     141       
     142        sysarg_t close_hpos = widget->hpos + widget->width -
     143            border_thickness - close_thickness;
     144        sysarg_t close_vpos = widget->vpos + border_thickness;
     145       
     146        draw_bevel(&drawctx, &source, close_hpos, close_vpos,
     147            close_thickness, close_thickness, color_highlight, color_shadow);
     148       
     149        /* Close button surface */
     150       
     151        source_set_color(&source, color_surface);
     152        drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1,
     153            close_thickness - 2, close_thickness - 2);
     154       
     155        /* Close button icon */
     156       
     157        draw_icon_cross(surface, close_hpos + 3, close_vpos + 3,
     158            color_highlight, color_shadow);
     159       
     160        /* Window caption */
     161       
     162        font_t font;
     163        font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
     164       
    88165        drawctx_set_font(&drawctx, &font);
    89 
    90         source_set_color(&source, border_color);
    91         drawctx_transfer(&drawctx, w->hpos, w->vpos, border_thickness, w->height);
    92         drawctx_transfer(&drawctx, w->hpos + w->width - border_thickness,
    93             w->vpos, border_thickness, w->height);
    94         drawctx_transfer(&drawctx, w->hpos, w->vpos, w->width, border_thickness);
    95         drawctx_transfer(&drawctx, w->hpos,
    96             w->vpos + w->height - border_thickness, w->width, border_thickness);
    97 
    98         source_set_color(&source,
    99             w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
    100         drawctx_transfer(&drawctx,
    101             w->hpos + border_thickness, w->vpos + border_thickness,
    102                 w->width - 2 * border_thickness, header_height);
    103 
     166        source_set_color(&source, widget->window->is_focused ?
     167            color_caption_focus : color_caption_unfocus);
     168       
    104169        sysarg_t cpt_width;
    105170        sysarg_t cpt_height;
    106         font_get_box(&font, w->window->caption, &cpt_width, &cpt_height);
    107         sysarg_t cls_width;
    108         sysarg_t cls_height;
    109         char cls_pict[] = "x";
    110         font_get_box(&font, cls_pict, &cls_width, &cls_height);
    111         source_set_color(&source,
    112             w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
    113         sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
    114             border_thickness - close_width;
    115         sysarg_t cls_y = ((header_height - cls_height) / 2) + w->vpos + border_thickness;
    116         drawctx_print(&drawctx, cls_pict, cls_x, cls_y);
    117 
    118         bool draw_title = (w->width >= 2 * border_thickness + close_width + cpt_width);
     171        font_get_box(&font, widget->window->caption, &cpt_width, &cpt_height);
     172       
     173        bool draw_title =
     174            (widget->width >= 2 * border_thickness + 2 * bevel_thickness +
     175            close_thickness + cpt_width);
    119176        if (draw_title) {
    120                 sysarg_t cpt_x = ((w->width - cpt_width) / 2) + w->hpos;
    121                 sysarg_t cpt_y = ((header_height - cpt_height) / 2) + w->vpos + border_thickness;
    122                 if (w->window->caption) {
    123                         drawctx_print(&drawctx, w->window->caption, cpt_x, cpt_y);
    124                 }
    125         }
    126 
     177                sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos;
     178                sysarg_t cpt_y = ((header_height - cpt_height) / 2) +
     179                    widget->vpos + border_thickness;
     180               
     181                if (widget->window->caption)
     182                        drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y);
     183        }
     184       
    127185        font_release(&font);
    128         window_yield(w->window);
     186        window_yield(widget->window);
    129187}
    130188
     
    137195{
    138196        if (widget->window->is_decorated) {
    139                 list_foreach(widget->children, link) {
    140                         widget_t *child = list_get_instance(link, widget_t, link);
    141                         child->rearrange(child,
     197                list_foreach(widget->children, link, widget_t, child) {
     198                        child->rearrange(child,
    142199                            widget->hpos + border_thickness,
    143200                            widget->vpos + border_thickness + header_height,
     
    146203                }
    147204        } else {
    148                 list_foreach(widget->children, link) {
    149                         widget_t *child = list_get_instance(link, widget_t, link);
     205                list_foreach(widget->children, link, widget_t, child) {
    150206                        child->rearrange(child, widget->hpos, widget->vpos,
    151207                            widget->width, widget->height);
     
    160216        if (widget->window->is_decorated) {
    161217                paint_internal(widget);
    162                 list_foreach(widget->children, link) {
    163                         widget_t *child = list_get_instance(link, widget_t, link);
     218                list_foreach(widget->children, link, widget_t, child) {
    164219                        child->rearrange(child,
    165220                            hpos + border_thickness,
     
    169224                }
    170225        } else {
    171                 list_foreach(widget->children, link) {
    172                         widget_t *child = list_get_instance(link, widget_t, link);
     226                list_foreach(widget->children, link, widget_t, child) {
    173227                        child->rearrange(child, hpos, vpos, width, height);
    174228                }
     
    181235                paint_internal(widget);
    182236        }
    183         list_foreach(widget->children, link) {
    184                 widget_t *child = list_get_instance(link, widget_t, link);
     237        list_foreach(widget->children, link, widget_t, child) {
    185238                child->repaint(child);
    186239        }
     
    216269                    (event.vpos >= border_thickness) &&
    217270                    (event.vpos < border_thickness + header_height);
    218                 bool close = header && (event.hpos >= width - border_thickness - close_width);
     271                bool close = (header) &&
     272                    (event.hpos >= width - border_thickness - close_thickness);
    219273
    220274                if (top && left && allowed_button) {
     
    268322                        win_grab(widget->window->osess, event.pos_id, flags);
    269323                } else {
    270                         list_foreach(widget->children, link) {
    271                                 widget_t *child = list_get_instance(link, widget_t, link);
     324                        list_foreach(widget->children, link, widget_t, child) {
    272325                                child->handle_position_event(child, event);
    273326                        }
    274327                }
    275328        } else {
    276                 list_foreach(widget->children, link) {
    277                         widget_t *child = list_get_instance(link, widget_t, link);
     329                list_foreach(widget->children, link, widget_t, child) {
    278330                        child->handle_position_event(child, event);
    279331                }
     
    299351}
    300352
    301 static void handle_signal_event(window_t *win, sig_event_t event)
     353static void handle_signal_event(window_t *win, signal_event_t event)
    302354{
    303355        widget_t *widget = (widget_t *) event.object;
     
    310362}
    311363
    312 static void handle_resize(window_t *win, sysarg_t width, sysarg_t height)
    313 {
    314         int rc;
    315         surface_t *old_surface;
    316         surface_t *new_surface;
    317 
     364static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
     365    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
     366{
    318367        if (width < 2 * border_thickness + header_min_width) {
    319368                win_damage(win->osess, 0, 0, 0, 0);
    320369                return;
    321370        }
    322 
     371       
    323372        if (height < 2 * border_thickness + header_height) {
    324373                win_damage(win->osess, 0, 0, 0, 0);
    325374                return;
    326375        }
    327 
     376       
    328377        /* Allocate resources for new surface. */
    329         new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
    330         if (!new_surface) {
     378        surface_t *new_surface = surface_create(width, height, NULL,
     379            SURFACE_FLAG_SHARED);
     380        if (!new_surface)
    331381                return;
    332         }
    333 
     382       
    334383        /* Switch new and old surface. */
    335384        fibril_mutex_lock(&win->guard);
    336         old_surface = win->surface;
     385        surface_t *old_surface = win->surface;
    337386        win->surface = new_surface;
    338387        fibril_mutex_unlock(&win->guard);
    339 
    340         /* Let all widgets in the tree alter their position and size. Widgets might
    341          * also paint themselves onto the new surface. */
     388       
     389        /*
     390         * Let all widgets in the tree alter their position and size.
     391         * Widgets might also paint themselves onto the new surface.
     392         */
    342393        win->root.rearrange(&win->root, 0, 0, width, height);
    343 
     394       
    344395        fibril_mutex_lock(&win->guard);
    345396        surface_reset_damaged_region(win->surface);
    346397        fibril_mutex_unlock(&win->guard);
    347 
     398       
    348399        /* Inform compositor about new surface. */
    349         rc = win_resize(win->osess,
    350                 width, height, surface_direct_access(new_surface));
    351 
     400        int rc = win_resize(win->osess, offset_x, offset_y, width, height,
     401            placement_flags, surface_direct_access(new_surface));
     402       
    352403        if (rc != EOK) {
    353404                /* Rollback to old surface. Reverse all changes. */
    354 
     405               
    355406                sysarg_t old_width = 0;
    356407                sysarg_t old_height = 0;
    357                 if (old_surface) {
     408                if (old_surface)
    358409                        surface_get_resolution(old_surface, &old_width, &old_height);
    359                 }
    360 
     410               
    361411                fibril_mutex_lock(&win->guard);
    362412                new_surface = win->surface;
    363413                win->surface = old_surface;
    364414                fibril_mutex_unlock(&win->guard);
    365 
     415               
    366416                win->root.rearrange(&win->root, 0, 0, old_width, old_height);
    367417               
     
    371421                        fibril_mutex_unlock(&win->guard);
    372422                }
    373 
     423               
    374424                surface_destroy(new_surface);
    375                 return;
    376         }
    377 
    378         /* Finally deallocate old surface. */
    379         if (old_surface) {
    380                 surface_destroy(old_surface);
     425        } else {
     426                /* Deallocate old surface. */
     427                if (old_surface)
     428                        surface_destroy(old_surface);
    381429        }
    382430}
     
    460508                        break;
    461509                case ET_SIGNAL_EVENT:
    462                         handle_signal_event(win, event->data.sig);
     510                        handle_signal_event(win, event->data.signal);
    463511                        break;
    464512                case ET_WINDOW_RESIZE:
    465                         handle_resize(win, event->data.rsz.width, event->data.rsz.height);
     513                        handle_resize(win, event->data.resize.offset_x,
     514                            event->data.resize.offset_y, event->data.resize.width,
     515                            event->data.resize.height, event->data.resize.placement_flags);
    466516                        break;
    467517                case ET_WINDOW_FOCUS:
     
    536586}
    537587
    538 window_t *window_open(char *winreg, bool is_main, bool is_decorated,
    539     const char *caption, sysarg_t x_offset, sysarg_t y_offset)
    540 {
    541         int rc;
    542 
     588window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
     589    const char *caption)
     590{
    543591        window_t *win = (window_t *) malloc(sizeof(window_t));
    544         if (!win) {
     592        if (!win)
    545593                return NULL;
    546         }
    547 
     594       
    548595        win->is_main = is_main;
    549596        win->is_decorated = is_decorated;
     
    551598        prodcons_initialize(&win->events);
    552599        fibril_mutex_initialize(&win->guard);
     600       
    553601        widget_init(&win->root, NULL);
    554602        win->root.window = win;
     
    562610        win->focus = NULL;
    563611        win->surface = NULL;
    564 
     612       
    565613        service_id_t reg_dsid;
    566         async_sess_t *reg_sess;
    567 
    568         rc = loc_service_get_id(winreg, &reg_dsid, 0);
     614        int rc = loc_service_get_id(winreg, &reg_dsid, 0);
    569615        if (rc != EOK) {
    570616                free(win);
    571617                return NULL;
    572618        }
    573 
    574         reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0);
     619       
     620        async_sess_t *reg_sess = loc_service_connect(EXCHANGE_SERIALIZE,
     621            reg_dsid, 0);
    575622        if (reg_sess == NULL) {
    576623                free(win);
    577624                return NULL;
    578625        }
    579 
     626       
    580627        service_id_t in_dsid;
    581628        service_id_t out_dsid;
    582        
    583         rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
     629        rc = win_register(reg_sess, &in_dsid, &out_dsid);
    584630        async_hangup(reg_sess);
    585631        if (rc != EOK) {
     
    587633                return NULL;
    588634        }
    589 
     635       
    590636        win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0);
    591637        if (win->osess == NULL) {
     
    593639                return NULL;
    594640        }
    595 
     641       
    596642        win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0);
    597643        if (win->isess == NULL) {
     
    600646                return NULL;
    601647        }
    602 
    603         if (caption == NULL) {
     648       
     649        if (caption == NULL)
    604650                win->caption = NULL;
    605         } else {
     651        else
    606652                win->caption = str_dup(caption);
    607         }
    608 
     653       
    609654        return win;
    610655}
    611656
    612 void window_resize(window_t *win, sysarg_t width, sysarg_t height)
     657void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
     658    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
    613659{
    614660        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     
    616662                link_initialize(&event->link);
    617663                event->type = ET_WINDOW_RESIZE;
    618                 event->data.rsz.width = width;
    619                 event->data.rsz.height = height;
     664                event->data.resize.offset_x = offset_x;
     665                event->data.resize.offset_y = offset_y;
     666                event->data.resize.width = width;
     667                event->data.resize.height = height;
     668                event->data.resize.placement_flags = placement_flags;
    620669                prodcons_produce(&win->events, &event->link);
    621670        }
Note: See TracChangeset for help on using the changeset viewer.