Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset e79a025 in mainline


Ignore:
Timestamp:
2020-07-03T23:41:46Z (5 weeks ago)
Author:
GitHub <noreply@…>
Branches:
master
Children:
fd11144
Parents:
edb57bc6 (diff), ddb844e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
jxsvoboda <5887334+jxsvoboda@…> (2020-07-03 23:41:46)
git-committer:
GitHub <noreply@…> (2020-07-03 23:41:46)
Message:

Merge pull request #200 from jxsvoboda/gfx

Display server

Files:
133 added
7 deleted
31 edited
5 moved

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    redb57bc6 re79a025  
    608608! [(PLATFORM=ia32|PLATFORM=amd64|MACHINE=beagleboardxm)&CONFIG_HID_OUT!=none&CONFIG_FB=y] CONFIG_BFB_BPP (choice)
    609609
     610% Display double buffering
     611! [CONFIG_FB=y] CONFIG_DISP_DOUBLE_BUF (y/n)
     612
     613% Window double buffering
     614! [CONFIG_FB=y] CONFIG_WIN_DOUBLE_BUF (n/y)
     615
    610616% Start AP processors by the loader
    611617! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
  • abi/include/abi/ipc/interfaces.h

    redb57bc6 re79a025  
    112112        INTERFACE_OUTPUT =
    113113            FOURCC_COMPACT('o', 'u', 'd', 'v') | IFACE_EXCHANGE_SERIALIZE,
    114         INTERFACE_COMPOSITOR =
    115             FOURCC_COMPACT('c', 'm', 'p', 's') | IFACE_EXCHANGE_SERIALIZE,
    116114        INTERFACE_HOUND =
    117115            FOURCC_COMPACT('h', 'o', 'u', 'n') | IFACE_EXCHANGE_PARALLEL,
    118         INTERFACE_VISUALIZER_CB =
    119             FOURCC_COMPACT('v', 's', 'd', 'v') | IFACE_EXCHANGE_PARALLEL | IFACE_MOD_CALLBACK,
    120116        INTERFACE_LOC_SUPPLIER =
    121117            FOURCC_COMPACT('l', 'o', 'c', 's') | IFACE_EXCHANGE_SERIALIZE,
     
    187183            FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE,
    188184        INTERFACE_PCI =
    189             FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE
     185            FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE,
     186        INTERFACE_DDEV =
     187            FOURCC_COMPACT('d', 'd', 'e', 'v') | IFACE_EXCHANGE_SERIALIZE,
     188        INTERFACE_DISPLAY =
     189            FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE,
     190        INTERFACE_DISPLAY_CB =
     191            FOURCC_COMPACT('d', 's', 'p', 'l') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK,
     192        INTERFACE_GC =
     193            FOURCC_COMPACT('g', 'f', 'x', 'c') | IFACE_EXCHANGE_SERIALIZE,
    190194} iface_t;
    191195
  • meson/part/initrd_manifest/meson.build

    redb57bc6 re79a025  
    6363                'app/vterm',
    6464
    65                 'srv/hid/compositor',
     65                'srv/hid/display',
    6666        ]
    6767endif
  • tools/export.sh

    redb57bc6 re79a025  
    4141        uspace/lib/libmath.a \
    4242        uspace/lib/libclui.a \
     43        uspace/lib/libdisplay.a \
     44        uspace/lib/libgfx.a \
    4345        uspace/lib/libgui.a \
     46        uspace/lib/libipcgfx.a \
    4447        uspace/lib/libdraw.a \
    4548        uspace/lib/libsoftrend.a \
  • tools/xcw/bin/helenos-pkg-config

    redb57bc6 re79a025  
    4444libmath_libs="$LIB_DIR/libmath.a"
    4545
    46 libgui_cflags="-I$INCLUDE_DIR/libgui"
    47 libgui_libs="$LIB_DIR/libgui.a"
     46libgui_cflags="-I$INCLUDE_DIR/libgui -I$INCLUDE_DIR/libdisplay -I$INCLUDE_DIR/libgfx -I$INCLUDE_DIR/libipcgfx"
     47libgui_libs="$LIB_DIR/libgui.a $LIB_DIR/libdisplay.a $LIB_DIR/libipcgfx.a $LIB_DIR/libgfx.a"
    4848
    4949libdraw_cflags="-I$INCLUDE_DIR/libdraw"
     
    5555libpcm_cflags="-I$INCLUDE_DIR/libpcm"
    5656libpcm_libs="$LIB_DIR/libpcm.a"
     57
     58libgfx_cflags="-I$INCLUDE_DIR/libgfx"
     59libgfx_libs="$LIB_DIR/libgfx.a"
     60
     61libipcgfx_cflags="-I$INCLUDE_DIR/libipcgfx"
     62libipcgfx_libs="$LIB_DIR/libipcgfx.a"
     63
     64libdisplay_cflags="-I$INCLUDE_DIR/libdisplay"
     65libdisplay_libs="$LIB_DIR/libdisplay.a"
    5766
    5867action=none
     
    7180            (libhound) ;;
    7281            (libpcm) ;;
     82            (libgfx) ;;
     83            (libipcgfx) ;;
     84            (libdisplay) ;;
    7385            (*) echo "Unknown package $1" >&2; exit 1;;
    7486            esac
  • uspace/app/init/init.c

    redb57bc6 re79a025  
    3434 */
    3535
     36#include <fibril.h>
    3637#include <stdio.h>
    3738#include <stdarg.h>
     
    4748#include <config.h>
    4849#include <io/logctl.h>
     50#include <vfs/vfs.h>
    4951#include <vol.h>
    5052#include "untar.h"
     
    6668#define APP_GETTERM  "/app/getterm"
    6769
    68 #define SRV_COMPOSITOR  "/srv/hid/compositor"
     70#define SRV_DISPLAY  "/srv/hid/display"
     71#define DISPLAY_SVC  "hid/display"
    6972
    7073#define HID_INPUT              "hid/input"
    7174#define HID_OUTPUT             "hid/output"
    72 #define HID_COMPOSITOR_SERVER  ":0"
    7375
    7476#define srv_start(path, ...) \
     
    271273}
    272274
    273 static errno_t compositor(const char *isvc, const char *name)
    274 {
    275         /* Wait for the input service to be ready */
    276         service_id_t service_id;
    277         errno_t rc = loc_service_get_id(isvc, &service_id, IPC_FLAG_BLOCKING);
    278         if (rc != EOK) {
    279                 printf("%s: Error waiting on %s (%s)\n", NAME, isvc,
    280                     str_error(rc));
    281                 return rc;
    282         }
    283 
    284         return srv_start(SRV_COMPOSITOR, isvc, name);
    285 }
    286 
    287 static int gui_start(const char *app, const char *srv_name)
    288 {
    289         char winreg[50];
    290         snprintf(winreg, sizeof(winreg), "%s%s%s", "comp", srv_name, "/winreg");
    291 
    292         printf("%s: Spawning %s %s\n", NAME, app, winreg);
     275static errno_t display_server(void)
     276{
     277        return srv_start(SRV_DISPLAY);
     278}
     279
     280static int gui_start(const char *app, const char *display_svc)
     281{
     282        printf("%s: Spawning %s\n", NAME, app);
    293283
    294284        task_id_t id;
    295285        task_wait_t wait;
    296         errno_t rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
     286        errno_t rc = task_spawnl(&id, &wait, app, app, display_svc, NULL);
    297287        if (rc != EOK) {
    298288                oom_check(rc, app);
    299                 printf("%s: Error spawning %s %s (%s)\n", NAME, app,
    300                     winreg, str_error(rc));
    301                 return rc;
     289                printf("%s: Error spawning %s (%s)\n", NAME, app,
     290                    str_error(rc));
     291                return -1;
    302292        }
    303293
     
    480470
    481471        if (!config_key_exists("console")) {
    482                 rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
     472                rc = display_server();
    483473                if (rc == EOK) {
    484                         gui_start("/app/barber", HID_COMPOSITOR_SERVER);
    485                         gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
    486                         gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
     474                        gui_start("/app/barber", DISPLAY_SVC);
     475                        gui_start("/app/vlaunch", DISPLAY_SVC);
     476                        gui_start("/app/vterm", DISPLAY_SVC);
    487477                }
    488478        }
  • uspace/app/meson.build

    redb57bc6 re79a025  
    4545        'fontviewer',
    4646        'getterm',
     47        'gfxdemo',
    4748        'gunzip',
    4849        'hbench',
  • uspace/app/vterm/vterm.c

    redb57bc6 re79a025  
    5656        }
    5757
    58         window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_ANY);
     58        window_resize(main_window, 0, 0, 648, 508, WINDOW_PLACEMENT_TOP |
     59            WINDOW_PLACEMENT_LEFT);
    5960        terminal_t *terminal_widget =
    6061            create_terminal(window_root(main_window), NULL, 640, 480);
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c

    redb57bc6 re79a025  
    11/*
     2 * Copyright (c) 2020 Jiri Svoboda
    23 * Copyright (c) 2013 Jan Vesely
    34 * All rights reserved.
     
    3536
    3637#include <align.h>
     38#include <as.h>
    3739#include <assert.h>
    3840#include <errno.h>
     41#include <ddev_srv.h>
     42#include <ddev/info.h>
     43#include <ddf/driver.h>
    3944#include <ddf/log.h>
    4045#include <ddi.h>
    41 #include <as.h>
     46#include <gfx/color.h>
     47#include <io/pixelmap.h>
    4248
    4349#include "amdm37x_dispc.h"
     
    5561#endif
    5662
    57 static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
    58 static errno_t handle_damage(visualizer_t *vs,
    59     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    60     sysarg_t x_offset, sysarg_t y_offset);
    61 static errno_t dummy(visualizer_t *vs)
    62 {
    63         return EOK;
    64 }
    65 
    66 static const visualizer_ops_t amdm37x_dispc_vis_ops = {
    67         .change_mode = change_mode,
    68         .handle_damage = handle_damage,
    69         .claim = dummy,
    70         .yield = dummy,
    71         .suspend = dummy,
    72         .wakeup = dummy,
     63static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
     64    visual_t);
     65
     66static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     67static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
     68
     69static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
     70static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
     71static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     72    gfx_bitmap_alloc_t *, void **);
     73static errno_t amdm37x_gc_bitmap_destroy(void *);
     74static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     75static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     76
     77ddev_ops_t amdm37x_ddev_ops = {
     78        .get_gc = amdm37x_ddev_get_gc,
     79        .get_info = amdm37x_ddev_get_info
     80};
     81
     82gfx_context_ops_t amdm37x_gc_ops = {
     83        .set_color = amdm37x_gc_set_color,
     84        .fill_rect = amdm37x_gc_fill_rect,
     85        .bitmap_create = amdm37x_gc_bitmap_create,
     86        .bitmap_destroy = amdm37x_gc_bitmap_destroy,
     87        .bitmap_render = amdm37x_gc_bitmap_render,
     88        .bitmap_get_alloc = amdm37x_gc_bitmap_get_alloc
    7389};
    7490
     
    94110};
    95111
    96 static void mode_init(vslmode_list_element_t *mode,
    97     unsigned width, unsigned height, visual_t visual)
    98 {
    99         mode->mode.index = 0;
    100         mode->mode.version = 0;
    101         mode->mode.refresh_rate = 0;
    102         mode->mode.screen_aspect.width = width;
    103         mode->mode.screen_aspect.height = height;
    104         mode->mode.screen_width = width;
    105         mode->mode.screen_height = height;
    106         mode->mode.cell_aspect.width = 1;
    107         mode->mode.cell_aspect.height = 1;
    108         mode->mode.cell_visual.pixel_visual = visual;
    109 
    110         link_initialize(&mode->link);
    111 
    112 }
    113 
    114 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
    115 {
    116         assert(instance);
    117         assert(vis);
    118 
     112errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
     113{
     114        instance->fun = fun;
    119115        instance->fb_data = NULL;
    120116        instance->size = 0;
     
    145141        }
    146142
    147         mode_init(&instance->modes[0],
    148             CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, visual);
    149 
    150         /* Handle vis stuff */
    151         vis->dev_ctx = instance;
    152         vis->def_mode_idx = 0;
    153         vis->ops = amdm37x_dispc_vis_ops;
    154         list_append(&instance->modes[0].link, &vis->modes);
     143        ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
     144            CONFIG_BFB_HEIGHT, visual);
     145        if (ret != EOK)
     146                return EIO;
    155147
    156148        return EOK;
     
    269261}
    270262
    271 static errno_t change_mode(visualizer_t *vis, vslmode_t mode)
    272 {
    273         assert(vis);
    274         assert(vis->dev_ctx);
    275 
    276         amdm37x_dispc_t *dispc = vis->dev_ctx;
    277         const visual_t visual = mode.cell_visual.pixel_visual;
     263static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
     264    unsigned y, visual_t visual)
     265{
    278266        assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
    279267        const unsigned bpp = pixel2visual_table[visual].bpp;
    280268        pixel2visual_t p2v = pixel2visual_table[visual].func;
    281         const unsigned x = mode.screen_width;
    282         const unsigned y = mode.screen_height;
    283269        ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
    284270        const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
     
    296282        dispc->fb_data = buffer;
    297283        amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
    298         dispc->active_fb.idx = mode.index;
    299284        dispc->active_fb.width = x;
    300285        dispc->active_fb.height = y;
     
    302287        dispc->active_fb.bpp = bpp;
    303288        dispc->active_fb.pixel2visual = p2v;
     289        dispc->rect.p0.x = 0;
     290        dispc->rect.p0.y = 0;
     291        dispc->rect.p1.x = x;
     292        dispc->rect.p1.y = y;
    304293        dispc->size = size;
    305         assert(mode.index < 1);
    306 
    307         return EOK;
    308 }
    309 
    310 static errno_t handle_damage(visualizer_t *vs,
    311     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    312     sysarg_t x_offset, sysarg_t y_offset)
    313 {
    314         assert(vs);
    315         assert(vs->dev_ctx);
    316         amdm37x_dispc_t *dispc = vs->dev_ctx;
    317         pixelmap_t *map = &vs->cells;
    318 
    319 #define FB_POS(x, y) \
    320         (((y) * (dispc->active_fb.width + dispc->active_fb.pitch) + (x)) \
    321             * dispc->active_fb.bpp)
    322         if (x_offset == 0 && y_offset == 0) {
    323                 /* Faster damage routine ignoring offsets. */
    324                 for (sysarg_t y = y0; y < height + y0; ++y) {
    325                         pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
    326                         for (sysarg_t x = x0; x < width + x0; ++x) {
    327                                 dispc->active_fb.pixel2visual(
    328                                     dispc->fb_data + FB_POS(x, y), *pixel++);
    329                         }
     294
     295        return EOK;
     296}
     297
     298#define FB_POS(d, x, y) \
     299    (((y) * ((d)->active_fb.width + (d)->active_fb.pitch) + (x)) \
     300    * (d)->active_fb.bpp)
     301
     302static errno_t amdm37x_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     303{
     304        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     305
     306        *arg2 = ddf_fun_get_handle(dispc->fun);
     307        *arg3 = 42;
     308        return EOK;
     309}
     310
     311static errno_t amdm37x_ddev_get_info(void *arg, ddev_info_t *info)
     312{
     313        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     314
     315        ddev_info_init(info);
     316        info->rect.p0.x = 0;
     317        info->rect.p0.y = 0;
     318        info->rect.p1.x = dispc->active_fb.width;
     319        info->rect.p1.y = dispc->active_fb.height;
     320        return EOK;
     321}
     322
     323/** Set color on AMDM37x display controller.
     324 *
     325 * Set drawing color on AMDM37x GC.
     326 *
     327 * @param arg AMDM37x display controller
     328 * @param color Color
     329 *
     330 * @return EOK on success or an error code
     331 */
     332static errno_t amdm37x_gc_set_color(void *arg, gfx_color_t *color)
     333{
     334        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     335        uint16_t r, g, b;
     336
     337        gfx_color_get_rgb_i16(color, &r, &g, &b);
     338        dispc->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     339        return EOK;
     340}
     341
     342/** Fill rectangle on AMDM37x display controller.
     343 *
     344 * @param arg AMDM37x display controller
     345 * @param rect Rectangle
     346 *
     347 * @return EOK on success or an error code
     348 */
     349static errno_t amdm37x_gc_fill_rect(void *arg, gfx_rect_t *rect)
     350{
     351        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     352        gfx_rect_t crect;
     353        gfx_coord_t x, y;
     354
     355        /* Make sure we have a sorted, clipped rectangle */
     356        gfx_rect_clip(rect, &dispc->rect, &crect);
     357
     358        for (y = crect.p0.y; y < crect.p1.y; y++) {
     359                for (x = crect.p0.x; x < crect.p1.x; x++) {
     360                        dispc->active_fb.pixel2visual(dispc->fb_data +
     361                            FB_POS(dispc, x, y), dispc->color);
     362                }
     363        }
     364
     365        return EOK;
     366}
     367
     368/** Create bitmap in AMDM37x GC.
     369 *
     370 * @param arg AMDM37x display controller
     371 * @param params Bitmap params
     372 * @param alloc Bitmap allocation info or @c NULL
     373 * @param rbm Place to store pointer to new bitmap
     374 * @return EOK on success or an error code
     375 */
     376errno_t amdm37x_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     377    gfx_bitmap_alloc_t *alloc, void **rbm)
     378{
     379        amdm37x_dispc_t *dispc = (amdm37x_dispc_t *) arg;
     380        amdm37x_bitmap_t *dcbm = NULL;
     381        gfx_coord2_t dim;
     382        errno_t rc;
     383
     384        /* Check that we support all required flags */
     385        if ((params->flags & ~bmpf_color_key) != 0)
     386                return ENOTSUP;
     387
     388        dcbm = calloc(1, sizeof(amdm37x_bitmap_t));
     389        if (dcbm == NULL)
     390                return ENOMEM;
     391
     392        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     393        dcbm->rect = params->rect;
     394
     395        if (alloc == NULL) {
     396                dcbm->alloc.pitch = dim.x * sizeof(uint32_t);
     397                dcbm->alloc.off0 = 0;
     398                dcbm->alloc.pixels = malloc(dcbm->alloc.pitch * dim.y);
     399                dcbm->myalloc = true;
     400
     401                if (dcbm->alloc.pixels == NULL) {
     402                        rc = ENOMEM;
     403                        goto error;
    330404                }
    331405        } else {
    332                 for (sysarg_t y = y0; y < height + y0; ++y) {
    333                         for (sysarg_t x = x0; x < width + x0; ++x) {
    334                                 dispc->active_fb.pixel2visual(
    335                                     dispc->fb_data + FB_POS(x, y),
    336                                     *pixelmap_pixel_at(map,
    337                                     (x + x_offset) % map->width,
    338                                     (y + y_offset) % map->height));
    339                         }
     406                dcbm->alloc = *alloc;
     407        }
     408
     409        dcbm->dispc = dispc;
     410        *rbm = (void *)dcbm;
     411        return EOK;
     412error:
     413        if (rbm != NULL)
     414                free(dcbm);
     415        return rc;
     416}
     417
     418/** Destroy bitmap in AMDM37x GC.
     419 *
     420 * @param bm Bitmap
     421 * @return EOK on success or an error code
     422 */
     423static errno_t amdm37x_gc_bitmap_destroy(void *bm)
     424{
     425        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     426        if (dcbm->myalloc)
     427                free(dcbm->alloc.pixels);
     428        free(dcbm);
     429        return EOK;
     430}
     431
     432/** Render bitmap in AMDM37x GC.
     433 *
     434 * @param bm Bitmap
     435 * @param srect0 Source rectangle or @c NULL
     436 * @param offs0 Offset or @c NULL
     437 * @return EOK on success or an error code
     438 */
     439static errno_t amdm37x_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     440    gfx_coord2_t *offs0)
     441{
     442        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     443        amdm37x_dispc_t *dispc = dcbm->dispc;
     444        gfx_rect_t srect;
     445        gfx_rect_t drect;
     446        gfx_rect_t skfbrect;
     447        gfx_rect_t crect;
     448        gfx_coord2_t offs;
     449        gfx_coord2_t bmdim;
     450        gfx_coord2_t dim;
     451        gfx_coord2_t sp;
     452        gfx_coord2_t dp;
     453        gfx_coord2_t pos;
     454        pixelmap_t pbm;
     455        pixel_t color;
     456
     457        /* Clip source rectangle to bitmap bounds */
     458
     459        if (srect0 != NULL)
     460                gfx_rect_clip(srect0, &dcbm->rect, &srect);
     461        else
     462                srect = dcbm->rect;
     463
     464        if (offs0 != NULL) {
     465                offs = *offs0;
     466        } else {
     467                offs.x = 0;
     468                offs.y = 0;
     469        }
     470
     471        /* Destination rectangle */
     472        gfx_rect_translate(&offs, &srect, &drect);
     473        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     474        gfx_coord2_subtract(&dcbm->rect.p1, &dcbm->rect.p0, &bmdim);
     475
     476        pbm.width = bmdim.x;
     477        pbm.height = bmdim.y;
     478        pbm.data = dcbm->alloc.pixels;
     479
     480        /* Transform AMDM37x bounding rectangle back to bitmap coordinate system */
     481        gfx_rect_rtranslate(&offs, &dispc->rect, &skfbrect);
     482
     483        /*
     484         * Make sure we have a sorted source rectangle, clipped so that
     485         * destination lies within AMDM37x bounding rectangle
     486         */
     487        gfx_rect_clip(&srect, &skfbrect, &crect);
     488
     489        // XXX bmpf_color_key
     490        for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     491                for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     492                        gfx_coord2_subtract(&pos, &dcbm->rect.p0, &sp);
     493                        gfx_coord2_add(&pos, &offs, &dp);
     494
     495                        color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     496                        dispc->active_fb.pixel2visual(dispc->fb_data +
     497                            FB_POS(dispc, dp.x, dp.y), color);
    340498                }
    341499        }
    342500
     501        return EOK;
     502}
     503
     504/** Get allocation info for bitmap in AMDM37x GC.
     505 *
     506 * @param bm Bitmap
     507 * @param alloc Place to store allocation info
     508 * @return EOK on success or an error code
     509 */
     510static errno_t amdm37x_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     511{
     512        amdm37x_bitmap_t *dcbm = (amdm37x_bitmap_t *)bm;
     513        *alloc = dcbm->alloc;
    343514        return EOK;
    344515}
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h

    redb57bc6 re79a025  
    11/*
     2 * Copyright (c) 2020 Jiri Svoboda
    23 * Copyright (c) 2013 Jan Vesely
    34 * All rights reserved.
     
    3738#define AMDM37X_DISPC_H_
    3839
    39 #include <graph.h>
    4040#include <abi/fb/visuals.h>
     41#include <ddev_srv.h>
     42#include <ddf/driver.h>
     43#include <gfx/context.h>
     44#include <gfx/coord.h>
     45#include <io/pixel.h>
    4146#include <pixconv.h>
    4247#include <ddi.h>
     
    4550
    4651typedef struct {
     52        ddf_fun_t *fun;
    4753        amdm37x_dispc_regs_t *regs;
    4854
     
    5359                unsigned pitch;
    5460                unsigned bpp;
    55                 unsigned idx;
    5661        } active_fb;
    5762
     63        pixel_t color;
     64        gfx_rect_t rect;
    5865        size_t size;
    5966        void *fb_data;
    60 
    61         vslmode_list_element_t modes[1];
    6267} amdm37x_dispc_t;
    6368
    64 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis);
    65 errno_t amdm37x_dispc_fini(amdm37x_dispc_t *instance);
     69typedef struct {
     70        amdm37x_dispc_t *dispc;
     71        gfx_bitmap_alloc_t alloc;
     72        gfx_rect_t rect;
     73        bool myalloc;
     74} amdm37x_bitmap_t;
     75
     76extern ddev_ops_t amdm37x_ddev_ops;
     77extern gfx_context_ops_t amdm37x_gc_ops;
     78
     79extern errno_t amdm37x_dispc_init(amdm37x_dispc_t *, ddf_fun_t *);
     80extern errno_t amdm37x_dispc_fini(amdm37x_dispc_t *);
    6681
    6782#endif
  • uspace/drv/fb/amdm37x_dispc/main.c

    redb57bc6 re79a025  
    11/*
     2 * Copyright (c) 2020 Jiri Svoboda
    23 * Copyright (c) 2013 Jan Vesely
    34 * Copyright (c) 2011 Petr Koupy
     
    3536 */
    3637
     38#include <ddev_srv.h>
    3739#include <ddf/driver.h>
    3840#include <ddf/log.h>
    3941#include <errno.h>
     42#include <ipcgfx/server.h>
    4043#include <str_error.h>
    4144#include <stdio.h>
    42 #include <graph.h>
    4345
    4446#include "amdm37x_dispc.h"
     
    4648#define NAME  "amdm37x_dispc"
    4749
    48 static void graph_vsl_connection(ipc_call_t *icall, void *arg)
     50static void amdm37x_client_conn(ipc_call_t *icall, void *arg)
    4951{
    50         visualizer_t *vsl;
     52        amdm37x_dispc_t *dispc;
     53        ddev_srv_t srv;
     54        sysarg_t gc_id;
     55        gfx_context_t *gc;
     56        errno_t rc;
    5157
    52         vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
    53         graph_visualizer_connection(vsl, icall, NULL);
     58        dispc = (amdm37x_dispc_t *) ddf_dev_data_get(
     59            ddf_fun_get_dev((ddf_fun_t *) arg));
     60
     61        gc_id = ipc_get_arg3(icall);
     62
     63        if (gc_id == 0) {
     64                /* Set up protocol structure */
     65                ddev_srv_initialize(&srv);
     66                srv.ops = &amdm37x_ddev_ops;
     67                srv.arg = dispc;
     68
     69                /* Handle connection */
     70                ddev_conn(icall, &srv);
     71        } else {
     72                assert(gc_id == 42);
     73
     74                rc = gfx_context_new(&amdm37x_gc_ops, dispc, &gc);
     75                if (rc != EOK)
     76                        goto error;
     77
     78                /* GC connection */
     79                gc_conn(icall, gc);
     80        }
     81
     82        return;
     83error:
     84        async_answer_0(icall, rc);
    5485}
    5586
     
    5788{
    5889        assert(dev);
    59         /* Visualizer part */
    60         ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "viz");
     90
     91        ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "a");
    6192        if (!fun) {
    62                 ddf_log_error("Failed to create visualizer function.");
     93                ddf_log_error("Failed to create display device function.");
    6394                return ENOMEM;
    6495        }
    6596
    66         visualizer_t *vis = ddf_fun_data_alloc(fun, sizeof(visualizer_t));
    67         if (!vis) {
    68                 ddf_log_error("Failed to allocate visualizer structure.");
    69                 ddf_fun_destroy(fun);
    70                 return ENOMEM;
    71         }
     97        ddf_fun_set_conn_handler(fun, &amdm37x_client_conn);
    7298
    73         graph_init_visualizer(vis);
    74         vis->reg_svc_handle = ddf_fun_get_handle(fun);
    75 
    76         ddf_fun_set_conn_handler(fun, graph_vsl_connection);
    7799        /* Hw part */
    78100        amdm37x_dispc_t *dispc =
     
    84106        }
    85107
    86         errno_t rc = amdm37x_dispc_init(dispc, vis);
     108        errno_t rc = amdm37x_dispc_init(dispc, fun);
    87109        if (rc != EOK) {
    88110                ddf_log_error("Failed to init dispc: %s.", str_error(rc));
     
    100122        }
    101123
    102         rc = ddf_fun_add_to_category(fun, "visualizer");
     124        rc = ddf_fun_add_to_category(fun, "display-device");
    103125        if (rc != EOK) {
    104                 ddf_log_error("Failed to add function: %s to visualizer "
     126                ddf_log_error("Failed to add function: %s to display device "
    105127                    "category.", str_error(rc));
    106128                amdm37x_dispc_fini(dispc);
  • uspace/drv/fb/amdm37x_dispc/meson.build

    redb57bc6 re79a025  
    2929#
    3030
    31 deps = [ 'graph', 'softrend' ]
     31deps = [ 'gfx', 'ipcgfx', 'ddev', 'softrend' ]
    3232src = files('amdm37x_dispc.c', 'main.c')
  • uspace/drv/fb/kfb/kfb.c

    redb57bc6 re79a025  
    3636#include <errno.h>
    3737#include <stdio.h>
    38 #include <graph.h>
    3938#include "port.h"
    4039#include "kfb.h"
  • uspace/drv/fb/kfb/kfb.h

    redb57bc6 re79a025  
    4141#define NAME  "kfb"
    4242
    43 extern ddf_dev_ops_t graph_vsl_device_ops;
    44 extern ddf_dev_ops_t graph_rnd_device_ops;
    45 
    4643#endif
    4744
  • uspace/drv/fb/kfb/meson.build

    redb57bc6 re79a025  
    2929#
    3030
    31 deps = [ 'graph', 'softrend' ]
     31deps = [ 'gfx', 'ipcgfx', 'ddev', 'softrend' ]
    3232src = files('port.c', 'kfb.c')
  • uspace/drv/fb/kfb/port.c

    redb57bc6 re79a025  
    11/*
     2 * Copyright (c) 2019 Jiri Svoboda
    23 * Copyright (c) 2006 Jakub Vana
    34 * Copyright (c) 2006 Ondrej Palkovsky
     
    3839
    3940#include <abi/fb/visuals.h>
     41#include <adt/list.h>
     42#include <align.h>
     43#include <as.h>
     44#include <ddev_srv.h>
     45#include <ddev/info.h>
     46#include <ddi.h>
     47#include <ddf/log.h>
     48#include <errno.h>
     49#include <gfx/bitmap.h>
     50#include <gfx/color.h>
     51#include <gfx/coord.h>
     52#include <io/mode.h>
     53#include <io/pixelmap.h>
     54#include <ipcgfx/server.h>
     55#include <mem.h>
     56#include <pixconv.h>
    4057#include <stddef.h>
    4158#include <stdint.h>
    42 #include <errno.h>
    43 
    4459#include <stdlib.h>
    45 #include <mem.h>
    46 #include <as.h>
    47 #include <align.h>
    48 
    4960#include <sysinfo.h>
    50 #include <ddi.h>
    51 
    52 #include <adt/list.h>
    53 
    54 #include <io/mode.h>
    55 #include <io/pixelmap.h>
    56 #include <io/chargrid.h>
    57 
    58 #include <pixconv.h>
    59 
    60 #include <graph.h>
    6161
    6262#include "kfb.h"
    6363#include "port.h"
    6464
    65 #define FB_POS(x, y)  ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
     65#define FB_POS(fb, x, y)  ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes)
    6666
    6767typedef struct {
     68        ddf_fun_t *fun;
     69
    6870        sysarg_t paddr;
    69         sysarg_t width;
    70         sysarg_t height;
     71        gfx_rect_t rect;
    7172        size_t offset;
    7273        size_t scanline;
     
    8081        size_t size;
    8182        uint8_t *addr;
     83
     84        /** Current drawing color */
     85        pixel_t color;
    8286} kfb_t;
    8387
    84 static kfb_t kfb;
    85 
    86 static vslmode_list_element_t pixel_mode;
    87 
    88 static errno_t kfb_claim(visualizer_t *vs)
    89 {
    90         return physmem_map(kfb.paddr + kfb.offset,
    91             ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
    92             AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
    93 }
    94 
    95 static errno_t kfb_yield(visualizer_t *vs)
    96 {
     88typedef struct {
     89        kfb_t *kfb;
     90        gfx_bitmap_alloc_t alloc;
     91        gfx_rect_t rect;
     92        gfx_bitmap_flags_t flags;
     93        pixel_t key_color;
     94        bool myalloc;
     95} kfb_bitmap_t;
     96
     97static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     98static errno_t kfb_ddev_get_info(void *, ddev_info_t *);
     99
     100static errno_t kfb_gc_set_color(void *, gfx_color_t *);
     101static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *);
     102static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     103    gfx_bitmap_alloc_t *, void **);
     104static errno_t kfb_gc_bitmap_destroy(void *);
     105static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     106static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     107
     108static ddev_ops_t kfb_ddev_ops = {
     109        .get_gc = kfb_ddev_get_gc,
     110        .get_info = kfb_ddev_get_info
     111};
     112
     113static gfx_context_ops_t kfb_gc_ops = {
     114        .set_color = kfb_gc_set_color,
     115        .fill_rect = kfb_gc_fill_rect,
     116        .bitmap_create = kfb_gc_bitmap_create,
     117        .bitmap_destroy = kfb_gc_bitmap_destroy,
     118        .bitmap_render = kfb_gc_bitmap_render,
     119        .bitmap_get_alloc = kfb_gc_bitmap_get_alloc
     120};
     121
     122static errno_t kfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     123{
     124        kfb_t *kfb = (kfb_t *) arg;
     125
     126        *arg2 = ddf_fun_get_handle(kfb->fun);
     127        *arg3 = 42;
     128        return EOK;
     129}
     130
     131static errno_t kfb_ddev_get_info(void *arg, ddev_info_t *info)
     132{
     133        kfb_t *kfb = (kfb_t *) arg;
     134
     135        ddev_info_init(info);
     136        info->rect = kfb->rect;
     137        return EOK;
     138}
     139
     140/** Set color on KFB.
     141 *
     142 * Set drawing color on KFB GC.
     143 *
     144 * @param arg KFB
     145 * @param color Color
     146 *
     147 * @return EOK on success or an error code
     148 */
     149static errno_t kfb_gc_set_color(void *arg, gfx_color_t *color)
     150{
     151        kfb_t *kfb = (kfb_t *) arg;
     152        uint16_t r, g, b;
     153
     154        gfx_color_get_rgb_i16(color, &r, &g, &b);
     155        kfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     156        return EOK;
     157}
     158
     159/** Fill rectangle on KFB.
     160 *
     161 * @param arg KFB
     162 * @param rect Rectangle
     163 *
     164 * @return EOK on success or an error code
     165 */
     166static errno_t kfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
     167{
     168        kfb_t *kfb = (kfb_t *) arg;
     169        gfx_rect_t crect;
     170        gfx_coord_t x, y;
     171
     172        /* Make sure we have a sorted, clipped rectangle */
     173        gfx_rect_clip(rect, &kfb->rect, &crect);
     174
     175        for (y = crect.p0.y; y < crect.p1.y; y++) {
     176                for (x = crect.p0.x; x < crect.p1.x; x++) {
     177                        kfb->pixel2visual(kfb->addr + FB_POS(kfb, x, y),
     178                            kfb->color);
     179                }
     180        }
     181
     182        return EOK;
     183}
     184
     185/** Create bitmap in KFB GC.
     186 *
     187 * @param arg KFB
     188 * @param params Bitmap params
     189 * @param alloc Bitmap allocation info or @c NULL
     190 * @param rbm Place to store pointer to new bitmap
     191 * @return EOK on success or an error code
     192 */
     193errno_t kfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     194    gfx_bitmap_alloc_t *alloc, void **rbm)
     195{
     196        kfb_t *kfb = (kfb_t *) arg;
     197        kfb_bitmap_t *kfbbm = NULL;
     198        gfx_coord2_t dim;
    97199        errno_t rc;
    98200
    99         if (vs->mode_set) {
    100                 vs->ops.handle_damage = NULL;
    101         }
    102 
    103         rc = physmem_unmap(kfb.addr);
    104         if (rc != EOK)
    105                 return rc;
    106 
    107         kfb.addr = NULL;
    108         return EOK;
    109 }
    110 
    111 static errno_t kfb_handle_damage_pixels(visualizer_t *vs,
    112     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    113     sysarg_t x_offset, sysarg_t y_offset)
    114 {
    115         pixelmap_t *map = &vs->cells;
    116 
    117         if (x_offset == 0 && y_offset == 0) {
    118                 /* Faster damage routine ignoring offsets. */
    119                 for (sysarg_t y = y0; y < height + y0; ++y) {
    120                         pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
    121                         for (sysarg_t x = x0; x < width + x0; ++x) {
    122                                 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
     201        /* Check that we support all required flags */
     202        if ((params->flags & ~bmpf_color_key) != 0)
     203                return ENOTSUP;
     204
     205        kfbbm = calloc(1, sizeof(kfb_bitmap_t));
     206        if (kfbbm == NULL)
     207                return ENOMEM;
     208
     209        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     210        kfbbm->rect = params->rect;
     211        kfbbm->flags = params->flags;
     212        kfbbm->key_color = params->key_color;
     213
     214        if (alloc == NULL) {
     215                kfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
     216                kfbbm->alloc.off0 = 0;
     217                kfbbm->alloc.pixels = malloc(kfbbm->alloc.pitch * dim.y);
     218                kfbbm->myalloc = true;
     219
     220                if (kfbbm->alloc.pixels == NULL) {
     221                        rc = ENOMEM;
     222                        goto error;
     223                }
     224        } else {
     225                kfbbm->alloc = *alloc;
     226        }
     227
     228        kfbbm->kfb = kfb;
     229        *rbm = (void *)kfbbm;
     230        return EOK;
     231error:
     232        if (rbm != NULL)
     233                free(kfbbm);
     234        return rc;
     235}
     236
     237/** Destroy bitmap in KFB GC.
     238 *
     239 * @param bm Bitmap
     240 * @return EOK on success or an error code
     241 */
     242static errno_t kfb_gc_bitmap_destroy(void *bm)
     243{
     244        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     245        if (kfbbm->myalloc)
     246                free(kfbbm->alloc.pixels);
     247        free(kfbbm);
     248        return EOK;
     249}
     250
     251/** Render bitmap in KFB GC.
     252 *
     253 * @param bm Bitmap
     254 * @param srect0 Source rectangle or @c NULL
     255 * @param offs0 Offset or @c NULL
     256 * @return EOK on success or an error code
     257 */
     258static errno_t kfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     259    gfx_coord2_t *offs0)
     260{
     261        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     262        kfb_t *kfb = kfbbm->kfb;
     263        gfx_rect_t srect;
     264        gfx_rect_t drect;
     265        gfx_rect_t skfbrect;
     266        gfx_rect_t crect;
     267        gfx_coord2_t offs;
     268        gfx_coord2_t bmdim;
     269        gfx_coord2_t dim;
     270        gfx_coord2_t sp;
     271        gfx_coord2_t dp;
     272        gfx_coord2_t pos;
     273        pixelmap_t pbm;
     274        pixel_t color;
     275
     276        /* Clip source rectangle to bitmap bounds */
     277
     278        if (srect0 != NULL)
     279                gfx_rect_clip(srect0, &kfbbm->rect, &srect);
     280        else
     281                srect = kfbbm->rect;
     282
     283        if (offs0 != NULL) {
     284                offs = *offs0;
     285        } else {
     286                offs.x = 0;
     287                offs.y = 0;
     288        }
     289
     290        /* Destination rectangle */
     291        gfx_rect_translate(&offs, &srect, &drect);
     292        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     293        gfx_coord2_subtract(&kfbbm->rect.p1, &kfbbm->rect.p0, &bmdim);
     294
     295        pbm.width = bmdim.x;
     296        pbm.height = bmdim.y;
     297        pbm.data = kfbbm->alloc.pixels;
     298
     299        /* Transform KFB bounding rectangle back to bitmap coordinate system */
     300        gfx_rect_rtranslate(&offs, &kfb->rect, &skfbrect);
     301
     302        /*
     303         * Make sure we have a sorted source rectangle, clipped so that
     304         * destination lies within KFB bounding rectangle
     305         */
     306        gfx_rect_clip(&srect, &skfbrect, &crect);
     307
     308        if ((kfbbm->flags & bmpf_color_key) != 0) {
     309                for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     310                        for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     311                                gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
     312                                gfx_coord2_add(&pos, &offs, &dp);
     313
     314                                color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     315                                if (color != kfbbm->key_color) {
     316                                        kfb->pixel2visual(kfb->addr +
     317                                            FB_POS(kfb, dp.x, dp.y), color);
     318                                }
    123319                        }
    124320                }
    125321        } else {
    126                 for (sysarg_t y = y0; y < height + y0; ++y) {
    127                         for (sysarg_t x = x0; x < width + x0; ++x) {
    128                                 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
    129                                     *pixelmap_pixel_at(map,
    130                                     (x + x_offset) % map->width,
    131                                     (y + y_offset) % map->height));
     322                for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     323                        for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     324                                gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
     325                                gfx_coord2_add(&pos, &offs, &dp);
     326
     327                                color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     328                                kfb->pixel2visual(kfb->addr +
     329                                    FB_POS(kfb, dp.x, dp.y), color);
    132330                        }
    133331                }
     
    137335}
    138336
    139 static errno_t kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
    140 {
    141         vs->ops.handle_damage = kfb_handle_damage_pixels;
    142         return EOK;
    143 }
    144 
    145 static errno_t kfb_suspend(visualizer_t *vs)
    146 {
    147         return EOK;
    148 }
    149 
    150 static errno_t kfb_wakeup(visualizer_t *vs)
    151 {
    152         return EOK;
    153 }
    154 
    155 static visualizer_ops_t kfb_ops = {
    156         .claim = kfb_claim,
    157         .yield = kfb_yield,
    158         .change_mode = kfb_change_mode,
    159         .handle_damage = NULL,
    160         .suspend = kfb_suspend,
    161         .wakeup = kfb_wakeup
    162 };
    163 
    164 static void graph_vsl_connection(ipc_call_t *icall, void *arg)
    165 {
    166         visualizer_t *vsl;
     337/** Get allocation info for bitmap in KFB GC.
     338 *
     339 * @param bm Bitmap
     340 * @param alloc Place to store allocation info
     341 * @return EOK on success or an error code
     342 */
     343static errno_t kfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     344{
     345        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     346        *alloc = kfbbm->alloc;
     347        return EOK;
     348}
     349
     350#include <stdio.h>
     351static void kfb_client_conn(ipc_call_t *icall, void *arg)
     352{
     353        kfb_t *kfb;
     354        ddev_srv_t srv;
     355        sysarg_t gc_id;
     356        gfx_context_t *gc;
    167357        errno_t rc;
    168358
    169         vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
    170         graph_visualizer_connection(vsl, icall, NULL);
    171 
    172         if (kfb.addr != NULL) {
    173                 rc = physmem_unmap(kfb.addr);
     359        kfb = (kfb_t *) ddf_fun_data_get((ddf_fun_t *) arg);
     360
     361        printf("kfb_client_conn arg2=%lu arg3=%lu arg4=%lu\n",
     362            (unsigned long) ipc_get_arg2(icall),
     363            (unsigned long) ipc_get_arg3(icall),
     364            (unsigned long) ipc_get_arg4(icall));
     365
     366        gc_id = ipc_get_arg3(icall);
     367
     368        if (gc_id == 0) {
     369                /* Set up protocol structure */
     370                ddev_srv_initialize(&srv);
     371                srv.ops = &kfb_ddev_ops;
     372                srv.arg = kfb;
     373
     374                /* Handle connection */
     375                ddev_conn(icall, &srv);
     376        } else {
     377                assert(gc_id == 42);
     378
     379                if (kfb->addr != AS_AREA_ANY) {
     380                        /* This means there already is a GC connection */
     381                        async_answer_0(icall, EBUSY);
     382                        return;
     383                }
     384
     385                rc = physmem_map(kfb->paddr + kfb->offset,
     386                    ALIGN_UP(kfb->size, PAGE_SIZE) >> PAGE_WIDTH,
     387                    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb->addr);
     388                if (rc != EOK)
     389                        goto error;
     390
     391                rc = gfx_context_new(&kfb_gc_ops, kfb, &gc);
     392                if (rc != EOK)
     393                        goto error;
     394
     395                /* GC connection */
     396                gc_conn(icall, gc);
     397
     398                rc = physmem_unmap(kfb->addr);
    174399                if (rc == EOK)
    175                         kfb.addr = NULL;
    176         }
     400                        kfb->addr = AS_AREA_ANY;
     401        }
     402
     403        return;
     404error:
     405        if (kfb->addr != AS_AREA_ANY) {
     406                if (physmem_unmap(kfb->addr) == EOK)
     407                        kfb->addr = AS_AREA_ANY;
     408        }
     409
     410        async_answer_0(icall, rc);
    177411}
    178412
    179413errno_t port_init(ddf_dev_t *dev)
    180414{
     415        ddf_fun_t *fun = NULL;
     416        kfb_t *kfb = NULL;
     417        errno_t rc;
     418
     419        fun = ddf_fun_create(dev, fun_exposed, "kfb");
     420        if (fun == NULL) {
     421                rc = ENOMEM;
     422                goto error;
     423        }
     424
     425        ddf_fun_set_conn_handler(fun, &kfb_client_conn);
     426
     427        kfb = ddf_fun_data_alloc(fun, sizeof(kfb_t));
     428        if (kfb == NULL) {
     429                rc = ENOMEM;
     430                goto error;
     431        }
     432
    181433        sysarg_t present;
    182         errno_t rc = sysinfo_get_value("fb", &present);
     434        rc = sysinfo_get_value("fb", &present);
    183435        if (rc != EOK)
    184436                present = false;
    185437
    186         if (!present)
    187                 return ENOENT;
     438        if (!present) {
     439                ddf_fun_destroy(fun);
     440                rc = ENOENT;
     441                goto error;
     442        }
    188443
    189444        sysarg_t kind;
     
    192447                kind = (sysarg_t) -1;
    193448
    194         if (kind != 1)
    195                 return EINVAL;
     449        if (kind != 1) {
     450                rc = EINVAL;
     451                goto error;
     452        }
    196453
    197454        sysarg_t paddr;
    198455        rc = sysinfo_get_value("fb.address.physical", &paddr);
    199456        if (rc != EOK)
    200                 return rc;
     457                goto error;
    201458
    202459        sysarg_t offset;
     
    208465        rc = sysinfo_get_value("fb.width", &width);
    209466        if (rc != EOK)
    210                 return rc;
     467                goto error;
    211468
    212469        sysarg_t height;
    213470        rc = sysinfo_get_value("fb.height", &height);
    214471        if (rc != EOK)
    215                 return rc;
     472                goto error;
    216473
    217474        sysarg_t scanline;
    218475        rc = sysinfo_get_value("fb.scanline", &scanline);
    219476        if (rc != EOK)
    220                 return rc;
     477                goto error;
    221478
    222479        sysarg_t visual;
    223480        rc = sysinfo_get_value("fb.visual", &visual);
    224481        if (rc != EOK)
    225                 return rc;
    226 
    227         kfb.width = width;
    228         kfb.height = height;
    229         kfb.paddr = paddr;
    230         kfb.offset = offset;
    231         kfb.scanline = scanline;
    232         kfb.visual = visual;
     482                goto error;
     483
     484        kfb->fun = fun;
     485
     486        kfb->rect.p0.x = 0;
     487        kfb->rect.p0.y = 0;
     488        kfb->rect.p1.x = width;
     489        kfb->rect.p1.y = height;
     490
     491        kfb->paddr = paddr;
     492        kfb->offset = offset;
     493        kfb->scanline = scanline;
     494        kfb->visual = visual;
    233495
    234496        switch (visual) {
    235497        case VISUAL_INDIRECT_8:
    236                 kfb.pixel2visual = pixel2bgr_323;
    237                 kfb.visual2pixel = bgr_323_2pixel;
    238                 kfb.visual_mask = visual_mask_323;
    239                 kfb.pixel_bytes = 1;
     498                kfb->pixel2visual = pixel2bgr_323;
     499                kfb->visual2pixel = bgr_323_2pixel;
     500                kfb->visual_mask = visual_mask_323;
     501                kfb->pixel_bytes = 1;
    240502                break;
    241503        case VISUAL_RGB_5_5_5_LE:
    242                 kfb.pixel2visual = pixel2rgb_555_le;
    243                 kfb.visual2pixel = rgb_555_le_2pixel;
    244                 kfb.visual_mask = visual_mask_555;
    245                 kfb.pixel_bytes = 2;
     504                kfb->pixel2visual = pixel2rgb_555_le;
     505                kfb->visual2pixel = rgb_555_le_2pixel;
     506                kfb->visual_mask = visual_mask_555;
     507                kfb->pixel_bytes = 2;
    246508                break;
    247509        case VISUAL_RGB_5_5_5_BE:
    248                 kfb.pixel2visual = pixel2rgb_555_be;
    249                 kfb.visual2pixel = rgb_555_be_2pixel;
    250                 kfb.visual_mask = visual_mask_555;
    251                 kfb.pixel_bytes = 2;
     510                kfb->pixel2visual = pixel2rgb_555_be;
     511                kfb->visual2pixel = rgb_555_be_2pixel;
     512                kfb->visual_mask = visual_mask_555;
     513                kfb->pixel_bytes = 2;
    252514                break;
    253515        case VISUAL_RGB_5_6_5_LE:
    254                 kfb.pixel2visual = pixel2rgb_565_le;
    255                 kfb.visual2pixel = rgb_565_le_2pixel;
    256                 kfb.visual_mask = visual_mask_565;
    257                 kfb.pixel_bytes = 2;
     516                kfb->pixel2visual = pixel2rgb_565_le;
     517                kfb->visual2pixel = rgb_565_le_2pixel;
     518                kfb->visual_mask = visual_mask_565;
     519                kfb->pixel_bytes = 2;
    258520                break;
    259521        case VISUAL_RGB_5_6_5_BE:
    260                 kfb.pixel2visual = pixel2rgb_565_be;
    261                 kfb.visual2pixel = rgb_565_be_2pixel;
    262                 kfb.visual_mask = visual_mask_565;
    263                 kfb.pixel_bytes = 2;
     522                kfb->pixel2visual = pixel2rgb_565_be;
     523                kfb->visual2pixel = rgb_565_be_2pixel;
     524                kfb->visual_mask = visual_mask_565;
     525                kfb->pixel_bytes = 2;
    264526                break;
    265527        case VISUAL_RGB_8_8_8:
    266                 kfb.pixel2visual = pixel2rgb_888;
    267                 kfb.visual2pixel = rgb_888_2pixel;
    268                 kfb.visual_mask = visual_mask_888;
    269                 kfb.pixel_bytes = 3;
     528                kfb->pixel2visual = pixel2rgb_888;
     529                kfb->visual2pixel = rgb_888_2pixel;
     530                kfb->visual_mask = visual_mask_888;
     531                kfb->pixel_bytes = 3;
    270532                break;
    271533        case VISUAL_BGR_8_8_8:
    272                 kfb.pixel2visual = pixel2bgr_888;
    273                 kfb.visual2pixel = bgr_888_2pixel;
    274                 kfb.visual_mask = visual_mask_888;
    275                 kfb.pixel_bytes = 3;
     534                kfb->pixel2visual = pixel2bgr_888;
     535                kfb->visual2pixel = bgr_888_2pixel;
     536                kfb->visual_mask = visual_mask_888;
     537                kfb->pixel_bytes = 3;
    276538                break;
    277539        case VISUAL_RGB_8_8_8_0:
    278                 kfb.pixel2visual = pixel2rgb_8880;
    279                 kfb.visual2pixel = rgb_8880_2pixel;
    280                 kfb.visual_mask = visual_mask_8880;
    281                 kfb.pixel_bytes = 4;
     540                kfb->pixel2visual = pixel2rgb_8880;
     541                kfb->visual2pixel = rgb_8880_2pixel;
     542                kfb->visual_mask = visual_mask_8880;
     543                kfb->pixel_bytes = 4;
    282544                break;
    283545        case VISUAL_RGB_0_8_8_8:
    284                 kfb.pixel2visual = pixel2rgb_0888;
    285                 kfb.visual2pixel = rgb_0888_2pixel;
    286                 kfb.visual_mask = visual_mask_0888;
    287                 kfb.pixel_bytes = 4;
     546                kfb->pixel2visual = pixel2rgb_0888;
     547                kfb->visual2pixel = rgb_0888_2pixel;
     548                kfb->visual_mask = visual_mask_0888;
     549                kfb->pixel_bytes = 4;
    288550                break;
    289551        case VISUAL_BGR_0_8_8_8:
    290                 kfb.pixel2visual = pixel2bgr_0888;
    291                 kfb.visual2pixel = bgr_0888_2pixel;
    292                 kfb.visual_mask = visual_mask_0888;
    293                 kfb.pixel_bytes = 4;
     552                kfb->pixel2visual = pixel2bgr_0888;
     553                kfb->visual2pixel = bgr_0888_2pixel;
     554                kfb->visual_mask = visual_mask_0888;
     555                kfb->pixel_bytes = 4;
    294556                break;
    295557        case VISUAL_BGR_8_8_8_0:
    296                 kfb.pixel2visual = pixel2bgr_8880;
    297                 kfb.visual2pixel = bgr_8880_2pixel;
    298                 kfb.visual_mask = visual_mask_8880;
    299                 kfb.pixel_bytes = 4;
     558                kfb->pixel2visual = pixel2bgr_8880;
     559                kfb->visual2pixel = bgr_8880_2pixel;
     560                kfb->visual_mask = visual_mask_8880;
     561                kfb->pixel_bytes = 4;
    300562                break;
    301563        default:
     
    303565        }
    304566
    305         kfb.size = scanline * height;
    306         kfb.addr = AS_AREA_ANY;
    307 
    308         ddf_fun_t *fun_vs = ddf_fun_create(dev, fun_exposed, "vsl0");
    309         if (fun_vs == NULL) {
    310                 as_area_destroy(kfb.addr);
    311                 return ENOMEM;
    312         }
    313         ddf_fun_set_conn_handler(fun_vs, &graph_vsl_connection);
    314 
    315         visualizer_t *vs = ddf_fun_data_alloc(fun_vs, sizeof(visualizer_t));
    316         if (vs == NULL) {
    317                 as_area_destroy(kfb.addr);
    318                 return ENOMEM;
    319         }
    320         graph_init_visualizer(vs);
    321 
    322         pixel_mode.mode.index = 0;
    323         pixel_mode.mode.version = 0;
    324         pixel_mode.mode.refresh_rate = 0;
    325         pixel_mode.mode.screen_aspect.width = width;
    326         pixel_mode.mode.screen_aspect.height = height;
    327         pixel_mode.mode.screen_width = width;
    328         pixel_mode.mode.screen_height = height;
    329         pixel_mode.mode.cell_aspect.width = 1;
    330         pixel_mode.mode.cell_aspect.height = 1;
    331         pixel_mode.mode.cell_visual.pixel_visual = visual;
    332 
    333         link_initialize(&pixel_mode.link);
    334         list_append(&pixel_mode.link, &vs->modes);
    335 
    336         vs->def_mode_idx = 0;
    337 
    338         vs->ops = kfb_ops;
    339         vs->dev_ctx = NULL;
    340 
    341         rc = ddf_fun_bind(fun_vs);
     567        kfb->size = scanline * height;
     568        kfb->addr = AS_AREA_ANY;
     569
     570        rc = ddf_fun_bind(fun);
     571        if (rc != EOK)
     572                goto error;
     573
     574        rc = ddf_fun_add_to_category(fun, "display-device");
    342575        if (rc != EOK) {
    343                 list_remove(&pixel_mode.link);
    344                 ddf_fun_destroy(fun_vs);
    345                 as_area_destroy(kfb.addr);
    346                 return rc;
    347         }
    348 
    349         vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
    350         rc = ddf_fun_add_to_category(fun_vs, "visualizer");
    351         if (rc != EOK) {
    352                 list_remove(&pixel_mode.link);
    353                 ddf_fun_unbind(fun_vs);
    354                 ddf_fun_destroy(fun_vs);
    355                 as_area_destroy(kfb.addr);
    356                 return rc;
    357         }
    358 
    359         return EOK;
     576                ddf_fun_unbind(fun);
     577                goto error;
     578        }
     579
     580        return EOK;
     581error:
     582        if (fun != NULL)
     583                ddf_fun_destroy(fun);
     584        return rc;
    360585}
    361586
  • uspace/lib/c/include/io/kbd_event.h

    redb57bc6 re79a025  
    3737
    3838#include <adt/list.h>
     39#include <inttypes.h>
    3940#include <io/keycode.h>
    4041
  • uspace/lib/c/include/io/window.h

    redb57bc6 re79a025  
    3636#define _LIBC_IO_WINDOW_H_
    3737
    38 #include <stdbool.h>
    39 #include <async.h>
    40 #include <loc.h>
    4138#include <io/kbd_event.h>
    4239#include <io/pos_event.h>
     40#include <types/common.h>
    4341
    4442typedef enum {
     
    113111} window_event_t;
    114112
    115 extern errno_t win_register(async_sess_t *, window_flags_t, service_id_t *,
    116     service_id_t *);
    117 
    118 extern errno_t win_get_event(async_sess_t *, window_event_t *);
    119 
    120 extern errno_t win_damage(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
    121 extern errno_t win_grab(async_sess_t *, sysarg_t, sysarg_t);
    122 extern errno_t win_resize(async_sess_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    123     window_placement_flags_t, void *);
    124 extern errno_t win_close(async_sess_t *);
    125 extern errno_t win_close_request(async_sess_t *);
    126 
    127113#endif
    128114
  • uspace/lib/c/include/ipc/services.h

    redb57bc6 re79a025  
    5454#define SERVICE_NAME_CLIPBOARD "clipboard"
    5555#define SERVICE_NAME_CORECFG  "corecfg"
     56#define SERVICE_NAME_DISPLAY  "hid/display"
    5657#define SERVICE_NAME_DHCP     "net/dhcp"
    5758#define SERVICE_NAME_DNSR     "net/dnsr"
  • uspace/lib/c/meson.build

    redb57bc6 re79a025  
    131131        'generic/io/console.c',
    132132        'generic/io/table.c',
    133         'generic/io/visualizer.c',
    134         'generic/io/window.c',
    135133        'generic/iplink.c',
    136134        'generic/iplink_srv.c',
  • uspace/lib/congfx/meson.build

    redb57bc6 re79a025  
    11#
    2 # Copyright (c) 2011 Petr Koupy
     2# Copyright (c) 2019 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 src = files('graph.c')
     29deps = [ 'gfx' ]
     30src = files(
     31        'src/console.c',
     32)
  • uspace/lib/ddev/include/ddev_srv.h

    redb57bc6 re79a025  
    11/*
    2  * Copyright (c) 2011 Petr Koupy
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
     29/** @addtogroup libdisplay
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef _LIBC_IO_VISUALIZER_H_
    36 #define _LIBC_IO_VISUALIZER_H_
     35#ifndef _LIBDDEV_DDEV_SRV_H_
     36#define _LIBDDEV_DDEV_SRV_H_
    3737
    3838#include <async.h>
    39 #include <io/mode.h>
     39#include <errno.h>
     40#include <gfx/context.h>
     41#include "types/ddev/info.h"
    4042
    41 extern errno_t visualizer_claim(async_sess_t *, sysarg_t);
    42 extern errno_t visualizer_yield(async_sess_t *);
     43typedef struct ddev_ops ddev_ops_t;
    4344
    44 extern errno_t visualizer_enumerate_modes(async_sess_t *, vslmode_t *, sysarg_t);
    45 extern errno_t visualizer_get_default_mode(async_sess_t *, vslmode_t *);
    46 extern errno_t visualizer_get_current_mode(async_sess_t *, vslmode_t *);
    47 extern errno_t visualizer_get_mode(async_sess_t *, vslmode_t *, sysarg_t);
    48 extern errno_t visualizer_set_mode(async_sess_t *, sysarg_t, sysarg_t, void *);
     45/** Display device server structure (per client session) */
     46typedef struct {
     47        async_sess_t *client_sess;
     48        ddev_ops_t *ops;
     49        void *arg;
     50} ddev_srv_t;
    4951
    50 extern errno_t visualizer_update_damaged_region(async_sess_t *,
    51     sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
     52struct ddev_ops {
     53        errno_t (*get_gc)(void *, sysarg_t *, sysarg_t *);
     54        errno_t (*get_info)(void *, ddev_info_t *);
     55};
    5256
    53 extern errno_t visualizer_suspend(async_sess_t *);
    54 extern errno_t visualizer_wakeup(async_sess_t *);
     57extern void ddev_conn(ipc_call_t *, ddev_srv_t *);
     58extern void ddev_srv_initialize(ddev_srv_t *);
    5559
    5660#endif
  • uspace/lib/display/include/ipc/display.h

    redb57bc6 re79a025  
    11/*
    2  * Copyright (c) 2011 Petr Koupy
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
     29/** @addtogroup libdisplay
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef _LIBC_IPC_GRAPH_H_
    36 #define _LIBC_IPC_GRAPH_H_
     35#ifndef _LIBC_IPC_DISPLAY_H_
     36#define _LIBC_IPC_DISPLAY_H_
    3737
    3838#include <ipc/common.h>
    3939
    4040typedef enum {
    41         VISUALIZER_CLAIM = IPC_FIRST_USER_METHOD,
    42         VISUALIZER_YIELD,
    43 
    44         VISUALIZER_ENUMERATE_MODES,
    45         VISUALIZER_GET_DEFAULT_MODE,
    46         VISUALIZER_GET_CURRENT_MODE,
    47         VISUALIZER_GET_MODE,
    48         VISUALIZER_SET_MODE,
    49 
    50         VISUALIZER_UPDATE_DAMAGED_REGION,
    51 
    52         VISUALIZER_SUSPEND,
    53         VISUALIZER_WAKE_UP,
    54 } visualizer_request_t;
     41        DISPLAY_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
     42        DISPLAY_WINDOW_CREATE,
     43        DISPLAY_WINDOW_DESTROY,
     44        DISPLAY_WINDOW_MOVE,
     45        DISPLAY_WINDOW_MOVE_REQ,
     46        DISPLAY_WINDOW_RESIZE,
     47        DISPLAY_WINDOW_RESIZE_REQ,
     48        DISPLAY_WINDOW_SET_CURSOR,
     49        DISPLAY_GET_EVENT,
     50        DISPLAY_GET_INFO
     51} display_request_t;
    5552
    5653typedef enum {
    57         VISUALIZER_MODE_CHANGE = IPC_FIRST_USER_METHOD,
    58         VISUALIZER_DISCONNECT
    59 } visualizer_notif_t;
    60 
    61 typedef enum {
    62         RENDERER_REQ_NONE = IPC_FIRST_USER_METHOD,
    63         // TODO: similar interface as provides libsoftrend
    64 } renderer_request_t;
    65 
    66 typedef enum {
    67         RENDERER_NOTIF_NONE = IPC_FIRST_USER_METHOD,
    68         // TODO: similar interface as provides libsoftrend
    69 } renderer_notif_t;
     54        DISPLAY_EV_PENDING = IPC_FIRST_USER_METHOD
     55} display_event_t;
    7056
    7157#endif
  • uspace/lib/gfx/include/types/gfx/coord.h

    redb57bc6 re79a025  
    11/*
    2  * Copyright (c) 2012 Petr Koupy
     2 * Copyright (c) 2019 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup compositor
     29/** @addtogroup libgfx
    3030 * @{
    3131 */
    32 /** @file
     32/**
     33 * @file Graphic coordinates
    3334 */
    3435
    35 #ifndef COMPOSITOR_COMPOSITOR_H_
    36 #define COMPOSITOR_COMPOSITOR_H_
     36#ifndef _GFX_TYPES_COORD_H
     37#define _GFX_TYPES_COORD_H
    3738
    38 typedef native_t desktop_coord_t;
     39#include <errno.h>
     40#include <stdint.h>
     41
     42typedef int gfx_coord_t;
    3943
    4044typedef struct {
    41         desktop_coord_t x;
    42         desktop_coord_t y;
    43 } desktop_point_t;
    44 
    45 typedef desktop_point_t desktop_vector_t;
     45        gfx_coord_t x;
     46        gfx_coord_t y;
     47} gfx_coord2_t;
    4648
    4749typedef struct {
    48         desktop_coord_t x;
    49         desktop_coord_t y;
    50         desktop_coord_t w;
    51         desktop_coord_t h;
    52 } desktop_rect_t;
    53 
    54 /* TODO remove? */
    55 typedef struct {
    56         double x;
    57         double y;
    58 } double_point_t;
    59 
    60 typedef double_point_t double_vector_t;
     50        gfx_coord2_t p0;
     51        gfx_coord2_t p1;
     52} gfx_rect_t;
    6153
    6254#endif
  • uspace/lib/gui/meson.build

    redb57bc6 re79a025  
    2727#
    2828
    29 deps = [ 'draw' , 'softrend' , 'graph' ]
     29deps = [ 'draw' , 'softrend', 'display' ]
    3030src = files(
    3131        'common.c',
  • uspace/lib/gui/terminal.c

    redb57bc6 re79a025  
    4242#include <io/concaps.h>
    4343#include <io/console.h>
     44#include <loc.h>
    4445#include <task.h>
    4546#include <adt/list.h>
  • uspace/lib/gui/terminal.h

    redb57bc6 re79a025  
    4242#include <io/chargrid.h>
    4343#include <io/con_srv.h>
     44#include <loc.h>
    4445#include <adt/list.h>
    4546#include <adt/prodcons.h>
  • uspace/lib/gui/window.c

    redb57bc6 re79a025  
    4848#include <adt/list.h>
    4949
    50 #include <async.h>
    5150#include <loc.h>
    5251
     
    5655#include <draw/drawctx.h>
    5756#include <draw/surface.h>
     57#include <display.h>
    5858
    5959#include "common.h"
     
    6767static sysarg_t header_min_width = 40;
    6868static sysarg_t close_thickness = 20;
     69static sysarg_t corner_size = 24;
     70static sysarg_t window_initial_size = 1;
    6971
    7072static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
     
    8284static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
    8385static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
     86
     87static void window_close_event(void *);
     88static void window_focus_event(void *);
     89static void window_kbd_event(void *, kbd_event_t *);
     90static void window_pos_event(void *, pos_event_t *);
     91static void window_resize_event(void *, gfx_rect_t *);
     92static void window_unfocus_event(void *);
     93
     94static display_wnd_cb_t window_cb = {
     95        .close_event = window_close_event,
     96        .focus_event = window_focus_event,
     97        .kbd_event = window_kbd_event,
     98        .pos_event = window_pos_event,
     99        .resize_event = window_resize_event,
     100        .unfocus_event = window_unfocus_event
     101};
     102
     103static void set_cursor(window_t *window, display_stock_cursor_t cursor)
     104{
     105        if (cursor != window->cursor) {
     106                (void) display_window_set_cursor(window->dwindow, cursor);
     107                window->cursor = cursor;
     108        }
     109}
    84110
    85111static void paint_internal(widget_t *widget)
     
    258284static void root_handle_position_event(widget_t *widget, pos_event_t event)
    259285{
     286        gfx_coord2_t pos;
     287
    260288        if (widget->window->is_decorated) {
    261289                sysarg_t width = widget->width;
     
    263291
    264292                bool btn_left = (event.btn_num == 1) && (event.type == POS_PRESS);
    265                 bool btn_right = (event.btn_num == 2) && (event.type == POS_PRESS);
    266                 bool allowed_button = btn_left || btn_right;
    267293
    268294                bool left = (event.hpos < border_thickness);
     
    270296                bool top = (event.vpos < border_thickness);
    271297                bool bottom = (event.vpos >= height - border_thickness);
     298                bool edge = left || right || top || bottom;
     299
     300                bool cleft = (event.hpos < corner_size);
     301                bool cright = (event.hpos >= width - corner_size);
     302                bool ctop = (event.vpos < corner_size);
     303                bool cbottom = (event.vpos >= height - corner_size);
     304
    272305                bool header = (event.hpos >= border_thickness) &&
    273306                    (event.hpos < width - border_thickness) &&
     
    277310                    (event.hpos >= width - border_thickness - close_thickness);
    278311
    279                 if (top && left && allowed_button) {
    280                         window_grab_flags_t flags = GF_EMPTY;
    281                         flags |= GF_MOVE_X;
    282                         flags |= GF_MOVE_Y;
    283                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    284                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    285                         win_grab(widget->window->osess, event.pos_id, flags);
    286                 } else if (bottom && left && allowed_button) {
    287                         window_grab_flags_t flags = GF_EMPTY;
    288                         flags |= GF_MOVE_X;
    289                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    290                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    291                         win_grab(widget->window->osess, event.pos_id, flags);
    292                 } else if (bottom && right && allowed_button) {
    293                         window_grab_flags_t flags = GF_EMPTY;
    294                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    295                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    296                         win_grab(widget->window->osess, event.pos_id, flags);
    297                 } else if (top && right && allowed_button) {
    298                         window_grab_flags_t flags = GF_EMPTY;
    299                         flags |= GF_MOVE_Y;
    300                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    301                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    302                         win_grab(widget->window->osess, event.pos_id, flags);
    303                 } else if (top && allowed_button) {
    304                         window_grab_flags_t flags = GF_EMPTY;
    305                         flags |= GF_MOVE_Y;
    306                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    307                         win_grab(widget->window->osess, event.pos_id, flags);
    308                 } else if (left && allowed_button) {
    309                         window_grab_flags_t flags = GF_EMPTY;
    310                         flags |= GF_MOVE_X;
    311                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    312                         win_grab(widget->window->osess, event.pos_id, flags);
    313                 } else if (bottom && allowed_button) {
    314                         window_grab_flags_t flags = GF_EMPTY;
    315                         flags |= btn_left ? GF_RESIZE_Y : GF_SCALE_Y;
    316                         win_grab(widget->window->osess, event.pos_id, flags);
    317                 } else if (right && allowed_button) {
    318                         window_grab_flags_t flags = GF_EMPTY;
    319                         flags |= btn_left ? GF_RESIZE_X : GF_SCALE_X;
    320                         win_grab(widget->window->osess, event.pos_id, flags);
     312                bool isresize = widget->window->is_resizable;
     313                display_wnd_rsztype_t rsztype = 0;
     314
     315                if (edge && ctop && cleft) {
     316                        rsztype = display_wr_top_left;
     317                } else if (edge && cbottom && cleft) {
     318                        rsztype = display_wr_bottom_left;
     319                } else if (edge && cbottom && cright) {
     320                        rsztype = display_wr_bottom_right;
     321                } else if (edge && ctop && cright) {
     322                        rsztype = display_wr_top_right;
     323                } else if (top) {
     324                        rsztype = display_wr_top;
     325                } else if (left) {
     326                        rsztype = display_wr_left;
     327                } else if (bottom) {
     328                        rsztype = display_wr_bottom;
     329                } else if (right) {
     330                        rsztype = display_wr_right;
     331                } else {
     332                        isresize = false;
     333                }
     334
     335                if (isresize) {
     336                        (void) set_cursor(widget->window,
     337                            display_cursor_from_wrsz(rsztype));
     338                } else {
     339                        (void) set_cursor(widget->window, dcurs_arrow);
     340                }
     341
     342                pos.x = event.hpos;
     343                pos.y = event.vpos;
     344
     345                if (isresize && btn_left) {
     346                        (void) display_window_resize_req(
     347                            widget->window->dwindow, rsztype, &pos);
    321348                } else if (close && btn_left) {
    322                         win_close_request(widget->window->osess);
     349                        window_close(widget->window);
    323350                } else if (header && btn_left) {
    324                         window_grab_flags_t flags = GF_EMPTY;
    325                         flags |= GF_MOVE_X;
    326                         flags |= GF_MOVE_Y;
    327                         win_grab(widget->window->osess, event.pos_id, flags);
     351                        (void) display_window_move_req(widget->window->dwindow,
     352                            &pos);
    328353                } else {
    329354                        list_foreach(widget->children, link, widget_t, child) {
     
    370395    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
    371396{
    372         if (width < 2 * border_thickness + header_min_width) {
    373                 win_damage(win->osess, 0, 0, 0, 0);
    374                 return;
    375         }
    376 
    377         if (height < 2 * border_thickness + header_height) {
    378                 win_damage(win->osess, 0, 0, 0, 0);
    379                 return;
    380         }
    381 
    382         /* Allocate resources for new surface. */
    383         surface_t *new_surface = surface_create(width, height, NULL,
     397        gfx_bitmap_params_t params;
     398        gfx_bitmap_alloc_t alloc;
     399        gfx_bitmap_t *new_bitmap = NULL;
     400        gfx_coord2_t offs;
     401        gfx_coord2_t dpos;
     402        display_info_t dinfo;
     403        gfx_rect_t drect;
     404        gfx_rect_t nrect;
     405        errno_t rc;
     406
     407        if (width < 2 * border_thickness + header_min_width)
     408                return;
     409
     410        if (height < 2 * border_thickness + header_height)
     411                return;
     412
     413        fibril_mutex_lock(&win->guard);
     414
     415        /* Deallocate old bitmap. */
     416        if (win->bitmap != NULL) {
     417                gfx_bitmap_destroy(win->bitmap);
     418                win->bitmap = NULL;
     419        }
     420
     421        /* Deallocate old surface. */
     422        if (win->surface != NULL) {
     423                surface_destroy(win->surface);
     424                win->surface = NULL;
     425        }
     426
     427        /* Place window, if appropriate */
     428        if (placement_flags != WINDOW_PLACEMENT_ANY) {
     429                dpos.x = 0;
     430                dpos.y = 0;
     431
     432                rc = display_get_info(win->display, &dinfo);
     433                if (rc != EOK) {
     434                        fibril_mutex_unlock(&win->guard);
     435                        return;
     436                }
     437
     438                drect = dinfo.rect;
     439
     440                if (placement_flags & WINDOW_PLACEMENT_LEFT)
     441                        dpos.x = drect.p0.x;
     442                else if (placement_flags & WINDOW_PLACEMENT_CENTER_X)
     443                        dpos.x = (drect.p0.x + drect.p1.x - width) / 2;
     444                else
     445                        dpos.x = drect.p1.x - width;
     446
     447                if (placement_flags & WINDOW_PLACEMENT_TOP)
     448                        dpos.y = drect.p0.y;
     449                else if (placement_flags & WINDOW_PLACEMENT_CENTER_Y)
     450                        dpos.y = (drect.p0.y + drect.p1.y - height) / 2;
     451                else
     452                        dpos.y = drect.p1.y - height;
     453
     454                (void) display_window_move(win->dwindow, &dpos);
     455        }
     456
     457        /* Resize the display window. */
     458        offs.x = offset_x;
     459        offs.y = offset_y;
     460        nrect.p0.x = 0;
     461        nrect.p0.y = 0;
     462        nrect.p1.x = width;
     463        nrect.p1.y = height;
     464
     465        rc = display_window_resize(win->dwindow, &offs, &nrect);
     466        if (rc != EOK) {
     467                fibril_mutex_unlock(&win->guard);
     468                return;
     469        }
     470
     471        gfx_bitmap_params_init(&params);
     472#ifndef CONFIG_WIN_DOUBLE_BUF
     473        params.flags = bmpf_direct_output;
     474#else
     475        params.flags = 0;
     476#endif
     477        params.rect.p0.x = 0;
     478        params.rect.p0.y = 0;
     479        params.rect.p1.x = width;
     480        params.rect.p1.y = height;
     481
     482        rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
     483        if (rc != EOK) {
     484                if (rc == ENOTSUP) {
     485                        /* Direct output is not supported */
     486                        params.flags &= ~bmpf_direct_output;
     487                        rc = gfx_bitmap_create(win->gc, &params, NULL, &new_bitmap);
     488                        if (rc != EOK) {
     489                                fibril_mutex_unlock(&win->guard);
     490                                return;
     491                        }
     492                }
     493        }
     494
     495        rc = gfx_bitmap_get_alloc(new_bitmap, &alloc);
     496        if (rc != EOK) {
     497                fibril_mutex_unlock(&win->guard);
     498                return;
     499        }
     500
     501        /* Allocate new surface. */
     502        surface_t *new_surface = surface_create(width, height, alloc.pixels,
    384503            SURFACE_FLAG_SHARED);
    385         if (!new_surface)
    386                 return;
    387 
    388         /* Switch new and old surface. */
    389         fibril_mutex_lock(&win->guard);
    390         surface_t *old_surface = win->surface;
     504        if (!new_surface) {
     505                gfx_bitmap_destroy(new_bitmap);
     506                fibril_mutex_unlock(&win->guard);
     507                return;
     508        }
     509
     510        /* Switch in new surface and bitmap. */
    391511        win->surface = new_surface;
     512        win->bitmap = new_bitmap;
    392513        fibril_mutex_unlock(&win->guard);
    393514
     
    402523        fibril_mutex_unlock(&win->guard);
    403524
    404         /* Inform compositor about new surface. */
    405         errno_t rc = win_resize(win->osess, offset_x, offset_y, width, height,
    406             placement_flags, surface_direct_access(new_surface));
    407 
    408         if (rc != EOK) {
    409                 /* Rollback to old surface. Reverse all changes. */
    410 
    411                 sysarg_t old_width = 0;
    412                 sysarg_t old_height = 0;
    413                 if (old_surface)
    414                         surface_get_resolution(old_surface, &old_width, &old_height);
    415 
    416                 fibril_mutex_lock(&win->guard);
    417                 new_surface = win->surface;
    418                 win->surface = old_surface;
    419                 fibril_mutex_unlock(&win->guard);
    420 
    421                 win->root.rearrange(&win->root, 0, 0, old_width, old_height);
    422 
    423                 if (win->surface) {
    424                         fibril_mutex_lock(&win->guard);
    425                         surface_reset_damaged_region(win->surface);
    426                         fibril_mutex_unlock(&win->guard);
    427                 }
    428 
    429                 surface_destroy(new_surface);
    430         } else {
    431                 /* Deallocate old surface. */
    432                 if (old_surface)
    433                         surface_destroy(old_surface);
    434         }
     525        (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
    435526}
    436527
     
    443534{
    444535        sysarg_t x, y, width, height;
     536        gfx_rect_t rect;
    445537        fibril_mutex_lock(&win->guard);
    446538        surface_get_damaged_region(win->surface, &x, &y, &width, &height);
     
    449541
    450542        if (width > 0 && height > 0) {
    451                 /* Notify compositor. */
    452                 win_damage(win->osess, x, y, width, height);
     543                rect.p0.x = x;
     544                rect.p0.y = y;
     545                rect.p1.x = x + width;
     546                rect.p1.y = y + height;
     547
     548                if (win->bitmap != NULL)
     549                        (void) gfx_bitmap_render(win->bitmap, &rect, NULL);
    453550        }
    454551}
     
    472569        win->focus = NULL;
    473570
    474         win_close(win->osess);
    475         async_hangup(win->isess);
    476         async_hangup(win->osess);
     571        gfx_bitmap_destroy(win->bitmap);
     572
     573        /*
     574         * XXX Here we should properly destroy the IPC GC. We only have
     575         * the generic GC so either it would need to be cast back or
     576         * GC needs a virtual destructor.
     577         */
     578
     579        display_window_destroy(win->dwindow);
     580        display_close(win->display);
    477581
    478582        while (!list_empty(&win->events.list)) {
     
    506610                        break;
    507611                case ET_POSITION_EVENT:
    508                         if (!win->is_focused) {
    509                                 win->is_focused = true;
    510                                 handle_refresh(win);
    511                         }
    512612                        deliver_position_event(win, event->data.pos);
    513613                        break;
     
    559659}
    560660
    561 /* Input fetcher from compositor. Runs in own dedicated fibril. */
    562 static errno_t fetch_input(void *arg)
    563 {
    564         errno_t rc;
    565         bool terminate = false;
    566         window_t *win = (window_t *) arg;
    567 
    568         while (true) {
    569                 window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
    570 
    571                 if (event) {
    572                         rc = win_get_event(win->isess, event);
    573                         if (rc == EOK) {
    574                                 terminate = (event->type == ET_WINDOW_CLOSE);
    575                                 link_initialize(&event->link);
    576                                 prodcons_produce(&win->events, &event->link);
    577                         } else {
    578                                 free(event);
    579                                 terminate = true;
    580                         }
    581                 } else {
    582                         terminate = true;
    583                 }
    584 
    585                 if (terminate) {
    586                         break;
    587                 }
    588         }
    589 
    590         return 0;
    591 }
    592 
    593661window_t *window_open(const char *winreg, const void *data,
    594662    window_flags_t flags, const char *caption)
    595663{
    596         window_t *win = (window_t *) malloc(sizeof(window_t));
     664        display_wnd_params_t wparams;
     665
     666        window_t *win = (window_t *) calloc(1, sizeof(window_t));
    597667        if (!win)
    598668                return NULL;
     
    600670        win->is_main = flags & WINDOW_MAIN;
    601671        win->is_decorated = flags & WINDOW_DECORATED;
     672        win->is_resizable = flags & WINDOW_RESIZEABLE;
    602673        win->is_focused = true;
    603674        prodcons_initialize(&win->events);
     
    614685        win->grab = NULL;
    615686        win->focus = NULL;
    616         win->surface = NULL;
    617 
    618         service_id_t reg_dsid;
    619         errno_t rc = loc_service_get_id(winreg, &reg_dsid, 0);
    620         if (rc != EOK) {
     687        win->cursor = dcurs_arrow;
     688
     689        /* Allocate resources for new surface. */
     690        win->surface = surface_create(window_initial_size,
     691            window_initial_size, NULL, SURFACE_FLAG_SHARED);
     692        if (win->surface == NULL) {
    621693                free(win);
    622694                return NULL;
    623695        }
    624696
    625         async_sess_t *reg_sess =
    626             loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0);
    627         if (reg_sess == NULL) {
     697        errno_t rc = display_open(winreg, &win->display);
     698        if (rc != EOK) {
     699                surface_destroy(win->surface);
    628700                free(win);
    629701                return NULL;
    630702        }
    631703
    632         service_id_t in_dsid;
    633         service_id_t out_dsid;
    634         rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
    635         async_hangup(reg_sess);
     704        /* Window dimensions are not know at this time */
     705        display_wnd_params_init(&wparams);
     706        wparams.rect.p0.x = 0;
     707        wparams.rect.p0.y = 0;
     708        wparams.rect.p1.x = window_initial_size;
     709        wparams.rect.p1.y = window_initial_size;
     710        wparams.min_size.x = 2 * border_thickness + header_min_width;
     711        wparams.min_size.y = 2 * border_thickness + header_height;
     712
     713        rc = display_window_create(win->display, &wparams, &window_cb,
     714            (void *) win, &win->dwindow);
    636715        if (rc != EOK) {
     716                display_close(win->display);
     717                surface_destroy(win->surface);
    637718                free(win);
    638719                return NULL;
    639720        }
    640721
    641         win->osess = loc_service_connect(out_dsid, INTERFACE_COMPOSITOR, 0);
    642         if (win->osess == NULL) {
    643                 free(win);
    644                 return NULL;
    645         }
    646 
    647         win->isess = loc_service_connect(in_dsid, INTERFACE_COMPOSITOR, 0);
    648         if (win->isess == NULL) {
    649                 async_hangup(win->osess);
     722        rc = display_window_get_gc(win->dwindow, &win->gc);
     723        if (rc != EOK) {
     724                display_window_destroy(win->dwindow);
     725                display_close(win->display);
     726                surface_destroy(win->surface);
    650727                free(win);
    651728                return NULL;
     
    724801{
    725802        fid_t ev_fid = fibril_create(event_loop, win);
    726         fid_t fi_fid = fibril_create(fetch_input, win);
    727         if (!ev_fid || !fi_fid) {
     803        if (!ev_fid) {
    728804                return;
    729805        }
    730806        fibril_add_ready(ev_fid);
    731         fibril_add_ready(fi_fid);
    732807}
    733808
     
    745820void window_close(window_t *win)
    746821{
    747         /* Request compositor to init closing cascade. */
    748         win_close_request(win->osess);
     822        window_event_t *event;
     823
     824        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     825        if (event == NULL)
     826                return;
     827
     828        link_initialize(&event->link);
     829        event->type = ET_WINDOW_CLOSE;
     830        prodcons_produce(&win->events, &event->link);
     831}
     832
     833static void window_close_event(void *arg)
     834{
     835        window_t *win = (window_t *) arg;
     836
     837        window_close(win);
     838}
     839
     840static void window_focus_event(void *arg)
     841{
     842        window_t *win = (window_t *) arg;
     843        window_event_t *event;
     844
     845        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     846        if (event == NULL)
     847                return;
     848
     849        link_initialize(&event->link);
     850        event->type = ET_WINDOW_FOCUS;
     851        prodcons_produce(&win->events, &event->link);
     852}
     853
     854static void window_kbd_event(void *arg, kbd_event_t *kevent)
     855{
     856        window_t *win = (window_t *) arg;
     857        window_event_t *event;
     858
     859        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     860        if (event == NULL)
     861                return;
     862
     863        link_initialize(&event->link);
     864        event->type = ET_KEYBOARD_EVENT;
     865        event->data.kbd = *kevent;
     866        prodcons_produce(&win->events, &event->link);
     867}
     868
     869static void window_pos_event(void *arg, pos_event_t *pevent)
     870{
     871        window_t *win = (window_t *) arg;
     872        window_event_t *event;
     873
     874        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     875        if (event == NULL)
     876                return;
     877
     878        link_initialize(&event->link);
     879        event->type = ET_POSITION_EVENT;
     880        event->data.pos = *pevent;
     881        prodcons_produce(&win->events, &event->link);
     882}
     883
     884static void window_resize_event(void *arg, gfx_rect_t *nrect)
     885{
     886        window_t *win = (window_t *) arg;
     887        window_event_t *event;
     888
     889        if (!win->is_resizable)
     890                return;
     891
     892        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     893        if (event == NULL)
     894                return;
     895
     896        link_initialize(&event->link);
     897        event->type = ET_WINDOW_RESIZE;
     898        event->data.resize.offset_x = nrect->p0.x;
     899        event->data.resize.offset_y = nrect->p0.y;
     900        event->data.resize.width = nrect->p1.x - nrect->p0.x;
     901        event->data.resize.height = nrect->p1.y - nrect->p0.y;
     902        event->data.resize.placement_flags = WINDOW_PLACEMENT_ANY;
     903        prodcons_produce(&win->events, &event->link);
     904}
     905
     906static void window_unfocus_event(void *arg)
     907{
     908        window_t *win = (window_t *) arg;
     909        window_event_t *event;
     910
     911        event = (window_event_t *) calloc(1, sizeof(window_event_t));
     912        if (event == NULL)
     913                return;
     914
     915        link_initialize(&event->link);
     916        event->type = ET_WINDOW_UNFOCUS;
     917        prodcons_produce(&win->events, &event->link);
    749918}
    750919
  • uspace/lib/gui/window.h

    redb57bc6 re79a025  
    3737#define GUI_WINDOW_H_
    3838
    39 #include <async.h>
    4039#include <adt/prodcons.h>
    4140#include <fibril_synch.h>
     
    4342#include <io/window.h>
    4443#include <draw/surface.h>
     44#include <display.h>
     45#include <gfx/bitmap.h>
     46#include <gfx/context.h>
    4547
    4648#include "widget.h"
     
    5052        bool is_decorated; /**< True if the window decorations should be rendered. */
    5153        bool is_focused; /**< True for the top level window of the desktop. */
     54        bool is_resizable; /**< True if window is resizable */
    5255        char *caption; /**< Text title of the window header. */
    53         async_sess_t *isess; /**< Input events from compositor. */
    54         async_sess_t *osess; /**< Mainly for damage reporting to compositor. */
     56        display_t *display; /**< Display service */
     57        display_window_t *dwindow; /**< Display window */
     58        gfx_context_t *gc; /**< GC of the window */
    5559        prodcons_t events; /**< Queue for window event loop. */
    5660        widget_t root; /**< Decoration widget serving as a root of widget hiearchy. */
     
    5862        widget_t *focus; /**< Widget owning the keyboard or NULL. */
    5963        fibril_mutex_t guard; /**< Mutex guarding window surface. */
    60         surface_t *surface; /**< Window surface shared with compositor. */
     64        surface_t *surface; /**< Window surface shared with display server. */
     65        gfx_bitmap_t *bitmap; /**< Window bitmap */
     66        display_stock_cursor_t cursor; /**< Selected cursor */
    6167};
    6268
    6369/**
    64  * Allocate all resources for new window and register it in the compositor.
     70 * Allocate all resources for new window and register it in the display server.
    6571 * If the window is declared as main, its closure causes termination of the
    6672 * whole application. Note that opened window does not have any surface yet.
     
    7177/**
    7278 * Post resize event into event loop. Window negotiates new surface with
    73  * compositor and asks all widgets in the tree to calculate their new properties
    74  * and to paint themselves on the new surface (top-bottom order). Should be
    75  * called also after opening new window to obtain surface.
     79 * display server and asks all widgets in the tree to calculate their new
     80 * properties and to paint themselves on the new surface (top-bottom order).
     81 * Should be called also after opening new window to obtain surface.
    7682 */
    7783extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     
    9096
    9197/**
    92  * Post damage event into event loop. Handler informs compositor to update the
    93  * window surface on the screen. Should be called by widget after painting
     98 * Post damage event into event loop. Handler informs display server to update
     99 * the window surface on the screen. Should be called by widget after painting
    94100 * itself or copying its buffer onto window surface.
    95101 */
     
    120126
    121127/**
    122  * Initiate the closing cascade for the window. First, compositor deallocates
     128 * Initiate the closing cascade for the window. First, display sever deallocates
    123129 * output resources, prepares special closing input event for the window and
    124130 * deallocates input resources after the event is dispatched. When window
  • uspace/lib/guigfx/meson.build

    redb57bc6 re79a025  
    11#
    2 # Copyright (c) 2012 Petr Koupy
     2# Copyright (c) 2019 Jiri Svoboda
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 deps = [ 'draw', 'softrend', 'drv', 'compress', 'math' ]
    30 src = files('compositor.c')
     29deps = [ 'gui', 'gfx', 'memgfx' ]
     30src = files(
     31        'src/canvas.c'
     32)
  • uspace/lib/meson.build

    redb57bc6 re79a025  
    3333        'c',
    3434        'math',
     35        'display',
    3536        'gui',
    3637        'draw',
     
    3940        'clui',
    4041        'pcm',
    41         'hound'
     42        'hound',
     43        'gfx',
     44        'ipcgfx',
     45        'display',
    4246]
    4347
     
    5559        'fmtutil',
    5660        'fs',
    57         'graph',
     61        'gfx',
    5862        'http',
    5963        'label',
     
    7276
    7377        'bithenge',
     78        'congfx',
    7479        'draw',
    7580        'drv',
    7681        'ext4',
    77         'gui',
    7882        'hound',
     83        'ipcgfx',
     84        'memgfx',
    7985        'nic',
    8086        'usb',
     
    8692
    8793        'ieee80211',
     94        'ddev',
     95        'display',
     96
     97        'gui',
     98
     99        'guigfx',
    88100]
    89101
  • uspace/srv/hid/input/input.c

    redb57bc6 re79a025  
    236236        }
    237237
     238        if (type == KEY_PRESS) {
     239                switch (key) {
     240                case KC_F12:
     241                        console_kcon();
     242                        break;
     243                }
     244        }
     245
    238246        ev.type = type;
    239247        ev.key = key;
  • uspace/srv/hid/rfb/main.c

    redb57bc6 re79a025  
    2727 */
    2828
    29 #include <stdlib.h>
     29#include <ddev/info.h>
     30#include <ddev_srv.h>
    3031#include <errno.h>
     32#include <fibril_synch.h>
     33#include <gfx/color.h>
     34#include <gfx/context.h>
     35#include <gfx/coord.h>
     36#include <inttypes.h>
     37#include <io/log.h>
     38#include <io/pixelmap.h>
     39#include <ipcgfx/server.h>
    3140#include <loc.h>
    3241#include <stdio.h>
    33 #include <fibril_synch.h>
    34 #include <abi/ipc/methods.h>
    35 #include <inttypes.h>
    36 #include <io/log.h>
    37 #include <str.h>
     42#include <stdlib.h>
    3843#include <task.h>
    3944
    40 #include <abi/fb/visuals.h>
    41 #include <adt/list.h>
    42 #include <io/mode.h>
    43 #include <io/pixelmap.h>
    44 #include <io/chargrid.h>
    45 #include <graph.h>
    46 
    4745#include "rfb.h"
    4846
    4947#define NAME "rfb"
    5048
    51 static vslmode_list_element_t pixel_mode;
    52 static visualizer_t *vis;
    53 static rfb_t rfb;
    54 
    55 static errno_t rfb_claim(visualizer_t *vs)
    56 {
    57         return EOK;
    58 }
    59 
    60 static errno_t rfb_yield(visualizer_t *vs)
    61 {
    62         return EOK;
    63 }
    64 
    65 static errno_t rfb_suspend(visualizer_t *vs)
    66 {
    67         return EOK;
    68 }
    69 
    70 static errno_t rfb_wakeup(visualizer_t *vs)
    71 {
    72         return EOK;
    73 }
    74 
    75 static errno_t rfb_handle_damage_pixels(visualizer_t *vs,
    76     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    77     sysarg_t x_offset, sysarg_t y_offset)
    78 {
    79         fibril_mutex_lock(&rfb.lock);
    80 
    81         if (x0 + width > rfb.width || y0 + height > rfb.height) {
    82                 fibril_mutex_unlock(&rfb.lock);
    83                 return EINVAL;
    84         }
    85 
    86         /* TODO update surface_t and use it */
    87         if (!rfb.damage_valid) {
    88                 rfb.damage_rect.x = x0;
    89                 rfb.damage_rect.y = y0;
    90                 rfb.damage_rect.width = width;
    91                 rfb.damage_rect.height = height;
    92                 rfb.damage_valid = true;
     49static errno_t rfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     50static errno_t rfb_ddev_get_info(void *, ddev_info_t *);
     51
     52static errno_t rfb_gc_set_color(void *, gfx_color_t *);
     53static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
     54static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     55    gfx_bitmap_alloc_t *, void **);
     56static errno_t rfb_gc_bitmap_destroy(void *);
     57static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     58static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     59
     60static ddev_ops_t rfb_ddev_ops = {
     61        .get_gc = rfb_ddev_get_gc,
     62        .get_info = rfb_ddev_get_info
     63};
     64
     65typedef struct {
     66        rfb_t rfb;
     67        pixel_t color;
     68} rfb_gc_t;
     69
     70typedef struct {
     71        rfb_gc_t *rfb;
     72        gfx_bitmap_alloc_t alloc;
     73        gfx_rect_t rect;
     74        gfx_bitmap_flags_t flags;
     75        pixel_t key_color;
     76        bool myalloc;
     77} rfb_bitmap_t;
     78
     79static gfx_context_ops_t rfb_gc_ops = {
     80        .set_color = rfb_gc_set_color,
     81        .fill_rect = rfb_gc_fill_rect,
     82        .bitmap_create = rfb_gc_bitmap_create,
     83        .bitmap_destroy = rfb_gc_bitmap_destroy,
     84        .bitmap_render = rfb_gc_bitmap_render,
     85        .bitmap_get_alloc = rfb_gc_bitmap_get_alloc
     86};
     87
     88static void rfb_gc_invalidate_rect(rfb_gc_t *rfbgc, gfx_rect_t *rect)
     89{
     90        rfb_t *rfb = &rfbgc->rfb;
     91        gfx_rect_t old_rect;
     92        gfx_rect_t new_rect;
     93
     94        if (gfx_rect_is_empty(rect))
     95                return;
     96
     97        if (!rfb->damage_valid) {
     98                old_rect.p0.x = old_rect.p0.y = 0;
     99                old_rect.p1.x = old_rect.p1.y = 0;
    93100        } else {
    94                 if (x0 < rfb.damage_rect.x) {
    95                         rfb.damage_rect.width += rfb.damage_rect.x - x0;
    96                         rfb.damage_rect.x = x0;
    97                 }
    98                 if (y0 < rfb.damage_rect.y) {
    99                         rfb.damage_rect.height += rfb.damage_rect.y - y0;
    100                         rfb.damage_rect.y = y0;
    101                 }
    102                 sysarg_t x1 = x0 + width;
    103                 sysarg_t dx1 = rfb.damage_rect.x + rfb.damage_rect.width;
    104                 if (x1 > dx1) {
    105                         rfb.damage_rect.width += x1 - dx1;
    106                 }
    107                 sysarg_t y1 = y0 + height;
    108                 sysarg_t dy1 = rfb.damage_rect.y + rfb.damage_rect.height;
    109                 if (y1 > dy1) {
    110                         rfb.damage_rect.height += y1 - dy1;
    111                 }
    112         }
    113 
    114         pixelmap_t *map = &vs->cells;
    115 
    116         for (sysarg_t y = y0; y < height + y0; ++y) {
    117                 for (sysarg_t x = x0; x < width + x0; ++x) {
    118                         pixel_t pix = pixelmap_get_pixel(map, (x + x_offset) % map->width,
    119                             (y + y_offset) % map->height);
    120                         pixelmap_put_pixel(&rfb.framebuffer, x, y, pix);
    121                 }
    122         }
    123 
    124         fibril_mutex_unlock(&rfb.lock);
    125         return EOK;
    126 }
    127 
    128 static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
    129 {
    130         return EOK;
    131 }
    132 
    133 static visualizer_ops_t rfb_ops = {
    134         .claim = rfb_claim,
    135         .yield = rfb_yield,
    136         .change_mode = rfb_change_mode,
    137         .handle_damage = rfb_handle_damage_pixels,
    138         .suspend = rfb_suspend,
    139         .wakeup = rfb_wakeup
    140 };
     101                old_rect.p0.x = rfb->damage_rect.x;
     102                old_rect.p0.y = rfb->damage_rect.y;
     103                old_rect.p1.x = rfb->damage_rect.x + rfb->damage_rect.width;
     104                old_rect.p1.y = rfb->damage_rect.y + rfb->damage_rect.height;
     105        }
     106
     107        gfx_rect_envelope(&old_rect, rect, &new_rect);
     108
     109        rfb->damage_rect.x = new_rect.p0.x;
     110        rfb->damage_rect.y = new_rect.p0.y;
     111        rfb->damage_rect.width = new_rect.p1.x - new_rect.p0.x;
     112        rfb->damage_rect.height = new_rect.p1.y - new_rect.p0.y;
     113}
     114
     115static errno_t rfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     116{
     117        *arg2 = 0;
     118        *arg3 = 42;
     119        return EOK;
     120}
     121
     122static errno_t rfb_ddev_get_info(void *arg, ddev_info_t *info)
     123{
     124        rfb_t *rfb = (rfb_t *) arg;
     125
     126        ddev_info_init(info);
     127
     128        info->rect.p0.x = 0;
     129        info->rect.p0.y = 0;
     130        info->rect.p1.x = rfb->width;
     131        info->rect.p1.y = rfb->height;
     132
     133        return EOK;
     134}
     135
     136/** Set color on RFB.
     137 *
     138 * Set drawing color on RFB GC.
     139 *
     140 * @param arg RFB
     141 * @param color Color
     142 *
     143 * @return EOK on success or an error code
     144 */
     145static errno_t rfb_gc_set_color(void *arg, gfx_color_t *color)
     146{
     147        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     148        uint16_t r, g, b;
     149
     150        gfx_color_get_rgb_i16(color, &r, &g, &b);
     151        rfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     152        return EOK;
     153}
     154
     155/** Fill rectangle on RFB.
     156 *
     157 * @param arg RFB
     158 * @param rect Rectangle
     159 *
     160 * @return EOK on success or an error code
     161 */
     162static errno_t rfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
     163{
     164        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     165        gfx_coord_t x, y;
     166
     167        // XXX We should handle p0.x > p1.x and p0.y > p1.y
     168
     169        for (y = rect->p0.y; y < rect->p1.y; y++) {
     170                for (x = rect->p0.x; x < rect->p1.x; x++) {
     171                        pixelmap_put_pixel(&rfb->rfb.framebuffer, x, y,
     172                            rfb->color);
     173                }
     174        }
     175
     176        rfb_gc_invalidate_rect(rfb, rect);
     177
     178        return EOK;
     179}
     180
     181/** Create bitmap in RFB GC.
     182 *
     183 * @param arg RFB
     184 * @param params Bitmap params
     185 * @param alloc Bitmap allocation info or @c NULL
     186 * @param rbm Place to store pointer to new bitmap
     187 * @return EOK on success or an error code
     188 */
     189errno_t rfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     190    gfx_bitmap_alloc_t *alloc, void **rbm)
     191{
     192        rfb_gc_t *rfb = (rfb_gc_t *) arg;
     193        rfb_bitmap_t *rfbbm = NULL;
     194        gfx_coord2_t dim;
     195        errno_t rc;
     196
     197        /* Check that we support all required flags */
     198        if ((params->flags & ~bmpf_color_key) != 0)
     199                return ENOTSUP;
     200
     201        rfbbm = calloc(1, sizeof(rfb_bitmap_t));
     202        if (rfbbm == NULL)
     203                return ENOMEM;
     204
     205        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     206        rfbbm->rect = params->rect;
     207        rfbbm->flags = params->flags;
     208        rfbbm->key_color = params->key_color;
     209
     210        if (alloc == NULL) {
     211                rfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
     212                rfbbm->alloc.off0 = 0;
     213                rfbbm->alloc.pixels = malloc(rfbbm->alloc.pitch * dim.y);
     214                rfbbm->myalloc = true;
     215
     216                if (rfbbm->alloc.pixels == NULL) {
     217                        rc = ENOMEM;
     218                        goto error;
     219                }
     220        } else {
     221                rfbbm->alloc = *alloc;
     222        }
     223
     224        rfbbm->rfb = rfb;
     225        *rbm = (void *)rfbbm;
     226        return EOK;
     227error:
     228        if (rbm != NULL)
     229                free(rfbbm);
     230        return rc;
     231}
     232
     233/** Destroy bitmap in RFB GC.
     234 *
     235 * @param bm Bitmap
     236 * @return EOK on success or an error code
     237 */
     238static errno_t rfb_gc_bitmap_destroy(void *bm)
     239{
     240        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     241        if (rfbbm->myalloc)
     242                free(rfbbm->alloc.pixels);
     243        free(rfbbm);
     244        return EOK;
     245}
     246
     247/** Render bitmap in RFB GC.
     248 *
     249 * @param bm Bitmap
     250 * @param srect0 Source rectangle or @c NULL
     251 * @param offs0 Offset or @c NULL
     252 * @return EOK on success or an error code
     253 */
     254static errno_t rfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     255    gfx_coord2_t *offs0)
     256{
     257        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     258        gfx_rect_t srect;
     259        gfx_rect_t drect;
     260        gfx_coord2_t offs;
     261        gfx_coord2_t bmdim;
     262        gfx_coord2_t dim;
     263        gfx_coord_t x, y;
     264        pixelmap_t pbm;
     265        pixel_t color;
     266
     267        if (srect0 != NULL)
     268                srect = *srect0;
     269        else
     270                srect = rfbbm->rect;
     271
     272        if (offs0 != NULL) {
     273                offs = *offs0;
     274        } else {
     275                offs.x = 0;
     276                offs.y = 0;
     277        }
     278
     279        /* Destination rectangle */
     280        gfx_rect_translate(&offs, &srect, &drect);
     281        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     282        gfx_coord2_subtract(&rfbbm->rect.p1, &rfbbm->rect.p0, &bmdim);
     283
     284        pbm.width = bmdim.x;
     285        pbm.height = bmdim.y;
     286        pbm.data = rfbbm->alloc.pixels;
     287
     288        if ((rfbbm->flags & bmpf_color_key) == 0) {
     289                for (y = srect.p0.y; y < srect.p1.y; y++) {
     290                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     291                                color = pixelmap_get_pixel(&pbm, x, y);
     292                                pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     293                                    x + offs.x, y + offs.y, color);
     294                        }
     295                }
     296        } else {
     297                for (y = srect.p0.y; y < srect.p1.y; y++) {
     298                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     299                                color = pixelmap_get_pixel(&pbm, x, y);
     300                                if (color != rfbbm->key_color) {
     301                                        pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     302                                            x + offs.x, y + offs.y, color);
     303                                }
     304                        }
     305                }
     306        }
     307
     308        rfb_gc_invalidate_rect(rfbbm->rfb, &drect);
     309
     310        return EOK;
     311}
     312
     313/** Get allocation info for bitmap in RFB GC.
     314 *
     315 * @param bm Bitmap
     316 * @param alloc Place to store allocation info
     317 * @return EOK on success or an error code
     318 */
     319static errno_t rfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     320{
     321        rfb_bitmap_t *rfbbm = (rfb_bitmap_t *)bm;
     322        *alloc = rfbbm->alloc;
     323        return EOK;
     324}
    141325
    142326static void syntax_print(void)
     
    145329}
    146330
    147 static void client_connection(ipc_call_t *call, void *data)
    148 {
    149         graph_visualizer_connection(vis, call, data);
     331static void client_connection(ipc_call_t *icall, void *arg)
     332{
     333        rfb_t *rfb = (rfb_t *) arg;
     334        ddev_srv_t srv;
     335        sysarg_t svc_id;
     336        gfx_context_t *gc;
     337        errno_t rc;
     338
     339        svc_id = ipc_get_arg2(icall);
     340
     341        if (svc_id != 0) {
     342                /* Set up protocol structure */
     343                ddev_srv_initialize(&srv);
     344                srv.ops = &rfb_ddev_ops;
     345                srv.arg = (void *) rfb;
     346
     347                /* Handle connection */
     348                ddev_conn(icall, &srv);
     349        } else {
     350                rc = gfx_context_new(&rfb_gc_ops, (void *) rfb, &gc);
     351                if (rc != EOK) {
     352                        async_answer_0(icall, ENOMEM);
     353                        return;
     354                }
     355
     356                /* GC connection */
     357                gc_conn(icall, gc);
     358        }
    150359}
    151360
    152361int main(int argc, char **argv)
    153362{
     363        rfb_t rfb;
     364
    154365        log_init(NAME);
    155366
     
    188399        rfb_init(&rfb, width, height, rfb_name);
    189400
    190         vis = malloc(sizeof(visualizer_t));
    191         if (vis == NULL) {
    192                 fprintf(stderr, "Failed allocating visualizer struct\n");
    193                 return 3;
    194         }
    195 
    196         graph_init_visualizer(vis);
    197 
    198         pixel_mode.mode.index = 0;
    199         pixel_mode.mode.version = 0;
    200         pixel_mode.mode.refresh_rate = 0;
    201         pixel_mode.mode.screen_aspect.width = rfb.width;
    202         pixel_mode.mode.screen_aspect.height = rfb.height;
    203         pixel_mode.mode.screen_width = rfb.width;
    204         pixel_mode.mode.screen_height = rfb.height;
    205         pixel_mode.mode.cell_aspect.width = 1;
    206         pixel_mode.mode.cell_aspect.height = 1;
    207         pixel_mode.mode.cell_visual.pixel_visual = VISUAL_RGB_8_8_8;
    208 
    209         link_initialize(&pixel_mode.link);
    210         list_append(&pixel_mode.link, &vis->modes);
    211 
    212         vis->def_mode_idx = 0;
    213 
    214         vis->ops = rfb_ops;
    215         vis->dev_ctx = NULL;
    216 
    217         async_set_fallback_port_handler(client_connection, NULL);
     401        async_set_fallback_port_handler(client_connection, &rfb);
    218402
    219403        errno_t rc = loc_server_register(NAME);
     
    240424        free(service_name);
    241425
    242         category_id_t visualizer_category;
    243         rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
     426        category_id_t ddev_cid;
     427        rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
    244428        if (rc != EOK) {
    245                 fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
     429                fprintf(stderr, NAME ": Unable to get display device category id.\n");
    246430                return 1;
    247431        }
    248432
    249         rc = loc_service_add_to_cat(service_id, visualizer_category);
     433        rc = loc_service_add_to_cat(service_id, ddev_cid);
    250434        if (rc != EOK) {
    251                 fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
     435                fprintf(stderr, NAME ": Unable to add service to display device category.\n");
    252436                return 1;
    253437        }
  • uspace/srv/hid/rfb/meson.build

    redb57bc6 re79a025  
    2727#
    2828
    29 deps = [ 'graph' ]
     29deps = [ 'ipcgfx', 'ddev' ]
    3030src = files('main.c', 'rfb.c')
  • uspace/srv/locsrv/locsrv.c

    redb57bc6 re79a025  
    13781378        categ_dir_add_cat(&cdir, cat);
    13791379
    1380         cat = category_new("visualizer");
    1381         categ_dir_add_cat(&cdir, cat);
    1382 
    13831380        cat = category_new("renderer");
     1381        categ_dir_add_cat(&cdir, cat);
     1382
     1383        cat = category_new("display-device");
    13841384        categ_dir_add_cat(&cdir, cat);
    13851385
  • uspace/srv/meson.build

    redb57bc6 re79a025  
    4343        'fs/tmpfs',
    4444        'fs/udf',
    45         'hid/compositor',
    4645        'hid/console',
     46        'hid/display',
    4747        'hid/input',
    4848        'hid/isdv4_tablet',
Note: See TracChangeset for help on using the changeset viewer.