-static void qxl_fb_delayed_fillrect(struct qxl_fbdev *qfbdev,
- const struct fb_fillrect *fb_rect)
-{
- struct qxl_fb_op *op;
- unsigned long flags;
-
- op = kmalloc(sizeof(struct qxl_fb_op), GFP_ATOMIC | __GFP_NOWARN);
- if (!op)
- return;
-
- op->op.fr = *fb_rect;
- op->img_data = NULL;
- op->op_type = QXL_FB_OP_FILLRECT;
-
- spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
- list_add_tail(&op->head, &qfbdev->delayed_ops);
- spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
-}
-
-static void qxl_fb_delayed_copyarea(struct qxl_fbdev *qfbdev,
- const struct fb_copyarea *fb_copy)
-{
- struct qxl_fb_op *op;
- unsigned long flags;
-
- op = kmalloc(sizeof(struct qxl_fb_op), GFP_ATOMIC | __GFP_NOWARN);
- if (!op)
- return;
-
- op->op.ca = *fb_copy;
- op->img_data = NULL;
- op->op_type = QXL_FB_OP_COPYAREA;
-
- spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
- list_add_tail(&op->head, &qfbdev->delayed_ops);
- spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
-}
-
-static void qxl_fb_delayed_imageblit(struct qxl_fbdev *qfbdev,
- const struct fb_image *fb_image)
-{
- struct qxl_fb_op *op;
- unsigned long flags;
- uint32_t size = fb_image->width * fb_image->height * (fb_image->depth >= 8 ? fb_image->depth / 8 : 1);
-
- op = kmalloc(sizeof(struct qxl_fb_op) + size, GFP_ATOMIC | __GFP_NOWARN);
- if (!op)
- return;
-
- op->op.ib = *fb_image;
- op->img_data = (void *)(op + 1);
- op->op_type = QXL_FB_OP_IMAGEBLIT;
-
- memcpy(op->img_data, fb_image->data, size);
-
- op->op.ib.data = op->img_data;
- spin_lock_irqsave(&qfbdev->delayed_ops_lock, flags);
- list_add_tail(&op->head, &qfbdev->delayed_ops);
- spin_unlock_irqrestore(&qfbdev->delayed_ops_lock, flags);
-}
-
-static void qxl_fb_fillrect_internal(struct fb_info *info,
- const struct fb_fillrect *fb_rect)
-{
- struct qxl_fbdev *qfbdev = info->par;
- struct qxl_device *qdev = qfbdev->qdev;
- struct qxl_rect rect;
- uint32_t color;
- int x = fb_rect->dx;
- int y = fb_rect->dy;
- int width = fb_rect->width;
- int height = fb_rect->height;
- uint16_t rop;
- struct qxl_draw_fill qxl_draw_fill_rec;
-
- if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
- info->fix.visual == FB_VISUAL_DIRECTCOLOR)
- color = ((u32 *) (info->pseudo_palette))[fb_rect->color];
- else
- color = fb_rect->color;
- rect.left = x;
- rect.right = x + width;
- rect.top = y;
- rect.bottom = y + height;
- switch (fb_rect->rop) {
- case ROP_XOR:
- rop = SPICE_ROPD_OP_XOR;
- break;
- case ROP_COPY:
- rop = SPICE_ROPD_OP_PUT;
- break;
- default:
- pr_err("qxl_fb_fillrect(): unknown rop, "
- "defaulting to SPICE_ROPD_OP_PUT\n");
- rop = SPICE_ROPD_OP_PUT;
- }
- qxl_draw_fill_rec.qdev = qdev;
- qxl_draw_fill_rec.rect = rect;
- qxl_draw_fill_rec.color = color;
- qxl_draw_fill_rec.rop = rop;
-
- qxl_draw_fill(&qxl_draw_fill_rec);
-}
-