Ignore:
File:
1 edited

Legend:

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

    r61b5b73d r34cb6c8  
    5656#include <surface.h>
    5757
    58 #include "common.h"
    5958#include "connection.h"
    6059#include "widget.h"
    6160#include "window.h"
    6261
    63 static sysarg_t border_thickness = 4;
    64 static sysarg_t bevel_thickness = 1;
     62static sysarg_t border_thickness = 5;
    6563static sysarg_t header_height = 20;
    6664static sysarg_t header_min_width = 40;
    67 static sysarg_t close_thickness = 20;
    68 
    69 static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
    70 static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
    71 static pixel_t color_surface = PIXEL(255, 186, 186, 186);
    72 
    73 static pixel_t color_header_focus_highlight = PIXEL(255, 120, 145, 255);
    74 static pixel_t color_header_focus_shadow = PIXEL(255, 40, 48, 89);
    75 static pixel_t color_header_focus_surface = PIXEL(255, 88, 106, 196);
    76 
    77 static pixel_t color_header_unfocus_highlight = PIXEL(255, 16, 78, 126);
    78 static pixel_t color_header_unfocus_shadow = PIXEL(255, 5, 26, 42);
    79 static pixel_t color_header_unfocus_surface = PIXEL(255, 12, 57, 92);
    80 
    81 static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
    82 static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
    83 
    84 static void paint_internal(widget_t *widget)
    85 {
    86         surface_t *surface = window_claim(widget->window);
    87         if (!surface)
    88                 window_yield(widget->window);
    89        
     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, 88, 106, 196);
     69static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
     70static pixel_t header_bg_unfocus_color = PIXEL(255, 12, 57, 92);
     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
    9080        source_t source;
     81        font_t font;
     82        drawctx_t drawctx;
     83
    9184        source_init(&source);
    92        
    93         drawctx_t drawctx;
     85        font_init(&font, FONT_DECODER_EMBEDDED, NULL, 16);
    9486        drawctx_init(&drawctx, surface);
    9587        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        
    16588        drawctx_set_font(&drawctx, &font);
    166         source_set_color(&source, widget->window->is_focused ?
    167             color_caption_focus : color_caption_unfocus);
    168        
     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
    169104        sysarg_t cpt_width;
    170105        sysarg_t cpt_height;
    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);
     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);
    176119        if (draw_title) {
    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        
     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
    185127        font_release(&font);
    186         window_yield(widget->window);
     128        window_yield(w->window);
    187129}
    188130
     
    196138        if (widget->window->is_decorated) {
    197139                list_foreach(widget->children, link, widget_t, child) {
    198                         child->rearrange(child,
     140                        child->rearrange(child, 
    199141                            widget->hpos + border_thickness,
    200142                            widget->vpos + border_thickness + header_height,
     
    269211                    (event.vpos >= border_thickness) &&
    270212                    (event.vpos < border_thickness + header_height);
    271                 bool close = (header) &&
    272                     (event.hpos >= width - border_thickness - close_thickness);
     213                bool close = header && (event.hpos >= width - border_thickness - close_width);
    273214
    274215                if (top && left && allowed_button) {
     
    351292}
    352293
    353 static void handle_signal_event(window_t *win, signal_event_t event)
     294static void handle_signal_event(window_t *win, sig_event_t event)
    354295{
    355296        widget_t *widget = (widget_t *) event.object;
     
    362303}
    363304
    364 static 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 {
     305static void handle_resize(window_t *win, sysarg_t width, sysarg_t height)
     306{
     307        int rc;
     308        surface_t *old_surface;
     309        surface_t *new_surface;
     310
    367311        if (width < 2 * border_thickness + header_min_width) {
    368312                win_damage(win->osess, 0, 0, 0, 0);
    369313                return;
    370314        }
    371        
     315
    372316        if (height < 2 * border_thickness + header_height) {
    373317                win_damage(win->osess, 0, 0, 0, 0);
    374318                return;
    375319        }
    376        
     320
    377321        /* Allocate resources for new surface. */
    378         surface_t *new_surface = surface_create(width, height, NULL,
    379             SURFACE_FLAG_SHARED);
    380         if (!new_surface)
     322        new_surface = surface_create(width, height, NULL, SURFACE_FLAG_SHARED);
     323        if (!new_surface) {
    381324                return;
    382        
     325        }
     326
    383327        /* Switch new and old surface. */
    384328        fibril_mutex_lock(&win->guard);
    385         surface_t *old_surface = win->surface;
     329        old_surface = win->surface;
    386330        win->surface = new_surface;
    387331        fibril_mutex_unlock(&win->guard);
    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          */
     332
     333        /* Let all widgets in the tree alter their position and size. Widgets might
     334         * also paint themselves onto the new surface. */
    393335        win->root.rearrange(&win->root, 0, 0, width, height);
    394        
     336
    395337        fibril_mutex_lock(&win->guard);
    396338        surface_reset_damaged_region(win->surface);
    397339        fibril_mutex_unlock(&win->guard);
    398        
     340
    399341        /* Inform compositor about new surface. */
    400         int rc = win_resize(win->osess, offset_x, offset_y, width, height,
    401             placement_flags, surface_direct_access(new_surface));
    402        
     342        rc = win_resize(win->osess,
     343                width, height, surface_direct_access(new_surface));
     344
    403345        if (rc != EOK) {
    404346                /* Rollback to old surface. Reverse all changes. */
    405                
     347
    406348                sysarg_t old_width = 0;
    407349                sysarg_t old_height = 0;
    408                 if (old_surface)
     350                if (old_surface) {
    409351                        surface_get_resolution(old_surface, &old_width, &old_height);
    410                
     352                }
     353
    411354                fibril_mutex_lock(&win->guard);
    412355                new_surface = win->surface;
    413356                win->surface = old_surface;
    414357                fibril_mutex_unlock(&win->guard);
    415                
     358
    416359                win->root.rearrange(&win->root, 0, 0, old_width, old_height);
    417360               
     
    421364                        fibril_mutex_unlock(&win->guard);
    422365                }
    423                
     366
    424367                surface_destroy(new_surface);
    425         } else {
    426                 /* Deallocate old surface. */
    427                 if (old_surface)
    428                         surface_destroy(old_surface);
     368                return;
     369        }
     370
     371        /* Finally deallocate old surface. */
     372        if (old_surface) {
     373                surface_destroy(old_surface);
    429374        }
    430375}
     
    508453                        break;
    509454                case ET_SIGNAL_EVENT:
    510                         handle_signal_event(win, event->data.signal);
     455                        handle_signal_event(win, event->data.sig);
    511456                        break;
    512457                case ET_WINDOW_RESIZE:
    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);
     458                        handle_resize(win, event->data.rsz.width, event->data.rsz.height);
    516459                        break;
    517460                case ET_WINDOW_FOCUS:
     
    587530
    588531window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
    589     const char *caption)
    590 {
     532    const char *caption, sysarg_t x_offset, sysarg_t y_offset)
     533{
     534        int rc;
     535
    591536        window_t *win = (window_t *) malloc(sizeof(window_t));
    592         if (!win)
     537        if (!win) {
    593538                return NULL;
    594        
     539        }
     540
    595541        win->is_main = is_main;
    596542        win->is_decorated = is_decorated;
     
    598544        prodcons_initialize(&win->events);
    599545        fibril_mutex_initialize(&win->guard);
    600        
    601546        widget_init(&win->root, NULL);
    602547        win->root.window = win;
     
    610555        win->focus = NULL;
    611556        win->surface = NULL;
    612        
     557
    613558        service_id_t reg_dsid;
    614         int rc = loc_service_get_id(winreg, &reg_dsid, 0);
     559        async_sess_t *reg_sess;
     560
     561        rc = loc_service_get_id(winreg, &reg_dsid, 0);
    615562        if (rc != EOK) {
    616563                free(win);
    617564                return NULL;
    618565        }
    619        
    620         async_sess_t *reg_sess = loc_service_connect(EXCHANGE_SERIALIZE,
    621             reg_dsid, 0);
     566
     567        reg_sess = loc_service_connect(EXCHANGE_SERIALIZE, reg_dsid, 0);
    622568        if (reg_sess == NULL) {
    623569                free(win);
    624570                return NULL;
    625571        }
    626        
     572
    627573        service_id_t in_dsid;
    628574        service_id_t out_dsid;
    629         rc = win_register(reg_sess, &in_dsid, &out_dsid);
     575       
     576        rc = win_register(reg_sess, &in_dsid, &out_dsid, x_offset, y_offset);
    630577        async_hangup(reg_sess);
    631578        if (rc != EOK) {
     
    633580                return NULL;
    634581        }
    635        
     582
    636583        win->osess = loc_service_connect(EXCHANGE_SERIALIZE, out_dsid, 0);
    637584        if (win->osess == NULL) {
     
    639586                return NULL;
    640587        }
    641        
     588
    642589        win->isess = loc_service_connect(EXCHANGE_SERIALIZE, in_dsid, 0);
    643590        if (win->isess == NULL) {
     
    646593                return NULL;
    647594        }
    648        
    649         if (caption == NULL)
     595
     596        if (caption == NULL) {
    650597                win->caption = NULL;
    651         else
     598        } else {
    652599                win->caption = str_dup(caption);
    653        
     600        }
     601
    654602        return win;
    655603}
    656604
    657 void 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)
     605void window_resize(window_t *win, sysarg_t width, sysarg_t height)
    659606{
    660607        window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
     
    662609                link_initialize(&event->link);
    663610                event->type = ET_WINDOW_RESIZE;
    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;
     611                event->data.rsz.width = width;
     612                event->data.rsz.height = height;
    669613                prodcons_produce(&win->events, &event->link);
    670614        }
Note: See TracChangeset for help on using the changeset viewer.