static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,

                              int dir, int avg)

{

    int i, j, k, mx, my, dx, dy, x, y;

    const int part_width    = ((size & 5) == 4) ? 4 : 16 >> (size & 1);

    const int part_height   = 16 >> ((unsigned)(size + 1) / 3);

    const int extra_width   = (mode == PREDICT_MODE) ? -16 * 6 : 0;

    const int h_edge_pos    = 6 * (s->h_edge_pos - part_width)  - extra_width;

    const int v_edge_pos    = 6 * (s->v_edge_pos - part_height) - extra_width;

    for (i = 0; i < 16; i += part_height)

        for (j = 0; j < 16; j += part_width) {

            const int b_xy = (4 * s->mb_x + (j >> 2)) +

                             (4 * s->mb_y + (i >> 2)) * s->b_stride;

            int dxy;

            x = 16 * s->mb_x + j;

            y = 16 * s->mb_y + i;

            k = (j >> 2 & 1) + (i >> 1 & 2) +

                (j >> 1 & 4) + (i      & 8);

            if (mode != PREDICT_MODE) {

                svq3_pred_motion(s, k, part_width >> 2, dir, 1, &mx, &my);

            } else {

                mx = s->next_pic->motion_val[0][b_xy][0] << 1;

                my = s->next_pic->motion_val[0][b_xy][1] << 1;

                if (dir == 0) {

                    mx = mx * s->frame_num_offset /

                         s->prev_frame_num_offset + 1 >> 1;

                    my = my * s->frame_num_offset /

                         s->prev_frame_num_offset + 1 >> 1;

                } else {

                    mx = mx * (s->frame_num_offset - s->prev_frame_num_offset) /

                         s->prev_frame_num_offset + 1 >> 1;

                    my = my * (s->frame_num_offset - s->prev_frame_num_offset) /

                         s->prev_frame_num_offset + 1 >> 1;

                }

            }

            /* clip motion vector prediction to frame border */

            mx = av_clip(mx, extra_width - 6 * x, h_edge_pos - 6 * x);

            my = av_clip(my, extra_width - 6 * y, v_edge_pos - 6 * y);

            /* get (optional) motion vector differential */

            if (mode == PREDICT_MODE) {

                dx = dy = 0;

            } else {

                dy = get_interleaved_se_golomb(&s->gb_slice);

                dx = get_interleaved_se_golomb(&s->gb_slice);

                if (dx != (int16_t)dx || dy != (int16_t)dy) {

                    av_log(s->avctx, AV_LOG_ERROR, "invalid MV vlc\n");

                    return -1;

                }

            }

            /* compute motion vector */

            if (mode == THIRDPEL_MODE) {

                int fx, fy;

                mx  = (mx + 1 >> 1) + dx;

                my  = (my + 1 >> 1) + dy;

                fx  = (unsigned)(mx + 0x30000) / 3 - 0x10000;

                fy  = (unsigned)(my + 0x30000) / 3 - 0x10000;

                dxy = (mx - 3 * fx) + 4 * (my - 3 * fy);

                svq3_mc_dir_part(s, x, y, part_width, part_height,

                                 fx, fy, dxy, 1, dir, avg);

                mx += mx;

                my += my;

            } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) {

                mx  = (unsigned)(mx + 1 + 0x30000) / 3 + dx - 0x10000;

                my  = (unsigned)(my + 1 + 0x30000) / 3 + dy - 0x10000;

                dxy = (mx & 1) + 2 * (my & 1);

                svq3_mc_dir_part(s, x, y, part_width, part_height,

                                 mx >> 1, my >> 1, dxy, 0, dir, avg);

                mx *= 3;

                my *= 3;

            } else {

                mx = (unsigned)(mx + 3 + 0x60000) / 6 + dx - 0x10000;

                my = (unsigned)(my + 3 + 0x60000) / 6 + dy - 0x10000;

                svq3_mc_dir_part(s, x, y, part_width, part_height,

                                 mx, my, 0, 0, dir, avg);

                mx *= 6;

                my *= 6;

            }

            /* update mv_cache */

            if (mode != PREDICT_MODE) {

                int32_t mv = pack16to32(mx, my);

                if (part_height == 8 && i < 8) {

                    AV_WN32A(s->mv_cache[dir][scan8[k] + 1 * 8], mv);

                    if (part_width == 8 && j < 8)

                        AV_WN32A(s->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);

                }

                if (part_width == 8 && j < 8)

                    AV_WN32A(s->mv_cache[dir][scan8[k] + 1], mv);

                if (part_width == 4 || part_height == 4)

                    AV_WN32A(s->mv_cache[dir][scan8[k]], mv);

            }

            /* write back motion vectors */

            fill_rectangle(s->cur_pic->motion_val[dir][b_xy],

                           part_width >> 2, part_height >> 2, s->b_stride,

                           pack16to32(mx, my), 4);

        }

    return 0;

}


static void pxa2xx_update_display(void *opaque)

{

    struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;

    target_phys_addr_t fbptr;

    int miny, maxy;

    int ch;

    if (!(s->control[0] & LCCR0_ENB))

        return;

    pxa2xx_descriptor_load(s);

    pxa2xx_lcdc_resize(s);

    miny = s->yres;

    maxy = 0;

    s->transp = s->dma_ch[2].up || s->dma_ch[3].up;

    /* Note: With overlay planes the order depends on LCCR0 bit 25.  */

    for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++)

        if (s->dma_ch[ch].up) {

            if (!s->dma_ch[ch].source) {

                pxa2xx_dma_ber_set(s, ch);

                continue;

            }

            fbptr = s->dma_ch[ch].source;

            if (!(fbptr >= PXA2XX_SDRAM_BASE &&

                    fbptr <= PXA2XX_SDRAM_BASE + phys_ram_size)) {

                pxa2xx_dma_ber_set(s, ch);

                continue;

            }

            if (s->dma_ch[ch].command & LDCMD_PAL) {

                cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,

                    MAX(LDCMD_LENGTH(s->dma_ch[ch].command),

                        sizeof(s->dma_ch[ch].pbuffer)));

                pxa2xx_palette_parse(s, ch, s->bpp);

            } else {

                /* Do we need to reparse palette */

                if (LCCR4_PALFOR(s->control[4]) != s->pal_for)

                    pxa2xx_palette_parse(s, ch, s->bpp);

                /* ACK frame start */

                pxa2xx_dma_sof_set(s, ch);

                s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);

                s->invalidated = 0;

                /* ACK frame completed */

                pxa2xx_dma_eof_set(s, ch);

            }

        }

    if (s->control[0] & LCCR0_DIS) {

        /* ACK last frame completed */

        s->control[0] &= ~LCCR0_ENB;

        s->status[0] |= LCSR0_LDD;

    }

    if (miny >= 0) {

        if (s->orientation)

            dpy_update(s->ds, miny, 0, maxy, s->xres);

        else

            dpy_update(s->ds, 0, miny, s->xres, maxy);

    }

    pxa2xx_lcdc_int_update(s);

    qemu_irq_raise(s->vsync_cb);

}


char *object_property_print(Object *obj, const char *name, bool human,

                            Error **errp)

{

    StringOutputVisitor *sov;

    char *string = NULL;

    Error *local_err = NULL;

    sov = string_output_visitor_new(human);

    object_property_get(obj, string_output_get_visitor(sov), name, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        goto out;

    }

    string = string_output_get_string(sov);

out:

    visit_free(string_output_get_visitor(sov));

    return string;

}


static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h)

{

    vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_TIGHT);

    vnc_tight_start(vs);

    vnc_raw_send_framebuffer_update(vs, x, y, w, h);

    vnc_tight_stop(vs);

    return send_solid_rect(vs);

}


static void qdict_array_split_test(void)

{

    QDict *test_dict = qdict_new();

    QDict *dict1, *dict2;

    QList *test_list;

    /*

     * Test the split of

     *

     * {

     *     "1.x": 0,

     *     "3.y": 1,

     *     "0.a": 42,

     *     "o.o": 7,

     *     "0.b": 23

     * }

     *

     * to

     *

     * [

     *     {

     *         "a": 42,

     *         "b": 23

     *     },

     *     {

     *         "x": 0

     *     }

     * ]

     *

     * and

     *

     * {

     *     "3.y": 1,

     *     "o.o": 7

     * }

     *

     * (remaining in the old QDict)

     *

     * This example is given in the comment of qdict_array_split().

     */

    qdict_put(test_dict, "1.x", qint_from_int(0));

    qdict_put(test_dict, "3.y", qint_from_int(1));

    qdict_put(test_dict, "0.a", qint_from_int(42));

    qdict_put(test_dict, "o.o", qint_from_int(7));

    qdict_put(test_dict, "0.b", qint_from_int(23));

    qdict_array_split(test_dict, &test_list);

    dict1 = qobject_to_qdict(qlist_pop(test_list));

    dict2 = qobject_to_qdict(qlist_pop(test_list));

    g_assert(dict1);

    g_assert(dict2);

    g_assert(qlist_empty(test_list));

    QDECREF(test_list);

    g_assert(qdict_get_int(dict1, "a") == 42);

    g_assert(qdict_get_int(dict1, "b") == 23);

    g_assert(qdict_size(dict1) == 2);

    QDECREF(dict1);

    g_assert(qdict_get_int(dict2, "x") == 0);

    g_assert(qdict_size(dict2) == 1);

    QDECREF(dict2);

    g_assert(qdict_get_int(test_dict, "3.y") == 1);

    g_assert(qdict_get_int(test_dict, "o.o") == 7);

    g_assert(qdict_size(test_dict) == 2);

    QDECREF(test_dict);

}