Changeset 0b63dc2 in mainline for uspace/drv/fb/kfb/port.c


Ignore:
Timestamp:
2019-12-07T20:26:28Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
df1a019
Parents:
71cbe5c
Message:

Switch compositor → display server

Convert KFB from visualizer to display device interface. Add ability
of display device implementor to provide client with arg2, arg3 needed
to connect to GC.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/fb/kfb/port.c

    r71cbe5c r0b63dc2  
    11/*
     2 * Copyright (c) 2019 Jiri Svoboda
    23 * Copyright (c) 2006 Jakub Vana
    34 * Copyright (c) 2006 Ondrej Palkovsky
     
    3839
    3940#include <abi/fb/visuals.h>
     41#include <adt/list.h>
     42#include <align.h>
     43#include <as.h>
     44#include <ddev_srv.h>
     45#include <ddi.h>
     46#include <ddf/log.h>
     47#include <errno.h>
     48#include <gfx/bitmap.h>
     49#include <gfx/color.h>
     50#include <gfx/coord.h>
     51#include <io/mode.h>
     52#include <io/pixelmap.h>
     53#include <ipcgfx/server.h>
     54#include <mem.h>
     55#include <pixconv.h>
    4056#include <stddef.h>
    4157#include <stdint.h>
    42 #include <errno.h>
    43 
    4458#include <stdlib.h>
    45 #include <mem.h>
    46 #include <as.h>
    47 #include <align.h>
    48 
    4959#include <sysinfo.h>
    50 #include <ddi.h>
    51 
    52 #include <adt/list.h>
    53 
    54 #include <io/mode.h>
    55 #include <io/pixelmap.h>
    56 #include <io/chargrid.h>
    57 
    58 #include <pixconv.h>
    59 
    60 #include <graph.h>
    6160
    6261#include "kfb.h"
    6362#include "port.h"
    6463
    65 #define FB_POS(x, y)  ((y) * kfb.scanline + (x) * kfb.pixel_bytes)
     64#define FB_POS(fb, x, y)  ((y) * (fb)->scanline + (x) * (fb)->pixel_bytes)
    6665
    6766typedef struct {
     67        ddf_fun_t *fun;
     68
    6869        sysarg_t paddr;
    6970        sysarg_t width;
     
    8081        size_t size;
    8182        uint8_t *addr;
     83
     84        /** Current drawing color */
     85        pixel_t color;
    8286} kfb_t;
    8387
    84 static kfb_t kfb;
    85 
    86 static vslmode_list_element_t pixel_mode;
    87 
    88 static errno_t kfb_claim(visualizer_t *vs)
    89 {
    90         return physmem_map(kfb.paddr + kfb.offset,
    91             ALIGN_UP(kfb.size, PAGE_SIZE) >> PAGE_WIDTH,
    92             AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb.addr);
    93 }
    94 
    95 static errno_t kfb_yield(visualizer_t *vs)
    96 {
     88typedef struct {
     89        kfb_t *kfb;
     90        gfx_bitmap_alloc_t alloc;
     91        gfx_rect_t rect;
     92        bool myalloc;
     93} kfb_bitmap_t;
     94
     95static errno_t kfb_ddev_get_gc(void *, sysarg_t *, sysarg_t *);
     96
     97static errno_t kfb_gc_set_color(void *, gfx_color_t *);
     98static errno_t kfb_gc_fill_rect(void *, gfx_rect_t *);
     99static errno_t kfb_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     100    gfx_bitmap_alloc_t *, void **);
     101static errno_t kfb_gc_bitmap_destroy(void *);
     102static errno_t kfb_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     103static errno_t kfb_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
     104
     105static ddev_ops_t kfb_ddev_ops = {
     106        .get_gc = kfb_ddev_get_gc
     107};
     108
     109static gfx_context_ops_t kfb_gc_ops = {
     110        .set_color = kfb_gc_set_color,
     111        .fill_rect = kfb_gc_fill_rect,
     112        .bitmap_create = kfb_gc_bitmap_create,
     113        .bitmap_destroy = kfb_gc_bitmap_destroy,
     114        .bitmap_render = kfb_gc_bitmap_render,
     115        .bitmap_get_alloc = kfb_gc_bitmap_get_alloc
     116};
     117
     118static errno_t kfb_ddev_get_gc(void *arg, sysarg_t *arg2, sysarg_t *arg3)
     119{
     120        kfb_t *kfb = (kfb_t *) arg;
     121
     122        *arg2 = ddf_fun_get_handle(kfb->fun);
     123        *arg3 = 42;
     124        return EOK;
     125}
     126
     127/** Set color on KFB.
     128 *
     129 * Set drawing color on KFB GC.
     130 *
     131 * @param arg KFB
     132 * @param color Color
     133 *
     134 * @return EOK on success or an error code
     135 */
     136static errno_t kfb_gc_set_color(void *arg, gfx_color_t *color)
     137{
     138        kfb_t *kfb = (kfb_t *) arg;
     139        uint16_t r, g, b;
     140
     141        gfx_color_get_rgb_i16(color, &r, &g, &b);
     142        kfb->color = PIXEL(0, r >> 8, g >> 8, b >> 8);
     143        return EOK;
     144}
     145
     146/** Fill rectangle on KFB.
     147 *
     148 * @param arg KFB
     149 * @param rect Rectangle
     150 *
     151 * @return EOK on success or an error code
     152 */
     153static errno_t kfb_gc_fill_rect(void *arg, gfx_rect_t *rect)
     154{
     155        kfb_t *kfb = (kfb_t *) arg;
     156        gfx_coord_t x, y;
     157
     158        // XXX We should handle p0.x > p1.x and p0.y > p1.y
     159
     160        for (y = rect->p0.y; y < rect->p1.y; y++) {
     161                for (x = rect->p0.x; x < rect->p1.x; x++) {
     162                        kfb->pixel2visual(kfb->addr + FB_POS(kfb, x, y),
     163                            kfb->color);
     164                }
     165        }
     166
     167        return EOK;
     168}
     169
     170/** Create bitmap in KFB GC.
     171 *
     172 * @param arg KFB
     173 * @param params Bitmap params
     174 * @param alloc Bitmap allocation info or @c NULL
     175 * @param rbm Place to store pointer to new bitmap
     176 * @return EOK on success or an error code
     177 */
     178errno_t kfb_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     179    gfx_bitmap_alloc_t *alloc, void **rbm)
     180{
     181        kfb_t *kfb = (kfb_t *) arg;
     182        kfb_bitmap_t *kfbbm = NULL;
     183        gfx_coord2_t dim;
    97184        errno_t rc;
    98185
    99         if (vs->mode_set) {
    100                 vs->ops.handle_damage = NULL;
    101         }
    102 
    103         rc = physmem_unmap(kfb.addr);
    104         if (rc != EOK)
    105                 return rc;
    106 
    107         kfb.addr = NULL;
    108         return EOK;
    109 }
    110 
    111 static errno_t kfb_handle_damage_pixels(visualizer_t *vs,
    112     sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
    113     sysarg_t x_offset, sysarg_t y_offset)
    114 {
    115         pixelmap_t *map = &vs->cells;
    116 
    117         if (x_offset == 0 && y_offset == 0) {
    118                 /* Faster damage routine ignoring offsets. */
    119                 for (sysarg_t y = y0; y < height + y0; ++y) {
    120                         pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
    121                         for (sysarg_t x = x0; x < width + x0; ++x) {
    122                                 kfb.pixel2visual(kfb.addr + FB_POS(x, y), *pixel++);
    123                         }
     186        kfbbm = calloc(1, sizeof(kfb_bitmap_t));
     187        if (kfbbm == NULL)
     188                return ENOMEM;
     189
     190        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     191        kfbbm->rect = params->rect;
     192
     193        if (alloc == NULL) {
     194                kfbbm->alloc.pitch = dim.x * sizeof(uint32_t);
     195                kfbbm->alloc.off0 = 0;
     196                kfbbm->alloc.pixels = malloc(kfbbm->alloc.pitch * dim.y);
     197                kfbbm->myalloc = true;
     198
     199                if (kfbbm->alloc.pixels == NULL) {
     200                        rc = ENOMEM;
     201                        goto error;
    124202                }
    125203        } else {
    126                 for (sysarg_t y = y0; y < height + y0; ++y) {
    127                         for (sysarg_t x = x0; x < width + x0; ++x) {
    128                                 kfb.pixel2visual(kfb.addr + FB_POS(x, y),
    129                                     *pixelmap_pixel_at(map,
    130                                     (x + x_offset) % map->width,
    131                                     (y + y_offset) % map->height));
    132                         }
     204                kfbbm->alloc = *alloc;
     205        }
     206
     207        kfbbm->kfb = kfb;
     208        *rbm = (void *)kfbbm;
     209        return EOK;
     210error:
     211        if (rbm != NULL)
     212                free(kfbbm);
     213        return rc;
     214}
     215
     216/** Destroy bitmap in KFB GC.
     217 *
     218 * @param bm Bitmap
     219 * @return EOK on success or an error code
     220 */
     221static errno_t kfb_gc_bitmap_destroy(void *bm)
     222{
     223        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     224        if (kfbbm->myalloc)
     225                free(kfbbm->alloc.pixels);
     226        free(kfbbm);
     227        return EOK;
     228}
     229
     230/** Render bitmap in KFB GC.
     231 *
     232 * @param bm Bitmap
     233 * @param srect0 Source rectangle or @c NULL
     234 * @param offs0 Offset or @c NULL
     235 * @return EOK on success or an error code
     236 */
     237static errno_t kfb_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     238    gfx_coord2_t *offs0)
     239{
     240        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     241        kfb_t *kfb = kfbbm->kfb;
     242        gfx_rect_t srect;
     243        gfx_rect_t drect;
     244        gfx_coord2_t offs;
     245        gfx_coord2_t bmdim;
     246        gfx_coord2_t dim;
     247        gfx_coord_t x, y;
     248        pixelmap_t pbm;
     249        pixel_t color;
     250
     251        if (srect0 != NULL)
     252                srect = *srect0;
     253        else
     254                srect = kfbbm->rect;
     255
     256        if (offs0 != NULL) {
     257                offs = *offs0;
     258        } else {
     259                offs.x = 0;
     260                offs.y = 0;
     261        }
     262
     263        /* Destination rectangle */
     264        gfx_rect_translate(&offs, &srect, &drect);
     265        gfx_coord2_subtract(&drect.p1, &drect.p0, &dim);
     266        gfx_coord2_subtract(&kfbbm->rect.p1, &kfbbm->rect.p0, &bmdim);
     267
     268        pbm.width = bmdim.x;
     269        pbm.height = bmdim.y;
     270        pbm.data = kfbbm->alloc.pixels;
     271
     272        for (y = srect.p0.y; y < srect.p1.y; y++) {
     273                for (x = srect.p0.x; x < srect.p1.x; x++) {
     274                        color = pixelmap_get_pixel(&pbm, x, y);
     275                        kfb->pixel2visual(kfb->addr +
     276                            FB_POS(kfb, x, y), color);
    133277                }
    134278        }
     
    137281}
    138282
    139 static errno_t kfb_change_mode(visualizer_t *vs, vslmode_t new_mode)
    140 {
    141         vs->ops.handle_damage = kfb_handle_damage_pixels;
    142         return EOK;
    143 }
    144 
    145 static errno_t kfb_suspend(visualizer_t *vs)
    146 {
    147         return EOK;
    148 }
    149 
    150 static errno_t kfb_wakeup(visualizer_t *vs)
    151 {
    152         return EOK;
    153 }
    154 
    155 static visualizer_ops_t kfb_ops = {
    156         .claim = kfb_claim,
    157         .yield = kfb_yield,
    158         .change_mode = kfb_change_mode,
    159         .handle_damage = NULL,
    160         .suspend = kfb_suspend,
    161         .wakeup = kfb_wakeup
    162 };
    163 
    164 static void graph_vsl_connection(ipc_call_t *icall, void *arg)
    165 {
    166         visualizer_t *vsl;
     283/** Get allocation info for bitmap in KFB GC.
     284 *
     285 * @param bm Bitmap
     286 * @param alloc Place to store allocation info
     287 * @return EOK on success or an error code
     288 */
     289static errno_t kfb_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     290{
     291        kfb_bitmap_t *kfbbm = (kfb_bitmap_t *)bm;
     292        *alloc = kfbbm->alloc;
     293        return EOK;
     294}
     295
     296#include <stdio.h>
     297static void kfb_client_conn(ipc_call_t *icall, void *arg)
     298{
     299        kfb_t *kfb;
     300        ddev_srv_t srv;
     301        sysarg_t gc_id;
     302        gfx_context_t *gc;
    167303        errno_t rc;
    168304
    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);
     305        kfb = (kfb_t *) ddf_fun_data_get((ddf_fun_t *) arg);
     306
     307        printf("kfb_client_conn arg2=%lu arg3=%lu arg4=%lu\n",
     308            ipc_get_arg2(icall), ipc_get_arg3(icall), ipc_get_arg4(icall));
     309        gc_id = ipc_get_arg3(icall);
     310
     311        if (gc_id == 0) {
     312                /* Set up protocol structure */
     313                ddev_srv_initialize(&srv);
     314                srv.ops = &kfb_ddev_ops;
     315                srv.arg = kfb;
     316
     317                /* Handle connection */
     318                ddev_conn(icall, &srv);
     319        } else {
     320                assert(gc_id == 42);
     321
     322                rc = physmem_map(kfb->paddr + kfb->offset,
     323                    ALIGN_UP(kfb->size, PAGE_SIZE) >> PAGE_WIDTH,
     324                    AS_AREA_READ | AS_AREA_WRITE, (void *) &kfb->addr);
     325                if (rc != EOK)
     326                        goto error;
     327
     328                rc = gfx_context_new(&kfb_gc_ops, kfb, &gc);
     329                if (rc != EOK)
     330                        goto error;
     331
     332                /* GC connection */
     333                gc_conn(icall, gc);
     334
     335                rc = physmem_unmap(kfb->addr);
    174336                if (rc == EOK)
    175                         kfb.addr = NULL;
    176         }
     337                        kfb->addr = NULL;
     338        }
     339
     340        return;
     341error:
     342        if (kfb->addr != NULL) {
     343                if (physmem_unmap(kfb->addr) == EOK)
     344                        kfb->addr = NULL;
     345        }
     346
     347        async_answer_0(icall, rc);
    177348}
    178349
    179350errno_t port_init(ddf_dev_t *dev)
    180351{
     352        ddf_fun_t *fun = NULL;
     353        kfb_t *kfb = NULL;
     354        errno_t rc;
     355
     356        fun = ddf_fun_create(dev, fun_exposed, "kfb");
     357        if (fun == NULL) {
     358                rc = ENOMEM;
     359                goto error;
     360        }
     361
     362        ddf_fun_set_conn_handler(fun, &kfb_client_conn);
     363
     364        kfb = ddf_fun_data_alloc(fun, sizeof(kfb_t));
     365        if (kfb == NULL) {
     366                rc = ENOMEM;
     367                goto error;
     368        }
     369
    181370        sysarg_t present;
    182         errno_t rc = sysinfo_get_value("fb", &present);
     371        rc = sysinfo_get_value("fb", &present);
    183372        if (rc != EOK)
    184373                present = false;
    185374
    186         if (!present)
    187                 return ENOENT;
     375        if (!present) {
     376                ddf_fun_destroy(fun);
     377                rc = ENOENT;
     378                goto error;
     379        }
    188380
    189381        sysarg_t kind;
     
    192384                kind = (sysarg_t) -1;
    193385
    194         if (kind != 1)
    195                 return EINVAL;
     386        if (kind != 1) {
     387                rc = EINVAL;
     388                goto error;
     389        }
    196390
    197391        sysarg_t paddr;
    198392        rc = sysinfo_get_value("fb.address.physical", &paddr);
    199393        if (rc != EOK)
    200                 return rc;
     394                goto error;
    201395
    202396        sysarg_t offset;
     
    208402        rc = sysinfo_get_value("fb.width", &width);
    209403        if (rc != EOK)
    210                 return rc;
     404                goto error;
    211405
    212406        sysarg_t height;
    213407        rc = sysinfo_get_value("fb.height", &height);
    214408        if (rc != EOK)
    215                 return rc;
     409                goto error;
    216410
    217411        sysarg_t scanline;
    218412        rc = sysinfo_get_value("fb.scanline", &scanline);
    219413        if (rc != EOK)
    220                 return rc;
     414                goto error;
    221415
    222416        sysarg_t visual;
    223417        rc = sysinfo_get_value("fb.visual", &visual);
    224418        if (rc != EOK)
    225                 return rc;
    226 
    227         kfb.width = width;
    228         kfb.height = height;
    229         kfb.paddr = paddr;
    230         kfb.offset = offset;
    231         kfb.scanline = scanline;
    232         kfb.visual = visual;
     419                goto error;
     420
     421        kfb->fun = fun;
     422
     423        kfb->width = width;
     424        kfb->height = height;
     425        kfb->paddr = paddr;
     426        kfb->offset = offset;
     427        kfb->scanline = scanline;
     428        kfb->visual = visual;
    233429
    234430        switch (visual) {
    235431        case VISUAL_INDIRECT_8:
    236                 kfb.pixel2visual = pixel2bgr_323;
    237                 kfb.visual2pixel = bgr_323_2pixel;
    238                 kfb.visual_mask = visual_mask_323;
    239                 kfb.pixel_bytes = 1;
     432                kfb->pixel2visual = pixel2bgr_323;
     433                kfb->visual2pixel = bgr_323_2pixel;
     434                kfb->visual_mask = visual_mask_323;
     435                kfb->pixel_bytes = 1;
    240436                break;
    241437        case VISUAL_RGB_5_5_5_LE:
    242                 kfb.pixel2visual = pixel2rgb_555_le;
    243                 kfb.visual2pixel = rgb_555_le_2pixel;
    244                 kfb.visual_mask = visual_mask_555;
    245                 kfb.pixel_bytes = 2;
     438                kfb->pixel2visual = pixel2rgb_555_le;
     439                kfb->visual2pixel = rgb_555_le_2pixel;
     440                kfb->visual_mask = visual_mask_555;
     441                kfb->pixel_bytes = 2;
    246442                break;
    247443        case VISUAL_RGB_5_5_5_BE:
    248                 kfb.pixel2visual = pixel2rgb_555_be;
    249                 kfb.visual2pixel = rgb_555_be_2pixel;
    250                 kfb.visual_mask = visual_mask_555;
    251                 kfb.pixel_bytes = 2;
     444                kfb->pixel2visual = pixel2rgb_555_be;
     445                kfb->visual2pixel = rgb_555_be_2pixel;
     446                kfb->visual_mask = visual_mask_555;
     447                kfb->pixel_bytes = 2;
    252448                break;
    253449        case VISUAL_RGB_5_6_5_LE:
    254                 kfb.pixel2visual = pixel2rgb_565_le;
    255                 kfb.visual2pixel = rgb_565_le_2pixel;
    256                 kfb.visual_mask = visual_mask_565;
    257                 kfb.pixel_bytes = 2;
     450                kfb->pixel2visual = pixel2rgb_565_le;
     451                kfb->visual2pixel = rgb_565_le_2pixel;
     452                kfb->visual_mask = visual_mask_565;
     453                kfb->pixel_bytes = 2;
    258454                break;
    259455        case VISUAL_RGB_5_6_5_BE:
    260                 kfb.pixel2visual = pixel2rgb_565_be;
    261                 kfb.visual2pixel = rgb_565_be_2pixel;
    262                 kfb.visual_mask = visual_mask_565;
    263                 kfb.pixel_bytes = 2;
     456                kfb->pixel2visual = pixel2rgb_565_be;
     457                kfb->visual2pixel = rgb_565_be_2pixel;
     458                kfb->visual_mask = visual_mask_565;
     459                kfb->pixel_bytes = 2;
    264460                break;
    265461        case VISUAL_RGB_8_8_8:
    266                 kfb.pixel2visual = pixel2rgb_888;
    267                 kfb.visual2pixel = rgb_888_2pixel;
    268                 kfb.visual_mask = visual_mask_888;
    269                 kfb.pixel_bytes = 3;
     462                kfb->pixel2visual = pixel2rgb_888;
     463                kfb->visual2pixel = rgb_888_2pixel;
     464                kfb->visual_mask = visual_mask_888;
     465                kfb->pixel_bytes = 3;
    270466                break;
    271467        case VISUAL_BGR_8_8_8:
    272                 kfb.pixel2visual = pixel2bgr_888;
    273                 kfb.visual2pixel = bgr_888_2pixel;
    274                 kfb.visual_mask = visual_mask_888;
    275                 kfb.pixel_bytes = 3;
     468                kfb->pixel2visual = pixel2bgr_888;
     469                kfb->visual2pixel = bgr_888_2pixel;
     470                kfb->visual_mask = visual_mask_888;
     471                kfb->pixel_bytes = 3;
    276472                break;
    277473        case VISUAL_RGB_8_8_8_0:
    278                 kfb.pixel2visual = pixel2rgb_8880;
    279                 kfb.visual2pixel = rgb_8880_2pixel;
    280                 kfb.visual_mask = visual_mask_8880;
    281                 kfb.pixel_bytes = 4;
     474                kfb->pixel2visual = pixel2rgb_8880;
     475                kfb->visual2pixel = rgb_8880_2pixel;
     476                kfb->visual_mask = visual_mask_8880;
     477                kfb->pixel_bytes = 4;
    282478                break;
    283479        case VISUAL_RGB_0_8_8_8:
    284                 kfb.pixel2visual = pixel2rgb_0888;
    285                 kfb.visual2pixel = rgb_0888_2pixel;
    286                 kfb.visual_mask = visual_mask_0888;
    287                 kfb.pixel_bytes = 4;
     480                kfb->pixel2visual = pixel2rgb_0888;
     481                kfb->visual2pixel = rgb_0888_2pixel;
     482                kfb->visual_mask = visual_mask_0888;
     483                kfb->pixel_bytes = 4;
    288484                break;
    289485        case VISUAL_BGR_0_8_8_8:
    290                 kfb.pixel2visual = pixel2bgr_0888;
    291                 kfb.visual2pixel = bgr_0888_2pixel;
    292                 kfb.visual_mask = visual_mask_0888;
    293                 kfb.pixel_bytes = 4;
     486                kfb->pixel2visual = pixel2bgr_0888;
     487                kfb->visual2pixel = bgr_0888_2pixel;
     488                kfb->visual_mask = visual_mask_0888;
     489                kfb->pixel_bytes = 4;
    294490                break;
    295491        case VISUAL_BGR_8_8_8_0:
    296                 kfb.pixel2visual = pixel2bgr_8880;
    297                 kfb.visual2pixel = bgr_8880_2pixel;
    298                 kfb.visual_mask = visual_mask_8880;
    299                 kfb.pixel_bytes = 4;
     492                kfb->pixel2visual = pixel2bgr_8880;
     493                kfb->visual2pixel = bgr_8880_2pixel;
     494                kfb->visual_mask = visual_mask_8880;
     495                kfb->pixel_bytes = 4;
    300496                break;
    301497        default:
     
    303499        }
    304500
    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);
     501        kfb->size = scanline * height;
     502        kfb->addr = AS_AREA_ANY;
     503
     504        rc = ddf_fun_bind(fun);
     505        if (rc != EOK)
     506                goto error;
     507
     508        rc = ddf_fun_add_to_category(fun, "display-device");
    342509        if (rc != EOK) {
    343                 list_remove(&pixel_mode.link);
    344                 ddf_fun_destroy(fun_vs);
    345                 as_area_destroy(kfb.addr);
    346                 return rc;
    347         }
    348 
    349         vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
    350         rc = ddf_fun_add_to_category(fun_vs, "visualizer");
    351         if (rc != EOK) {
    352                 list_remove(&pixel_mode.link);
    353                 ddf_fun_unbind(fun_vs);
    354                 ddf_fun_destroy(fun_vs);
    355                 as_area_destroy(kfb.addr);
    356                 return rc;
    357         }
    358 
    359         return EOK;
     510                ddf_fun_unbind(fun);
     511                goto error;
     512        }
     513
     514        return EOK;
     515error:
     516        if (fun != NULL)
     517                ddf_fun_destroy(fun);
     518        return rc;
    360519}
    361520
Note: See TracChangeset for help on using the changeset viewer.