Ignore:
File:
1 edited

Legend:

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

    r10cb47e r21eeb653  
    5555#include <drawctx.h>
    5656#include <surface.h>
    57 #include <font/embedded.h>
    58 
    59 #include "common.h"
     57
    6058#include "connection.h"
    6159#include "widget.h"
    6260#include "window.h"
    6361
    64 static sysarg_t border_thickness = 4;
    65 static sysarg_t bevel_thickness = 1;
     62static sysarg_t border_thickness = 5;
    6663static sysarg_t header_height = 20;
    6764static sysarg_t header_min_width = 40;
    68 static sysarg_t close_thickness = 20;
    69 
    70 static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
    71 static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
    72 static pixel_t color_surface = PIXEL(255, 186, 186, 186);
    73 
    74 static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
    75 static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
    76 static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
    77 
    78 static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
    79 static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
    80 static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
    81 
    82 static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
    83 static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
    84 
    85 static void paint_internal(widget_t *widget)
    86 {
    87         surface_t *surface = window_claim(widget->window);
    88         if (!surface)
    89                 window_yield(widget->window);
    90        
     65static sysarg_t close_width = 20;
     66
     67static pixel_t border_color = PIXEL(255, 0, 0, 0);
     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);
     72
     73static 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
    9180        source_t source;
     81        font_t font;
     82        drawctx_t drawctx;
     83
    9284        source_init(&source);
    93        
    94         drawctx_t drawctx;
     85        font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
    9586        drawctx_init(&drawctx, surface);
    9687        drawctx_set_source(&drawctx, &source);
    97        
    98         /* Window border outer bevel */
    99        
    100         draw_bevel(&drawctx, &source, widget->vpos, widget->hpos,
    101             widget->width, widget->height, color_highlight, color_shadow);
    102        
    103         /* Window border surface */
    104        
    105         source_set_color(&source, color_surface);
    106         drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
    107             widget->width - 2, 2);
    108         drawctx_transfer(&drawctx, widget->hpos + 1, widget->vpos + 1,
    109             2, widget->height - 2);
    110         drawctx_transfer(&drawctx, widget->hpos + 1,
    111             widget->vpos + widget->height - 3, widget->width - 2, 2);
    112         drawctx_transfer(&drawctx, widget->hpos + widget->width - 3,
    113             widget->vpos + 1, 2, widget->height - 4);
    114        
    115         /* Window border inner bevel */
    116        
    117         draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
    118             widget->width - 6, widget->height - 6, color_shadow,
    119             color_highlight);
    120        
    121         /* Header bevel */
    122        
    123         sysarg_t header_hpos = widget->hpos + border_thickness;
    124         sysarg_t header_vpos = widget->vpos + border_thickness;
    125         sysarg_t header_width = widget->width - 2 * border_thickness -
    126             close_thickness;
    127        
    128         draw_bevel(&drawctx, &source, header_hpos, header_vpos,
    129             header_width, header_height, widget->window->is_focused ?
    130             color_header_focus_highlight : color_header_unfocus_highlight,
    131             widget->window->is_focused ?
    132             color_header_focus_shadow : color_header_unfocus_shadow);
    133        
    134         /* Header surface */
    135        
    136         source_set_color(&source, widget->window->is_focused ?
    137             color_header_focus_surface : color_header_unfocus_surface);
    138         drawctx_transfer(&drawctx, header_hpos + 1, header_vpos + 1,
    139             header_width - 2, header_height - 2);
    140        
    141         /* Close button bevel */
    142        
    143         sysarg_t close_hpos = widget->hpos + widget->width -
    144             border_thickness - close_thickness;
    145         sysarg_t close_vpos = widget->vpos + border_thickness;
    146        
    147         draw_bevel(&drawctx, &source, close_hpos, close_vpos,
    148             close_thickness, close_thickness, color_highlight, color_shadow);
    149        
    150         /* Close button surface */
    151        
    152         source_set_color(&source, color_surface);
    153         drawctx_transfer(&drawctx, close_hpos + 1, close_vpos + 1,
    154             close_thickness - 2, close_thickness - 2);
    155        
    156         /* Close button icon */
    157        
    158         draw_icon_cross(surface, close_hpos + 3, close_vpos + 3,
    159             color_highlight, color_shadow);
    160        
    161         /* Window caption */
    162        
    163         font_t *font;
    164         int rc = embedded_font_create(&font, 16);
    165         if (rc != EOK) {
    166                 window_yield(widget->window);
    167                 return;
    168         }
    169        
    170         drawctx_set_font(&drawctx, font);
    171         source_set_color(&source, widget->window->is_focused ?
    172             color_caption_focus : color_caption_unfocus);
    173        
     88        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
    174104        sysarg_t cpt_width;
    175105        sysarg_t cpt_height;
    176         font_get_box(font, widget->window->caption, &cpt_width, &cpt_height);
    177        
    178         bool draw_title =
    179             (widget->width >= 2 * border_thickness + 2 * bevel_thickness +
    180             close_thickness + cpt_width);
     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);
    181119        if (draw_title) {
    182                 sysarg_t cpt_x = ((widget->width - cpt_width) / 2) + widget->hpos;
    183                 sysarg_t cpt_y = ((header_height - cpt_height) / 2) +
    184                     widget->vpos + border_thickness;
    185                
    186                 if (widget->window->caption)
    187                         drawctx_print(&drawctx, widget->window->caption, cpt_x, cpt_y);
    188         }
    189        
    190         font_release(font);
    191         window_yield(widget->window);
     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
     127        font_release(&font);
     128        window_yield(w->window);
    192129}
    193130
     
    200137{
    201138        if (widget->window->is_decorated) {
    202                 list_foreach(widget->children, link, widget_t, child) {
    203                         child->rearrange(child,
     139                list_foreach(widget->children, link) {
     140                        widget_t *child = list_get_instance(link, widget_t, link);
     141                        child->rearrange(child,
    204142                            widget->hpos + border_thickness,
    205143                            widget->vpos + border_thickness + header_height,
     
    208146                }
    209147        } else {
    210                 list_foreach(widget->children, link, widget_t, child) {
     148                list_foreach(widget->children, link) {
     149                        widget_t *child = list_get_instance(link, widget_t, link);
    211150                        child->rearrange(child, widget->hpos, widget->vpos,
    212151                            widget->width, widget->height);
     
    221160        if (widget->window->is_decorated) {
    222161                paint_internal(widget);
    223                 list_foreach(widget->children, link, widget_t, child) {
     162                list_foreach(widget->children, link) {
     163                        widget_t *child = list_get_instance(link, widget_t, link);
    224164                        child->rearrange(child,
    225165                            hpos + border_thickness,
     
    229169                }
    230170        } else {
    231                 list_foreach(widget->children, link, widget_t, child) {
     171                list_foreach(widget->children, link) {
     172                        widget_t *child = list_get_instance(link, widget_t, link);
    232173                        child->rearrange(child, hpos, vpos, width, height);
    233174                }
     
    240181                paint_internal(widget);
    241182        }
    242         list_foreach(widget->children, link, widget_t, child) {
     183        list_foreach(widget->children, link) {
     184                widget_t *child = list_get_instance(link, widget_t, link);
    243185                child->repaint(child);
    244186        }
     
    274216                    (event.vpos >= border_thickness) &&
    275217                    (event.vpos < border_thickness + header_height);
    276                 bool close = (header) &&
    277                     (event.hpos >= width - border_thickness - close_thickness);
     218                bool close = header && (event.hpos >= width - border_thickness - close_width);
    278219
    279220                if (top && left && allowed_button) {
     
    327268                        win_grab(widget->window->osess, event.pos_id, flags);
    328269                } else {
    329                         list_foreach(widget->children, link, widget_t, child) {
     270                        list_foreach(widget->children, link) {
     271                                widget_t *child = list_get_instance(link, widget_t, link);
    330272                                child->handle_position_event(child, event);
    331273                        }
    332274                }
    333275        } else {
    334                 list_foreach(widget->children, link, widget_t, child) {
     276                list_foreach(widget->children, link) {
     277                        widget_t *child = list_get_instance(link, widget_t, link);
    335278                        child->handle_position_event(child, event);
    336279                }
     
    356299}
    357300
    358 static void handle_signal_event(window_t *win, signal_event_t event)
     301static void handle_signal_event(window_t *win, sig_event_t event)
    359302{
    360303        widget_t *widget = (widget_t *) event.object;
     
    367310}
    368311
    369 static void handle_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
    370     sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
    371 {
     312static 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
    372318        if (width < 2 * border_thickness + header_min_width) {
    373319                win_damage(win->osess, 0, 0, 0, 0);
    374320                return;
    375321        }
    376        
     322
    377323        if (height < 2 * border_thickness + header_height) {
    378324                win_damage(win->osess, 0, 0, 0, 0);
    379325                return;
    380326        }
    381        
     327
    382328        /* Allocate resources for new surface. */
    383         surface_t *new_surface = surface_create(width, height, NULL,
    384             SURFACE_FLAG_SHARED);
    385         if (!new_surface)
     329        new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
     330        if (!new_surface) {
    386331                return;
    387        
     332        }
     333
    388334        /* Switch new and old surface. */
    389335        fibril_mutex_lock(&win->guard);
    390         surface_t *old_surface = win->surface;
     336        old_surface = win->surface;
    391337        win->surface = new_surface;
    392338        fibril_mutex_unlock(&win->guard);
    393        
    394         /*
    395          * Let all widgets in the tree alter their position and size.
    396          * Widgets might also paint themselves onto the new surface.
    397          */
     339
     340        /* Let all widgets in the tree alter their position and size. Widgets might
     341         * also paint themselves onto the new surface. */
    398342        win->root.rearrange(&win->root, 0, 0, width, height);
    399        
     343
    400344        fibril_mutex_lock(&win->guard);
    401345        surface_reset_damaged_region(win->surface);
    402346        fibril_mutex_unlock(&win->guard);
    403        
     347
    404348        /* Inform compositor about new surface. */
    405         int rc = win_resize(win->osess, offset_x, offset_y, width, height,
    406             placement_flags, surface_direct_access(new_surface));
    407        
     349        rc = win_resize(win->osess,
     350                width, height, surface_direct_access(new_surface));
     351
    408352        if (rc != EOK) {
    409353                /* Rollback to old surface. Reverse all changes. */
    410                
     354
    411355                sysarg_t old_width = 0;
    412356                sysarg_t old_height = 0;
    413                 if (old_surface)
     357                if (old_surface) {
    414358                        surface_get_resolution(old_surface, &old_width, &old_height);
    415                
     359                }
     360
    416361                fibril_mutex_lock(&win->guard);
    417362                new_surface = win->surface;
    418363                win->surface = old_surface;
    419364                fibril_mutex_unlock(&win->guard);
    420                
     365
    421366                win->root.rearrange(&win->root, 0, 0, old_width, old_height);
    422367               
     
    426371                        fibril_mutex_unlock(&win->guard);
    427372                }
    428                
     373
    429374                surface_destroy(new_surface);
    430         } else {
    431                 /* Deallocate old surface. */
    432                 if (old_surface)
    433                         surface_destroy(old_surface);
     375                return;
     376        }
     377
     378        /* Finally deallocate old surface. */
     379        if (old_surface) {
     380                surface_destroy(old_surface);
    434381        }
    435382}
     
    513460                        break;
    514461                case ET_SIGNAL_EVENT:
    515                         handle_signal_event(win, event->data.signal);
     462                        handle_signal_event(win, event->data.sig);
    516463                        break;
    517464                case ET_WINDOW_RESIZE:
    518                         handle_resize(win, event->data.resize.offset_x,
    519                             event->data.resize.offset_y, event->data.resize.width,
    520                             event->data.resize.height, event->data.resize.placement_flags);
     465                        handle_resize(win, event->data.rsz.width, event->data.rsz.height);
    521466                        break;
    522467                case ET_WINDOW_FOCUS:
     
    591536}
    592537
    593 window_t *window_open(const char *winreg, const void *data,
    594     window_flags_t flags, const char *caption)
    595 {
     538window_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
    596543        window_t *win = (window_t *) malloc(sizeof(window_t));
    597         if (!win)
     544        if (!win) {
    598545                return NULL;
    599        
    600         win->is_main = flags & WINDOW_MAIN;
    601         win->is_decorated = flags & WINDOW_DECORATED;
     546        }
     547
     548        win->is_main = is_main;
     549        win->is_decorated = is_decorated;
    602550        win->is_focused = true;
    603551        prodcons_initialize(&win->events);
    604552        fibril_mutex_initialize(&win->guard);
    605        
    606         widget_init(&win->root, NULL, data);
     553        widget_init(&win->root, NULL);
    607554        win->root.window = win;
    608555        win->root.destroy = root_destroy;
     
    615562        win->focus = NULL;
    616563        win->surface = NULL;
    617        
     564
    618565        service_id_t reg_dsid;
    619         int rc = loc_service_get_id(winreg, &reg_dsid, 0);
     566        async_sess_t *reg_sess;
     567
     568        rc = loc_service_get_id(winreg, &reg_dsid, 0);
    620569        if (rc != EOK) {
    621570                free(win);
    622571                return NULL;
    623572        }
    624        
    625         async_sess_t *reg_sess =
    626             loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0);
     573
     574        reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0);
    627575        if (reg_sess == NULL) {
    628576                free(win);
    629577                return NULL;
    630578        }
    631        
     579
    632580        service_id_t in_dsid;
    633581        service_id_t out_dsid;
    634         rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
     582       
     583        rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
    635584        async_hangup(reg_sess);
    636585        if (rc != EOK) {
     
    638587                return NULL;
    639588        }
    640        
    641         win->osess = loc_service_connect(out_dsid, INTERFACE_COMPOSITOR, 0);
     589
     590        win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0);
    642591        if (win->osess == NULL) {
    643592                free(win);
    644593                return NULL;
    645594        }
    646        
    647         win->isess = loc_service_connect(in_dsid, INTERFACE_COMPOSITOR, 0);
     595
     596        win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0);
    648597        if (win->isess == NULL) {
    649598                async_hangup(win->osess);
     
    651600                return NULL;
    652601        }
    653        
    654         if (caption == NULL)
     602
     603        if (caption == NULL) {
    655604                win->caption = NULL;
    656         else
     605        } else {
    657606                win->caption = str_dup(caption);
    658        
     607        }
     608
    659609        return win;
    660610}
    661611
    662 void window_resize(window_t *win, sysarg_t offset_x, sysarg_t offset_y,
    663     sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
     612void window_resize(window_t *win, sysarg_t width, sysarg_t height)
    664613{
    665614        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     
    667616                link_initialize(&event->link);
    668617                event->type = ET_WINDOW_RESIZE;
    669                 event->data.resize.offset_x = offset_x;
    670                 event->data.resize.offset_y = offset_y;
    671                 event->data.resize.width = width;
    672                 event->data.resize.height = height;
    673                 event->data.resize.placement_flags = placement_flags;
     618                event->data.rsz.width = width;
     619                event->data.rsz.height = height;
    674620                prodcons_produce(&win->events, &event->link);
    675621        }
Note: See TracChangeset for help on using the changeset viewer.