Changeset 0008c0f in mainline


Ignore:
Timestamp:
2019-10-26T23:30:51Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
587b4cb
Parents:
7b882c1f
Message:

Bitmaps in IPC GC and in display server

Location:
uspace
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/gfxdemo/gfxdemo.c

    r7b882c1f r0008c0f  
    144144                        offs.y = 0;
    145145
    146                         gfx_bitmap_render(bitmap, &srect, &offs);
     146                        rc = gfx_bitmap_render(bitmap, &srect, &offs);
     147                        if (rc != EOK)
     148                                goto error;
    147149                        fibril_usleep(500 * 1000);
    148150                }
     
    152154
    153155        return EOK;
     156error:
     157        gfx_bitmap_destroy(bitmap);
     158        return rc;
    154159}
    155160
  • uspace/lib/ipcgfx/include/ipcgfx/ipc/gc.h

    r7b882c1f r0008c0f  
    4040typedef enum {
    4141        GC_SET_RGB_COLOR = IPC_FIRST_USER_METHOD,
    42         GC_FILL_RECT
     42        GC_FILL_RECT,
     43        GC_BITMAP_CREATE,
     44        GC_BITMAP_DESTROY,
     45        GC_BITMAP_RENDER,
     46        GC_BITMAP_GET_ALLOC
    4347} gc_request_t;
    4448
  • uspace/lib/ipcgfx/private/client.h

    r7b882c1f r0008c0f  
    5252};
    5353
     54/** Bitmap in IPC GC */
     55typedef struct {
     56        /** Containing IPC GC */
     57        struct ipc_gc *ipcgc;
     58        /** Allocation info */
     59        gfx_bitmap_alloc_t alloc;
     60        /** @c true if we allocated the bitmap, @c false if allocated by caller */
     61        bool myalloc;
     62        /** Rectangle covered by bitmap */
     63        gfx_rect_t rect;
     64        /** Server bitmap ID */
     65        sysarg_t bmp_id;
     66} ipc_gc_bitmap_t;
     67
    5468#endif
    5569
  • uspace/lib/ipcgfx/src/client.c

    r7b882c1f r0008c0f  
    3636 */
    3737
     38#include <as.h>
    3839#include <ipcgfx/client.h>
    3940#include <ipcgfx/ipc/gc.h>
    4041#include <gfx/color.h>
     42#include <gfx/coord.h>
    4143#include <gfx/context.h>
    4244#include <stdlib.h>
     
    4547static errno_t ipc_gc_set_color(void *, gfx_color_t *);
    4648static errno_t ipc_gc_fill_rect(void *, gfx_rect_t *);
     49static errno_t ipc_gc_bitmap_create(void *, gfx_bitmap_params_t *,
     50    gfx_bitmap_alloc_t *, void **);
     51static errno_t ipc_gc_bitmap_destroy(void *);
     52static errno_t ipc_gc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     53static errno_t ipc_gc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    4754
    4855gfx_context_ops_t ipc_gc_ops = {
    4956        .set_color = ipc_gc_set_color,
    50         .fill_rect = ipc_gc_fill_rect
     57        .fill_rect = ipc_gc_fill_rect,
     58        .bitmap_create = ipc_gc_bitmap_create,
     59        .bitmap_destroy = ipc_gc_bitmap_destroy,
     60        .bitmap_render = ipc_gc_bitmap_render,
     61        .bitmap_get_alloc = ipc_gc_bitmap_get_alloc
    5162};
    5263
     
    101112}
    102113
     114/** Create bitmap in IPC GC.
     115 *
     116 * @param arg IPC GC
     117 * @param params Bitmap params
     118 * @param alloc Bitmap allocation info or @c NULL
     119 * @param rbm Place to store pointer to new bitmap
     120 * @return EOK on success or an error code
     121 */
     122errno_t ipc_gc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     123    gfx_bitmap_alloc_t *alloc, void **rbm)
     124{
     125        ipc_gc_t *ipcgc = (ipc_gc_t *) arg;
     126        ipc_gc_bitmap_t *ipcbm = NULL;
     127        gfx_coord2_t dim;
     128        async_exch_t *exch = NULL;
     129        ipc_call_t answer;
     130        aid_t req;
     131        errno_t rc;
     132
     133        ipcbm = calloc(1, sizeof(ipc_gc_bitmap_t));
     134        if (ipcbm == NULL)
     135                return ENOMEM;
     136
     137        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
     138        ipcbm->rect = params->rect;
     139
     140        if (alloc == NULL) {
     141                ipcbm->alloc.pitch = dim.x * sizeof(uint32_t);
     142                ipcbm->alloc.off0 = 0;
     143                ipcbm->alloc.pixels = as_area_create(AS_AREA_ANY,
     144                    dim.x * dim.y * sizeof(uint32_t), AS_AREA_READ |
     145                    AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
     146                if (ipcbm->alloc.pixels == NULL) {
     147                        rc = ENOMEM;
     148                        goto error;
     149                }
     150
     151                ipcbm->myalloc = true;
     152        } else {
     153                /*
     154                 * XXX We could allow this if the pixels point to a shareable
     155                 * area or we could do a copy of the data when rendering
     156                 */
     157                rc = ENOTSUP;
     158                goto error;
     159        }
     160
     161        exch = async_exchange_begin(ipcgc->sess);
     162        req = async_send_0(exch, GC_BITMAP_CREATE, &answer);
     163        rc = async_data_write_start(exch, params, sizeof (gfx_bitmap_params_t));
     164        if (rc != EOK) {
     165                async_forget(req);
     166                goto error;
     167        }
     168
     169        rc = async_share_out_start(exch, ipcbm->alloc.pixels,
     170            AS_AREA_READ | AS_AREA_CACHEABLE);
     171        if (rc != EOK) {
     172                async_forget(req);
     173                goto error;
     174        }
     175        async_exchange_end(exch);
     176        exch = NULL;
     177
     178        async_wait_for(req, &rc);
     179        if (rc != EOK)
     180                goto error;
     181
     182        ipcbm->ipcgc = ipcgc;
     183        ipcbm->bmp_id = ipc_get_arg1(&answer);
     184        *rbm = (void *)ipcbm;
     185        return EOK;
     186error:
     187        if (exch != NULL)
     188                async_exchange_end(exch);
     189        if (ipcbm != NULL) {
     190                if (ipcbm->alloc.pixels != NULL)
     191                        as_area_destroy(ipcbm->alloc.pixels);
     192                free(ipcbm);
     193        }
     194        return rc;
     195}
     196
     197/** Destroy bitmap in IPC GC.
     198 *
     199 * @param bm Bitmap
     200 * @return EOK on success or an error code
     201 */
     202static errno_t ipc_gc_bitmap_destroy(void *bm)
     203{
     204        ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
     205        async_exch_t *exch;
     206        errno_t rc;
     207
     208        printf("ipc_gc_bitmap_destroy\n");
     209
     210        exch = async_exchange_begin(ipcbm->ipcgc->sess);
     211        rc = async_req_1_0(exch, GC_BITMAP_DESTROY, ipcbm->bmp_id);
     212        async_exchange_end(exch);
     213
     214        if (rc != EOK)
     215                return rc;
     216
     217        if (ipcbm->myalloc)
     218                as_area_destroy(ipcbm->alloc.pixels);
     219        free(ipcbm);
     220        return EOK;
     221}
     222
     223/** Render bitmap in IPC GC.
     224 *
     225 * @param bm Bitmap
     226 * @param srect0 Source rectangle or @c NULL
     227 * @param offs0 Offset or @c NULL
     228 * @return EOK on success or an error code
     229 */
     230static errno_t ipc_gc_bitmap_render(void *bm, gfx_rect_t *srect0,
     231    gfx_coord2_t *offs0)
     232{
     233        ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
     234        gfx_rect_t srect;
     235        gfx_rect_t drect;
     236        gfx_coord2_t offs;
     237        async_exch_t *exch = NULL;
     238        ipc_call_t answer;
     239        aid_t req;
     240        errno_t rc;
     241
     242        if (srect0 != NULL)
     243                srect = *srect0;
     244        else
     245                srect = ipcbm->rect;
     246
     247        if (offs0 != NULL) {
     248                offs = *offs0;
     249        } else {
     250                offs.x = 0;
     251                offs.y = 0;
     252        }
     253
     254        /* Destination rectangle */
     255        gfx_rect_translate(&offs, &srect, &drect);
     256
     257        exch = async_exchange_begin(ipcbm->ipcgc->sess);
     258        req = async_send_3(exch, GC_BITMAP_RENDER, ipcbm->bmp_id, offs.x,
     259            offs.y, &answer);
     260
     261        rc = async_data_write_start(exch, &srect, sizeof (gfx_rect_t));
     262        if (rc != EOK) {
     263                async_forget(req);
     264                goto error;
     265        }
     266
     267        async_exchange_end(exch);
     268        exch = NULL;
     269
     270        async_wait_for(req, &rc);
     271        if (rc != EOK)
     272                goto error;
     273
     274        return EOK;
     275error:
     276        if (exch != NULL)
     277                async_exchange_end(exch);
     278        return rc;
     279}
     280
     281/** Get allocation info for bitmap in IPC GC.
     282 *
     283 * @param bm Bitmap
     284 * @param alloc Place to store allocation info
     285 * @return EOK on success or an error code
     286 */
     287static errno_t ipc_gc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     288{
     289        ipc_gc_bitmap_t *ipcbm = (ipc_gc_bitmap_t *)bm;
     290        *alloc = ipcbm->alloc;
     291        return EOK;
     292}
     293
    103294/** Create IPC GC.
    104295 *
  • uspace/lib/ipcgfx/src/server.c

    r7b882c1f r0008c0f  
    3636 */
    3737
     38#include <as.h>
    3839#include <errno.h>
     40#include <gfx/bitmap.h>
    3941#include <gfx/color.h>
    4042#include <gfx/render.h>
     
    4345#include <ipcgfx/server.h>
    4446#include <stdint.h>
    45 
     47#include <stdlib.h>
    4648#include <stdio.h>
    4749
    48 #include <bd_srv.h>
    49 
    50 static void gc_set_rgb_color_srv(gfx_context_t *gc, ipc_call_t *call)
     50#include "../private/server.h"
     51
     52static ipc_gc_srv_bitmap_t *gc_bitmap_lookup(ipc_gc_srv_t *, sysarg_t);
     53
     54static void gc_set_rgb_color_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
    5155{
    5256        uint16_t r, g, b;
     
    6468        }
    6569
    66         rc = gfx_set_color(gc, color);
     70        rc = gfx_set_color(srvgc->gc, color);
    6771        async_answer_0(call, rc);
    6872        printf("done with rgb_color_srv\n");
    6973}
    7074
    71 static void gc_fill_rect_srv(gfx_context_t *gc, ipc_call_t *call)
     75static void gc_fill_rect_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
    7276{
    7377        gfx_rect_t rect;
     
    7983        rect.p1.y = ipc_get_arg4(call);
    8084
    81         rc = gfx_fill_rect(gc, &rect);
     85        rc = gfx_fill_rect(srvgc->gc, &rect);
    8286        async_answer_0(call, rc);
    8387}
    8488
     89static void gc_bitmap_create_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
     90{
     91        gfx_bitmap_params_t params;
     92        gfx_bitmap_alloc_t alloc;
     93        gfx_bitmap_t *bitmap;
     94        gfx_coord2_t dim;
     95        ipc_gc_srv_bitmap_t *srvbmp = NULL;
     96        ipc_call_t call;
     97        size_t size;
     98        unsigned int flags;
     99        void *pixels;
     100        errno_t rc;
     101
     102        if (!async_data_write_receive(&call, &size)) {
     103                async_answer_0(&call, EREFUSED);
     104                async_answer_0(icall, EREFUSED);
     105                return;
     106        }
     107
     108        if (size != sizeof(gfx_bitmap_params_t)) {
     109                async_answer_0(&call, EINVAL);
     110                async_answer_0(icall, EINVAL);
     111                return;
     112        }
     113
     114        rc = async_data_write_finalize(&call, &params, size);
     115        if (rc != EOK) {
     116                async_answer_0(&call, rc);
     117                async_answer_0(icall, rc);
     118                return;
     119        }
     120
     121        /* Bitmap dimensions */
     122        gfx_coord2_subtract(&params.rect.p1, &params.rect.p0, &dim);
     123
     124        if (!async_share_out_receive(&call, &size, &flags)) {
     125                async_answer_0(icall, EINVAL);
     126                return;
     127        }
     128
     129        /* Check size */
     130        if (size != PAGES2SIZE(SIZE2PAGES(dim.x * dim.y * sizeof(uint32_t)))) {
     131                printf("size=%zu, expected=%zu\n", size, dim.x * dim.y * sizeof(uint32_t));
     132                async_answer_0(icall, EINVAL);
     133                return;
     134        }
     135
     136        rc = async_share_out_finalize(&call, &pixels);
     137        if (rc != EOK || pixels == AS_MAP_FAILED) {
     138                async_answer_0(icall, ENOMEM);
     139                return;
     140        }
     141
     142        alloc.pitch = dim.x * sizeof(uint32_t);
     143        alloc.off0 = 0;
     144        alloc.pixels = pixels;
     145
     146        srvbmp = calloc(1, sizeof(ipc_gc_srv_bitmap_t));
     147        if (srvbmp == NULL) {
     148                as_area_destroy(pixels);
     149                async_answer_0(icall, ENOMEM);
     150                return;
     151        }
     152
     153        rc = gfx_bitmap_create(srvgc->gc, &params, &alloc, &bitmap);
     154        if (rc != EOK) {
     155                free(srvbmp);
     156                as_area_destroy(pixels);
     157                async_answer_0(icall, rc);
     158                return;
     159        }
     160
     161        srvbmp->srvgc = srvgc;
     162        list_append(&srvbmp->lbitmaps, &srvgc->bitmaps);
     163        srvbmp->bmp = bitmap;
     164        srvbmp->bmp_id = srvgc->next_bmp_id++;
     165        printf("gc_bitmap_create_srv: storing bmp_id=%lu\n", srvbmp->bmp_id);
     166
     167        async_answer_1(icall, EOK, srvbmp->bmp_id);
     168}
     169
     170static void gc_bitmap_destroy_srv(ipc_gc_srv_t *srvgc, ipc_call_t *call)
     171{
     172        sysarg_t bmp_id;
     173        ipc_gc_srv_bitmap_t *bitmap;
     174        errno_t rc;
     175
     176        bmp_id = ipc_get_arg1(call);
     177
     178        bitmap = gc_bitmap_lookup(srvgc, bmp_id);
     179        if (bitmap == NULL) {
     180                async_answer_0(call, ENOENT);
     181                return;
     182        }
     183
     184        rc = gfx_bitmap_destroy(bitmap->bmp);
     185        if (rc != EOK) {
     186                async_answer_0(call, rc);
     187                return;
     188        }
     189
     190        list_remove(&bitmap->lbitmaps);
     191        free(bitmap);
     192
     193        async_answer_0(call, rc);
     194}
     195
     196static void gc_bitmap_render_srv(ipc_gc_srv_t *srvgc, ipc_call_t *icall)
     197{
     198        ipc_gc_srv_bitmap_t *bitmap;
     199        sysarg_t bmp_id;
     200        gfx_rect_t srect;
     201        gfx_coord2_t offs;
     202        ipc_call_t call;
     203        size_t size;
     204        errno_t rc;
     205
     206        if (!async_data_write_receive(&call, &size)) {
     207                async_answer_0(&call, EREFUSED);
     208                async_answer_0(icall, EREFUSED);
     209                return;
     210        }
     211
     212        if (size != sizeof(gfx_rect_t)) {
     213                async_answer_0(&call, EINVAL);
     214                async_answer_0(icall, EINVAL);
     215                return;
     216        }
     217
     218        rc = async_data_write_finalize(&call, &srect, size);
     219        if (rc != EOK) {
     220                async_answer_0(&call, rc);
     221                async_answer_0(icall, rc);
     222                return;
     223        }
     224
     225        bmp_id = ipc_get_arg1(icall);
     226        offs.x = ipc_get_arg2(icall);
     227        offs.y = ipc_get_arg3(icall);
     228
     229        bitmap = gc_bitmap_lookup(srvgc, bmp_id);
     230        if (bitmap == NULL) {
     231                async_answer_0(icall, ENOENT);
     232                return;
     233        }
     234
     235        rc = gfx_bitmap_render(bitmap->bmp, &srect, &offs);
     236        async_answer_0(icall, rc);
     237}
     238
    85239errno_t gc_conn(ipc_call_t *icall, gfx_context_t *gc)
    86240{
     241        ipc_gc_srv_t srvgc;
     242
    87243        /* Accept the connection */
    88244        async_accept_0(icall);
    89245
    90246        printf("gc_conn: accepted connection\n");
     247        srvgc.gc = gc;
     248        list_initialize(&srvgc.bitmaps);
     249        srvgc.next_bmp_id = 1;
    91250
    92251        while (true) {
     
    104263                case GC_SET_RGB_COLOR:
    105264                        printf("gc_conn: set_rgb_color\n");
    106                         gc_set_rgb_color_srv(gc, &call);
     265                        gc_set_rgb_color_srv(&srvgc, &call);
    107266                        printf("gc_conn: done set_rgb_color\n");
    108267                        break;
    109268                case GC_FILL_RECT:
    110269                        printf("gc_conn: fill_rect_srv\n");
    111                         gc_fill_rect_srv(gc, &call);
     270                        gc_fill_rect_srv(&srvgc, &call);
    112271                        printf("gc_conn: done fill_rect_srv\n");
     272                        break;
     273                case GC_BITMAP_CREATE:
     274                        printf("gc_conn: bitmap_create_srv\n");
     275                        gc_bitmap_create_srv(&srvgc, &call);
     276                        printf("gc_conn: done bitmap_create_srv\n");
     277                        break;
     278                case GC_BITMAP_DESTROY:
     279                        printf("gc_conn: bitmap_destroy_srv\n");
     280                        gc_bitmap_destroy_srv(&srvgc, &call);
     281                        printf("gc_conn: done bitmap_destroy_srv\n");
     282                        break;
     283                case GC_BITMAP_RENDER:
     284                        printf("gc_conn: bitmap_render_srv\n");
     285                        gc_bitmap_render_srv(&srvgc, &call);
     286                        printf("gc_conn: done bitmap_render_srv\n");
    113287                        break;
    114288                default:
     
    122296}
    123297
     298static ipc_gc_srv_bitmap_t *gc_bitmap_lookup(ipc_gc_srv_t *srvgc,
     299    sysarg_t bmp_id)
     300{
     301        link_t *link;
     302        ipc_gc_srv_bitmap_t *bmp;
     303
     304        link = list_first(&srvgc->bitmaps);
     305        while (link != NULL) {
     306                bmp = list_get_instance(link, ipc_gc_srv_bitmap_t, lbitmaps);
     307                printf("gc_bitmap_lookup: %lu==%lu?\n", bmp->bmp_id, bmp_id);
     308                if (bmp->bmp_id == bmp_id)
     309                        return bmp;
     310                link = list_next(link, &srvgc->bitmaps);
     311        }
     312
     313        return NULL;
     314}
     315
    124316/** @}
    125317 */
  • uspace/srv/hid/display/types/display/window.h

    r7b882c1f r0008c0f  
    4242typedef sysarg_t ds_wnd_id_t;
    4343
     44/** Display server window */
    4445typedef struct ds_window {
    4546        /** Parent display */
     
    5354} ds_window_t;
    5455
     56/** Bitmap in display server window GC */
     57typedef struct {
     58        /** Containing window */
     59        ds_window_t *wnd;
     60        /** Display bitmap */
     61        gfx_bitmap_t *bitmap;
     62} ds_window_bitmap_t;
     63
    5564#endif
    5665
  • uspace/srv/hid/display/window.c

    r7b882c1f r0008c0f  
    3636 */
    3737
     38#include <gfx/bitmap.h>
    3839#include <gfx/color.h>
     40#include <gfx/coord.h>
    3941#include <gfx/context.h>
    4042#include <gfx/render.h>
     
    4648static errno_t ds_window_set_color(void *, gfx_color_t *);
    4749static errno_t ds_window_fill_rect(void *, gfx_rect_t *);
     50static errno_t ds_window_bitmap_create(void *, gfx_bitmap_params_t *,
     51    gfx_bitmap_alloc_t *, void **);
     52static errno_t ds_window_bitmap_destroy(void *);
     53static errno_t ds_window_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     54static errno_t ds_window_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    4855
    4956gfx_context_ops_t ds_window_ops = {
    5057        .set_color = ds_window_set_color,
    51         .fill_rect = ds_window_fill_rect
     58        .fill_rect = ds_window_fill_rect,
     59        .bitmap_create = ds_window_bitmap_create,
     60        .bitmap_destroy = ds_window_bitmap_destroy,
     61        .bitmap_render = ds_window_bitmap_render,
     62        .bitmap_get_alloc = ds_window_bitmap_get_alloc
    5263};
    5364
     
    8293        log_msg(LOG_DEFAULT, LVL_NOTE, "gc_fill_rect");
    8394        return gfx_fill_rect(wnd->display->gc, rect);
     95}
     96
     97/** Create bitmap in canvas GC.
     98 *
     99 * @param arg Canvas GC
     100 * @param params Bitmap params
     101 * @param alloc Bitmap allocation info or @c NULL
     102 * @param rbm Place to store pointer to new bitmap
     103 * @return EOK on success or an error code
     104 */
     105errno_t ds_window_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     106    gfx_bitmap_alloc_t *alloc, void **rbm)
     107{
     108        ds_window_t *wnd = (ds_window_t *) arg;
     109        ds_window_bitmap_t *cbm = NULL;
     110        errno_t rc;
     111
     112        cbm = calloc(1, sizeof(ds_window_bitmap_t));
     113        if (cbm == NULL)
     114                return ENOMEM;
     115
     116        rc = gfx_bitmap_create(wnd->display->gc, params, alloc, &cbm->bitmap);
     117        if (rc != EOK)
     118                goto error;
     119
     120        cbm->wnd = wnd;
     121        *rbm = (void *)cbm;
     122        return EOK;
     123error:
     124        if (cbm != NULL)
     125                free(cbm);
     126        return rc;
     127}
     128
     129/** Destroy bitmap in canvas GC.
     130 *
     131 * @param bm Bitmap
     132 * @return EOK on success or an error code
     133 */
     134static errno_t ds_window_bitmap_destroy(void *bm)
     135{
     136        ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
     137
     138        gfx_bitmap_destroy(cbm->bitmap);
     139        free(cbm);
     140        return EOK;
     141}
     142
     143/** Render bitmap in canvas GC.
     144 *
     145 * @param bm Bitmap
     146 * @param srect0 Source rectangle or @c NULL
     147 * @param offs0 Offset or @c NULL
     148 * @return EOK on success or an error code
     149 */
     150static errno_t ds_window_bitmap_render(void *bm, gfx_rect_t *srect0,
     151    gfx_coord2_t *offs0)
     152{
     153        ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
     154
     155        return gfx_bitmap_render(cbm->bitmap, srect0, offs0);
     156}
     157
     158/** Get allocation info for bitmap in canvas GC.
     159 *
     160 * @param bm Bitmap
     161 * @param alloc Place to store allocation info
     162 * @return EOK on success or an error code
     163 */
     164static errno_t ds_window_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     165{
     166        ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
     167
     168        return gfx_bitmap_get_alloc(cbm->bitmap, alloc);
    84169}
    85170
Note: See TracChangeset for help on using the changeset viewer.