Changes in / [e79a025:edb57bc6] in mainline


Ignore:
Files:
12 added
138 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    re79a025 redb57bc6  
    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 
    616610% Start AP processors by the loader
    617611! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
  • abi/include/abi/ipc/interfaces.h

    re79a025 redb57bc6  
    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,
    114116        INTERFACE_HOUND =
    115117            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,
    116120        INTERFACE_LOC_SUPPLIER =
    117121            FOURCC_COMPACT('l', 'o', 'c', 's') | IFACE_EXCHANGE_SERIALIZE,
     
    183187            FOURCC_COMPACT('i', 'p', 'c', 't') | IFACE_EXCHANGE_SERIALIZE,
    184188        INTERFACE_PCI =
    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,
     189            FOURCC_COMPACT('p', 'c', 'i', ' ') | IFACE_EXCHANGE_SERIALIZE
    194190} iface_t;
    195191
  • meson/part/initrd_manifest/meson.build

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

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

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

    re79a025 redb57bc6  
    3434 */
    3535
    36 #include <fibril.h>
    3736#include <stdio.h>
    3837#include <stdarg.h>
     
    4847#include <config.h>
    4948#include <io/logctl.h>
    50 #include <vfs/vfs.h>
    5149#include <vol.h>
    5250#include "untar.h"
     
    6866#define APP_GETTERM  "/app/getterm"
    6967
    70 #define SRV_DISPLAY  "/srv/hid/display"
    71 #define DISPLAY_SVC  "hid/display"
     68#define SRV_COMPOSITOR  "/srv/hid/compositor"
    7269
    7370#define HID_INPUT              "hid/input"
    7471#define HID_OUTPUT             "hid/output"
     72#define HID_COMPOSITOR_SERVER  ":0"
    7573
    7674#define srv_start(path, ...) \
     
    273271}
    274272
    275 static errno_t display_server(void)
    276 {
    277         return srv_start(SRV_DISPLAY);
    278 }
    279 
    280 static int gui_start(const char *app, const char *display_svc)
    281 {
    282         printf("%s: Spawning %s\n", NAME, app);
     273static 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
     287static 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);
    283293
    284294        task_id_t id;
    285295        task_wait_t wait;
    286         errno_t rc = task_spawnl(&id, &wait, app, app, display_svc, NULL);
     296        errno_t rc = task_spawnl(&id, &wait, app, app, winreg, NULL);
    287297        if (rc != EOK) {
    288298                oom_check(rc, app);
    289                 printf("%s: Error spawning %s (%s)\n", NAME, app,
    290                     str_error(rc));
    291                 return -1;
     299                printf("%s: Error spawning %s %s (%s)\n", NAME, app,
     300                    winreg, str_error(rc));
     301                return rc;
    292302        }
    293303
     
    470480
    471481        if (!config_key_exists("console")) {
    472                 rc = display_server();
     482                rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
    473483                if (rc == EOK) {
    474                         gui_start("/app/barber", DISPLAY_SVC);
    475                         gui_start("/app/vlaunch", DISPLAY_SVC);
    476                         gui_start("/app/vterm", DISPLAY_SVC);
     484                        gui_start("/app/barber", HID_COMPOSITOR_SERVER);
     485                        gui_start("/app/vlaunch", HID_COMPOSITOR_SERVER);
     486                        gui_start("/app/vterm", HID_COMPOSITOR_SERVER);
    477487                }
    478488        }
  • uspace/app/meson.build

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

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

    re79a025 redb57bc6  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
    32 * Copyright (c) 2013 Jan Vesely
    43 * All rights reserved.
     
    3635
    3736#include <align.h>
    38 #include <as.h>
    3937#include <assert.h>
    4038#include <errno.h>
    41 #include <ddev_srv.h>
    42 #include <ddev/info.h>
    43 #include <ddf/driver.h>
    4439#include <ddf/log.h>
    4540#include <ddi.h>
    46 #include <gfx/color.h>
    47 #include <io/pixelmap.h>
     41#include <as.h>
    4842
    4943#include "amdm37x_dispc.h"
     
    6155#endif
    6256
    63 static errno_t amdm37x_change_mode(amdm37x_dispc_t *, unsigned, unsigned,
    64     visual_t);
    65 
    66 static errno_t amdm37x_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    67 static errno_t amdm37x_ddev_get_info(void *, ddev_info_t *);
    68 
    69 static errno_t amdm37x_gc_set_color(void *, gfx_color_t *);
    70 static errno_t amdm37x_gc_fill_rect(void *, gfx_rect_t *);
    71 static errno_t amdm37x_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    72     gfx_bitmap_alloc_t *, void **);
    73 static errno_t amdm37x_gc_bitmap_destroy(void *);
    74 static errno_t amdm37x_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    75 static errno_t amdm37x_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    76 
    77 ddev_ops_t amdm37x_ddev_ops = {
    78         .get_gc = amdm37x_ddev_get_gc,
    79         .get_info = amdm37x_ddev_get_info
    80 };
    81 
    82 gfx_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
     57static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
     58static 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);
     61static errno_t dummy(visualizer_t *vs)
     62{
     63        return EOK;
     64}
     65
     66static 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,
    8973};
    9074
     
    11094};
    11195
    112 errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, ddf_fun_t *fun)
    113 {
    114         instance->fun = fun;
     96static 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
     114errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
     115{
     116        assert(instance);
     117        assert(vis);
     118
    115119        instance->fb_data = NULL;
    116120        instance->size = 0;
     
    141145        }
    142146
    143         ret = amdm37x_change_mode(instance, CONFIG_BFB_WIDTH,
    144             CONFIG_BFB_HEIGHT, visual);
    145         if (ret != EOK)
    146                 return EIO;
     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);
    147155
    148156        return EOK;
     
    261269}
    262270
    263 static errno_t amdm37x_change_mode(amdm37x_dispc_t *dispc, unsigned x,
    264     unsigned y, visual_t visual)
    265 {
     271static 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;
    266278        assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
    267279        const unsigned bpp = pixel2visual_table[visual].bpp;
    268280        pixel2visual_t p2v = pixel2visual_table[visual].func;
     281        const unsigned x = mode.screen_width;
     282        const unsigned y = mode.screen_height;
    269283        ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp * 8);
    270284        const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
     
    282296        dispc->fb_data = buffer;
    283297        amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp * 8, (uint32_t)pa);
     298        dispc->active_fb.idx = mode.index;
    284299        dispc->active_fb.width = x;
    285300        dispc->active_fb.height = y;
     
    287302        dispc->active_fb.bpp = bpp;
    288303        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;
    293304        dispc->size = size;
    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 
    302 static 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 
    311 static 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  */
    332 static 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  */
    349 static 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  */
    376 errno_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;
     305        assert(mode.index < 1);
     306
     307        return EOK;
     308}
     309
     310static 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                        }
    404330                }
    405331        } else {
    406                 dcbm->alloc = *alloc;
    407         }
    408 
    409         dcbm->dispc = dispc;
    410         *rbm = (void *)dcbm;
    411         return EOK;
    412 error:
    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  */
    423 static 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  */
    439 static 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);
     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                        }
    498340                }
    499341        }
    500342
    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  */
    510 static 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;
    514343        return EOK;
    515344}
  • uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.h

    re79a025 redb57bc6  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
    32 * Copyright (c) 2013 Jan Vesely
    43 * All rights reserved.
     
    3837#define AMDM37X_DISPC_H_
    3938
     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>
    4641#include <pixconv.h>
    4742#include <ddi.h>
     
    5045
    5146typedef struct {
    52         ddf_fun_t *fun;
    5347        amdm37x_dispc_regs_t *regs;
    5448
     
    5953                unsigned pitch;
    6054                unsigned bpp;
     55                unsigned idx;
    6156        } active_fb;
    6257
    63         pixel_t color;
    64         gfx_rect_t rect;
    6558        size_t size;
    6659        void *fb_data;
     60
     61        vslmode_list_element_t modes[1];
    6762} amdm37x_dispc_t;
    6863
    69 typedef 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 
    76 extern ddev_ops_t amdm37x_ddev_ops;
    77 extern gfx_context_ops_t amdm37x_gc_ops;
    78 
    79 extern errno_t amdm37x_dispc_init(amdm37x_dispc_t *, ddf_fun_t *);
    80 extern errno_t amdm37x_dispc_fini(amdm37x_dispc_t *);
     64errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis);
     65errno_t amdm37x_dispc_fini(amdm37x_dispc_t *instance);
    8166
    8267#endif
  • uspace/drv/fb/amdm37x_dispc/main.c

    re79a025 redb57bc6  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
    32 * Copyright (c) 2013 Jan Vesely
    43 * Copyright (c) 2011 Petr Koupy
     
    3635 */
    3736
    38 #include <ddev_srv.h>
    3937#include <ddf/driver.h>
    4038#include <ddf/log.h>
    4139#include <errno.h>
    42 #include <ipcgfx/server.h>
    4340#include <str_error.h>
    4441#include <stdio.h>
     42#include <graph.h>
    4543
    4644#include "amdm37x_dispc.h"
     
    4846#define NAME  "amdm37x_dispc"
    4947
    50 static void amdm37x_client_conn(ipc_call_t *icall, void *arg)
     48static void graph_vsl_connection(ipc_call_t *icall, void *arg)
    5149{
    52         amdm37x_dispc_t *dispc;
    53         ddev_srv_t srv;
    54         sysarg_t gc_id;
    55         gfx_context_t *gc;
    56         errno_t rc;
     50        visualizer_t *vsl;
    5751
    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;
    83 error:
    84         async_answer_0(icall, rc);
     52        vsl = (visualizer_t *) ddf_fun_data_get((ddf_fun_t *)arg);
     53        graph_visualizer_connection(vsl, icall, NULL);
    8554}
    8655
     
    8857{
    8958        assert(dev);
    90 
    91         ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "a");
     59        /* Visualizer part */
     60        ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "viz");
    9261        if (!fun) {
    93                 ddf_log_error("Failed to create display device function.");
     62                ddf_log_error("Failed to create visualizer function.");
    9463                return ENOMEM;
    9564        }
    9665
    97         ddf_fun_set_conn_handler(fun, &amdm37x_client_conn);
     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        }
    9872
     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);
    9977        /* Hw part */
    10078        amdm37x_dispc_t *dispc =
     
    10684        }
    10785
    108         errno_t rc = amdm37x_dispc_init(dispc, fun);
     86        errno_t rc = amdm37x_dispc_init(dispc, vis);
    10987        if (rc != EOK) {
    11088                ddf_log_error("Failed to init dispc: %s.", str_error(rc));
     
    122100        }
    123101
    124         rc = ddf_fun_add_to_category(fun, "display-device");
     102        rc = ddf_fun_add_to_category(fun, "visualizer");
    125103        if (rc != EOK) {
    126                 ddf_log_error("Failed to add function: %s to display device "
     104                ddf_log_error("Failed to add function: %s to visualizer "
    127105                    "category.", str_error(rc));
    128106                amdm37x_dispc_fini(dispc);
  • uspace/drv/fb/amdm37x_dispc/meson.build

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

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

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

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

    re79a025 redb57bc6  
    11/*
    2  * Copyright (c) 2019 Jiri Svoboda
    32 * Copyright (c) 2006 Jakub Vana
    43 * Copyright (c) 2006 Ondrej Palkovsky
     
    3938
    4039#include <abi/fb/visuals.h>
     40#include <stddef.h>
     41#include <stdint.h>
     42#include <errno.h>
     43
     44#include <stdlib.h>
     45#include <mem.h>
     46#include <as.h>
     47#include <align.h>
     48
     49#include <sysinfo.h>
     50#include <ddi.h>
     51
    4152#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>
     53
    5254#include <io/mode.h>
    5355#include <io/pixelmap.h>
    54 #include <ipcgfx/server.h>
    55 #include <mem.h>
     56#include <io/chargrid.h>
     57
    5658#include <pixconv.h>
    57 #include <stddef.h>
    58 #include <stdint.h>
    59 #include <stdlib.h>
    60 #include <sysinfo.h>
     59
     60#include <graph.h>
    6161
    6262#include "kfb.h"
    6363#include "port.h"
    6464
    65 #define FB_POS(fb, x, y)  ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes)
     65#define FB_POS(x, y)  ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
    6666
    6767typedef struct {
    68         ddf_fun_t *fun;
    69 
    7068        sysarg_t paddr;
    71         gfx_rect_t rect;
     69        sysarg_t width;
     70        sysarg_t height;
    7271        size_t offset;
    7372        size_t scanline;
     
    8180        size_t size;
    8281        uint8_t *addr;
    83 
    84         /** Current drawing color */
    85         pixel_t color;
    8682} kfb_t;
    8783
    88 typedef 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 
    97 static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    98 static errno_t kfb_ddev_get_info(void *, ddev_info_t *);
    99 
    100 static errno_t kfb_gc_set_color(void *, gfx_color_t *);
    101 static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *);
    102 static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    103     gfx_bitmap_alloc_t *, void **);
    104 static errno_t kfb_gc_bitmap_destroy(void *);
    105 static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    106 static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    107 
    108 static ddev_ops_t kfb_ddev_ops = {
    109         .get_gc = kfb_ddev_get_gc,
    110         .get_info = kfb_ddev_get_info
    111 };
    112 
    113 static 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 
    122 static 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 
    131 static 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  */
    149 static 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  */
    166 static 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  */
    193 errno_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;
     84static kfb_t kfb;
     85
     86static vslmode_list_element_t pixel_mode;
     87
     88static 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
     95static errno_t kfb_yield(visualizer_t *vs)
     96{
    19997        errno_t rc;
    20098
    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;
    231 error:
    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  */
    242 static 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  */
    258 static 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                                 }
     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
     111static 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++);
    319123                        }
    320124                }
    321125        } else {
    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);
     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));
    330132                        }
    331133                }
     
    335137}
    336138
    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  */
    343 static 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>
    351 static 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;
     139static 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
     145static errno_t kfb_suspend(visualizer_t *vs)
     146{
     147        return EOK;
     148}
     149
     150static errno_t kfb_wakeup(visualizer_t *vs)
     151{
     152        return EOK;
     153}
     154
     155static 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
     164static void graph_vsl_connection(ipc_call_t *icall, void *arg)
     165{
     166        visualizer_t *vsl;
    357167        errno_t rc;
    358168
    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);
     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);
    399174                if (rc == EOK)
    400                         kfb->addr = AS_AREA_ANY;
    401         }
    402 
    403         return;
    404 error:
    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);
     175                        kfb.addr = NULL;
     176        }
    411177}
    412178
    413179errno_t port_init(ddf_dev_t *dev)
    414180{
    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 
    433181        sysarg_t present;
    434         rc = sysinfo_get_value("fb", &present);
     182        errno_t rc = sysinfo_get_value("fb", &present);
    435183        if (rc != EOK)
    436184                present = false;
    437185
    438         if (!present) {
    439                 ddf_fun_destroy(fun);
    440                 rc = ENOENT;
    441                 goto error;
    442         }
     186        if (!present)
     187                return ENOENT;
    443188
    444189        sysarg_t kind;
     
    447192                kind = (sysarg_t) -1;
    448193
    449         if (kind != 1) {
    450                 rc = EINVAL;
    451                 goto error;
    452         }
     194        if (kind != 1)
     195                return EINVAL;
    453196
    454197        sysarg_t paddr;
    455198        rc = sysinfo_get_value("fb.address.physical", &paddr);
    456199        if (rc != EOK)
    457                 goto error;
     200                return rc;
    458201
    459202        sysarg_t offset;
     
    465208        rc = sysinfo_get_value("fb.width", &width);
    466209        if (rc != EOK)
    467                 goto error;
     210                return rc;
    468211
    469212        sysarg_t height;
    470213        rc = sysinfo_get_value("fb.height", &height);
    471214        if (rc != EOK)
    472                 goto error;
     215                return rc;
    473216
    474217        sysarg_t scanline;
    475218        rc = sysinfo_get_value("fb.scanline", &scanline);
    476219        if (rc != EOK)
    477                 goto error;
     220                return rc;
    478221
    479222        sysarg_t visual;
    480223        rc = sysinfo_get_value("fb.visual", &visual);
    481224        if (rc != EOK)
    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;
     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;
    495233
    496234        switch (visual) {
    497235        case VISUAL_INDIRECT_8:
    498                 kfb->pixel2visual = pixel2bgr_323;
    499                 kfb->visual2pixel = bgr_323_2pixel;
    500                 kfb->visual_mask = visual_mask_323;
    501                 kfb->pixel_bytes = 1;
     236                kfb.pixel2visual = pixel2bgr_323;
     237                kfb.visual2pixel = bgr_323_2pixel;
     238                kfb.visual_mask = visual_mask_323;
     239                kfb.pixel_bytes = 1;
    502240                break;
    503241        case VISUAL_RGB_5_5_5_LE:
    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;
     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;
    508246                break;
    509247        case VISUAL_RGB_5_5_5_BE:
    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;
     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;
    514252                break;
    515253        case VISUAL_RGB_5_6_5_LE:
    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;
     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;
    520258                break;
    521259        case VISUAL_RGB_5_6_5_BE:
    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;
     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;
    526264                break;
    527265        case VISUAL_RGB_8_8_8:
    528                 kfb->pixel2visual = pixel2rgb_888;
    529                 kfb->visual2pixel = rgb_888_2pixel;
    530                 kfb->visual_mask = visual_mask_888;
    531                 kfb->pixel_bytes = 3;
     266                kfb.pixel2visual = pixel2rgb_888;
     267                kfb.visual2pixel = rgb_888_2pixel;
     268                kfb.visual_mask = visual_mask_888;
     269                kfb.pixel_bytes = 3;
    532270                break;
    533271        case VISUAL_BGR_8_8_8:
    534                 kfb->pixel2visual = pixel2bgr_888;
    535                 kfb->visual2pixel = bgr_888_2pixel;
    536                 kfb->visual_mask = visual_mask_888;
    537                 kfb->pixel_bytes = 3;
     272                kfb.pixel2visual = pixel2bgr_888;
     273                kfb.visual2pixel = bgr_888_2pixel;
     274                kfb.visual_mask = visual_mask_888;
     275                kfb.pixel_bytes = 3;
    538276                break;
    539277        case VISUAL_RGB_8_8_8_0:
    540                 kfb->pixel2visual = pixel2rgb_8880;
    541                 kfb->visual2pixel = rgb_8880_2pixel;
    542                 kfb->visual_mask = visual_mask_8880;
    543                 kfb->pixel_bytes = 4;
     278                kfb.pixel2visual = pixel2rgb_8880;
     279                kfb.visual2pixel = rgb_8880_2pixel;
     280                kfb.visual_mask = visual_mask_8880;
     281                kfb.pixel_bytes = 4;
    544282                break;
    545283        case VISUAL_RGB_0_8_8_8:
    546                 kfb->pixel2visual = pixel2rgb_0888;
    547                 kfb->visual2pixel = rgb_0888_2pixel;
    548                 kfb->visual_mask = visual_mask_0888;
    549                 kfb->pixel_bytes = 4;
     284                kfb.pixel2visual = pixel2rgb_0888;
     285                kfb.visual2pixel = rgb_0888_2pixel;
     286                kfb.visual_mask = visual_mask_0888;
     287                kfb.pixel_bytes = 4;
    550288                break;
    551289        case VISUAL_BGR_0_8_8_8:
    552                 kfb->pixel2visual = pixel2bgr_0888;
    553                 kfb->visual2pixel = bgr_0888_2pixel;
    554                 kfb->visual_mask = visual_mask_0888;
    555                 kfb->pixel_bytes = 4;
     290                kfb.pixel2visual = pixel2bgr_0888;
     291                kfb.visual2pixel = bgr_0888_2pixel;
     292                kfb.visual_mask = visual_mask_0888;
     293                kfb.pixel_bytes = 4;
    556294                break;
    557295        case VISUAL_BGR_8_8_8_0:
    558                 kfb->pixel2visual = pixel2bgr_8880;
    559                 kfb->visual2pixel = bgr_8880_2pixel;
    560                 kfb->visual_mask = visual_mask_8880;
    561                 kfb->pixel_bytes = 4;
     296                kfb.pixel2visual = pixel2bgr_8880;
     297                kfb.visual2pixel = bgr_8880_2pixel;
     298                kfb.visual_mask = visual_mask_8880;
     299                kfb.pixel_bytes = 4;
    562300                break;
    563301        default:
     
    565303        }
    566304
    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");
     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);
    575342        if (rc != EOK) {
    576                 ddf_fun_unbind(fun);
    577                 goto error;
    578         }
    579 
    580         return EOK;
    581 error:
    582         if (fun != NULL)
    583                 ddf_fun_destroy(fun);
    584         return rc;
     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;
    585360}
    586361
  • uspace/lib/c/include/io/kbd_event.h

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

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

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

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

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

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

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

    re79a025 redb57bc6  
    4848#include <adt/list.h>
    4949
     50#include <async.h>
    5051#include <loc.h>
    5152
     
    5556#include <draw/drawctx.h>
    5657#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;
    69 static sysarg_t corner_size = 24;
    70 static sysarg_t window_initial_size = 1;
    7169
    7270static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
     
    8482static pixel_t color_caption_focus = PIXEL(255, 255, 255, 255);
    8583static pixel_t color_caption_unfocus = PIXEL(255, 207, 207, 207);
    86 
    87 static void window_close_event(void *);
    88 static void window_focus_event(void *);
    89 static void window_kbd_event(void *, kbd_event_t *);
    90 static void window_pos_event(void *, pos_event_t *);
    91 static void window_resize_event(void *, gfx_rect_t *);
    92 static void window_unfocus_event(void *);
    93 
    94 static 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 
    103 static 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 }
    11084
    11185static void paint_internal(widget_t *widget)
     
    284258static void root_handle_position_event(widget_t *widget, pos_event_t event)
    285259{
    286         gfx_coord2_t pos;
    287 
    288260        if (widget->window->is_decorated) {
    289261                sysarg_t width = widget->width;
     
    291263
    292264                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;
    293267
    294268                bool left = (event.hpos < border_thickness);
     
    296270                bool top = (event.vpos < border_thickness);
    297271                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 
    305272                bool header = (event.hpos >= border_thickness) &&
    306273                    (event.hpos < width - border_thickness) &&
     
    310277                    (event.hpos >= width - border_thickness - close_thickness);
    311278
    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);
     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);
    348321                } else if (close && btn_left) {
    349                         window_close(widget->window);
     322                        win_close_request(widget->window->osess);
    350323                } else if (header && btn_left) {
    351                         (void) display_window_move_req(widget->window->dwindow,
    352                             &pos);
     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);
    353328                } else {
    354329                        list_foreach(widget->children, link, widget_t, child) {
     
    395370    sysarg_t width, sysarg_t height, window_placement_flags_t placement_flags)
    396371{
    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)
     372        if (width < 2 * border_thickness + header_min_width) {
     373                win_damage(win->osess, 0, 0, 0, 0);
    408374                return;
    409 
    410         if (height < 2 * border_thickness + header_height)
     375        }
     376
     377        if (height < 2 * border_thickness + header_height) {
     378                win_damage(win->osess, 0, 0, 0, 0);
    411379                return;
    412 
     380        }
     381
     382        /* Allocate resources for new surface. */
     383        surface_t *new_surface = surface_create(width, height, NULL,
     384            SURFACE_FLAG_SHARED);
     385        if (!new_surface)
     386                return;
     387
     388        /* Switch new and old surface. */
    413389        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,
    503             SURFACE_FLAG_SHARED);
    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. */
     390        surface_t *old_surface = win->surface;
    511391        win->surface = new_surface;
    512         win->bitmap = new_bitmap;
    513392        fibril_mutex_unlock(&win->guard);
    514393
     
    523402        fibril_mutex_unlock(&win->guard);
    524403
    525         (void) gfx_bitmap_render(win->bitmap, NULL, NULL);
     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        }
    526435}
    527436
     
    534443{
    535444        sysarg_t x, y, width, height;
    536         gfx_rect_t rect;
    537445        fibril_mutex_lock(&win->guard);
    538446        surface_get_damaged_region(win->surface, &x, &y, &width, &height);
     
    541449
    542450        if (width > 0 && height > 0) {
    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);
     451                /* Notify compositor. */
     452                win_damage(win->osess, x, y, width, height);
    550453        }
    551454}
     
    569472        win->focus = NULL;
    570473
    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);
     474        win_close(win->osess);
     475        async_hangup(win->isess);
     476        async_hangup(win->osess);
    581477
    582478        while (!list_empty(&win->events.list)) {
     
    610506                        break;
    611507                case ET_POSITION_EVENT:
     508                        if (!win->is_focused) {
     509                                win->is_focused = true;
     510                                handle_refresh(win);
     511                        }
    612512                        deliver_position_event(win, event->data.pos);
    613513                        break;
     
    659559}
    660560
     561/* Input fetcher from compositor. Runs in own dedicated fibril. */
     562static 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
    661593window_t *window_open(const char *winreg, const void *data,
    662594    window_flags_t flags, const char *caption)
    663595{
    664         display_wnd_params_t wparams;
    665 
    666         window_t *win = (window_t *) calloc(1, sizeof(window_t));
     596        window_t *win = (window_t *) malloc(sizeof(window_t));
    667597        if (!win)
    668598                return NULL;
     
    670600        win->is_main = flags & WINDOW_MAIN;
    671601        win->is_decorated = flags & WINDOW_DECORATED;
    672         win->is_resizable = flags & WINDOW_RESIZEABLE;
    673602        win->is_focused = true;
    674603        prodcons_initialize(&win->events);
     
    685614        win->grab = NULL;
    686615        win->focus = NULL;
    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) {
     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) {
    693621                free(win);
    694622                return NULL;
    695623        }
    696624
    697         errno_t rc = display_open(winreg, &win->display);
    698         if (rc != EOK) {
    699                 surface_destroy(win->surface);
     625        async_sess_t *reg_sess =
     626            loc_service_connect(reg_dsid, INTERFACE_COMPOSITOR, 0);
     627        if (reg_sess == NULL) {
    700628                free(win);
    701629                return NULL;
    702630        }
    703631
    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);
     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);
    715636        if (rc != EOK) {
    716                 display_close(win->display);
    717                 surface_destroy(win->surface);
    718637                free(win);
    719638                return NULL;
    720639        }
    721640
    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);
     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);
    727650                free(win);
    728651                return NULL;
     
    801724{
    802725        fid_t ev_fid = fibril_create(event_loop, win);
    803         if (!ev_fid) {
     726        fid_t fi_fid = fibril_create(fetch_input, win);
     727        if (!ev_fid || !fi_fid) {
    804728                return;
    805729        }
    806730        fibril_add_ready(ev_fid);
     731        fibril_add_ready(fi_fid);
    807732}
    808733
     
    820745void window_close(window_t *win)
    821746{
    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 
    833 static void window_close_event(void *arg)
    834 {
    835         window_t *win = (window_t *) arg;
    836 
    837         window_close(win);
    838 }
    839 
    840 static 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 
    854 static 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 
    869 static 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 
    884 static 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 
    906 static 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);
     747        /* Request compositor to init closing cascade. */
     748        win_close_request(win->osess);
    918749}
    919750
  • uspace/lib/gui/window.h

    re79a025 redb57bc6  
    3737#define GUI_WINDOW_H_
    3838
     39#include <async.h>
    3940#include <adt/prodcons.h>
    4041#include <fibril_synch.h>
     
    4243#include <io/window.h>
    4344#include <draw/surface.h>
    44 #include <display.h>
    45 #include <gfx/bitmap.h>
    46 #include <gfx/context.h>
    4745
    4846#include "widget.h"
     
    5250        bool is_decorated; /**< True if the window decorations should be rendered. */
    5351        bool is_focused; /**< True for the top level window of the desktop. */
    54         bool is_resizable; /**< True if window is resizable */
    5552        char *caption; /**< Text title of the window header. */
    56         display_t *display; /**< Display service */
    57         display_window_t *dwindow; /**< Display window */
    58         gfx_context_t *gc; /**< GC of the window */
     53        async_sess_t *isess; /**< Input events from compositor. */
     54        async_sess_t *osess; /**< Mainly for damage reporting to compositor. */
    5955        prodcons_t events; /**< Queue for window event loop. */
    6056        widget_t root; /**< Decoration widget serving as a root of widget hiearchy. */
     
    6258        widget_t *focus; /**< Widget owning the keyboard or NULL. */
    6359        fibril_mutex_t guard; /**< Mutex guarding window surface. */
    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 */
     60        surface_t *surface; /**< Window surface shared with compositor. */
    6761};
    6862
    6963/**
    70  * Allocate all resources for new window and register it in the display server.
     64 * Allocate all resources for new window and register it in the compositor.
    7165 * If the window is declared as main, its closure causes termination of the
    7266 * whole application. Note that opened window does not have any surface yet.
     
    7771/**
    7872 * Post resize event into event loop. Window negotiates new surface with
    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.
     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.
    8276 */
    8377extern void window_resize(window_t *, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     
    9690
    9791/**
    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
     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
    10094 * itself or copying its buffer onto window surface.
    10195 */
     
    126120
    127121/**
    128  * Initiate the closing cascade for the window. First, display sever deallocates
     122 * Initiate the closing cascade for the window. First, compositor deallocates
    129123 * output resources, prepares special closing input event for the window and
    130124 * deallocates input resources after the event is dispatched. When window
  • uspace/lib/meson.build

    re79a025 redb57bc6  
    3333        'c',
    3434        'math',
    35         'display',
    3635        'gui',
    3736        'draw',
     
    4039        'clui',
    4140        'pcm',
    42         'hound',
    43         'gfx',
    44         'ipcgfx',
    45         'display',
     41        'hound'
    4642]
    4743
     
    5955        'fmtutil',
    6056        'fs',
    61         'gfx',
     57        'graph',
    6258        'http',
    6359        'label',
     
    7672
    7773        'bithenge',
    78         'congfx',
    7974        'draw',
    8075        'drv',
    8176        'ext4',
     77        'gui',
    8278        'hound',
    83         'ipcgfx',
    84         'memgfx',
    8579        'nic',
    8680        'usb',
     
    9286
    9387        'ieee80211',
    94         'ddev',
    95         'display',
    96 
    97         'gui',
    98 
    99         'guigfx',
    10088]
    10189
  • uspace/srv/hid/input/input.c

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

    re79a025 redb57bc6  
    2727 */
    2828
    29 #include <ddev/info.h>
    30 #include <ddev_srv.h>
     29#include <stdlib.h>
    3130#include <errno.h>
     31#include <loc.h>
     32#include <stdio.h>
    3233#include <fibril_synch.h>
    33 #include <gfx/color.h>
    34 #include <gfx/context.h>
    35 #include <gfx/coord.h>
     34#include <abi/ipc/methods.h>
    3635#include <inttypes.h>
    3736#include <io/log.h>
     37#include <str.h>
     38#include <task.h>
     39
     40#include <abi/fb/visuals.h>
     41#include <adt/list.h>
     42#include <io/mode.h>
    3843#include <io/pixelmap.h>
    39 #include <ipcgfx/server.h>
    40 #include <loc.h>
    41 #include <stdio.h>
    42 #include <stdlib.h>
    43 #include <task.h>
     44#include <io/chargrid.h>
     45#include <graph.h>
    4446
    4547#include "rfb.h"
     
    4749#define NAME "rfb"
    4850
    49 static errno_t rfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
    50 static errno_t rfb_ddev_get_info(void *, ddev_info_t *);
    51 
    52 static errno_t rfb_gc_set_color(void *, gfx_color_t *);
    53 static errno_t rfb_gc_fill_rect(void *, gfx_rect_t *);
    54 static errno_t rfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
    55     gfx_bitmap_alloc_t *, void **);
    56 static errno_t rfb_gc_bitmap_destroy(void *);
    57 static errno_t rfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
    58 static errno_t rfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    59 
    60 static ddev_ops_t rfb_ddev_ops = {
    61         .get_gc = rfb_ddev_get_gc,
    62         .get_info = rfb_ddev_get_info
     51static vslmode_list_element_t pixel_mode;
     52static visualizer_t *vis;
     53static rfb_t rfb;
     54
     55static errno_t rfb_claim(visualizer_t *vs)
     56{
     57        return EOK;
     58}
     59
     60static errno_t rfb_yield(visualizer_t *vs)
     61{
     62        return EOK;
     63}
     64
     65static errno_t rfb_suspend(visualizer_t *vs)
     66{
     67        return EOK;
     68}
     69
     70static errno_t rfb_wakeup(visualizer_t *vs)
     71{
     72        return EOK;
     73}
     74
     75static 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;
     93        } 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
     128static errno_t rfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
     129{
     130        return EOK;
     131}
     132
     133static 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
    63140};
    64141
    65 typedef struct {
    66         rfb_t rfb;
    67         pixel_t color;
    68 } rfb_gc_t;
    69 
    70 typedef 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 
    79 static 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 
    88 static 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;
    100         } else {
    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 
    115 static 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 
    122 static 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  */
    145 static 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  */
    162 static 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  */
    189 errno_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;
    227 error:
    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  */
    238 static 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  */
    254 static 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  */
    319 static 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 }
    325 
    326142static void syntax_print(void)
    327143{
     
    329145}
    330146
    331 static 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         }
     147static void client_connection(ipc_call_t *call, void *data)
     148{
     149        graph_visualizer_connection(vis, call, data);
    359150}
    360151
    361152int main(int argc, char **argv)
    362153{
    363         rfb_t rfb;
    364 
    365154        log_init(NAME);
    366155
     
    399188        rfb_init(&rfb, width, height, rfb_name);
    400189
    401         async_set_fallback_port_handler(client_connection, &rfb);
     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);
    402218
    403219        errno_t rc = loc_server_register(NAME);
     
    424240        free(service_name);
    425241
    426         category_id_t ddev_cid;
    427         rc = loc_category_get_id("display-device", &ddev_cid, IPC_FLAG_BLOCKING);
    428         if (rc != EOK) {
    429                 fprintf(stderr, NAME ": Unable to get display device category id.\n");
    430                 return 1;
    431         }
    432 
    433         rc = loc_service_add_to_cat(service_id, ddev_cid);
    434         if (rc != EOK) {
    435                 fprintf(stderr, NAME ": Unable to add service to display device category.\n");
     242        category_id_t visualizer_category;
     243        rc = loc_category_get_id("visualizer", &visualizer_category, IPC_FLAG_BLOCKING);
     244        if (rc != EOK) {
     245                fprintf(stderr, NAME ": Unable to get visualizer category id.\n");
     246                return 1;
     247        }
     248
     249        rc = loc_service_add_to_cat(service_id, visualizer_category);
     250        if (rc != EOK) {
     251                fprintf(stderr, NAME ": Unable to add service to visualizer category.\n");
    436252                return 1;
    437253        }
  • uspace/srv/hid/rfb/meson.build

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

    re79a025 redb57bc6  
    13781378        categ_dir_add_cat(&cdir, cat);
    13791379
     1380        cat = category_new("visualizer");
     1381        categ_dir_add_cat(&cdir, cat);
     1382
    13801383        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

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