VirtualBox

Ignore:
Timestamp:
Jun 14, 2017 1:16:11 PM (8 years ago)
Author:
vboxsync
Message:

bugref:8524: Additions/linux: play nicely with distribution-installed Additions
Additions: linux/drm: Change vbox_mode.c to kernel coding style

This is the result of running linux/scripts/Lindent + manual cleanups.
After this the file passes linux/scripts/checkpatch -f
except for the LINUX_VERSION_CODE checks.

This patch contains no functional changes, only coding style fixes,
including changing uintXX_t types to uXX.

Signed-off-by: Hans de Goede <hdegoede@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/drm/vbox_mode.c

    r67175 r67404  
    4444#include <drm/drm_crtc_helper.h>
    4545#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
    46 # include <drm/drm_plane_helper.h>
     46#include <drm/drm_plane_helper.h>
    4747#endif
    4848
    4949static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
    50                             uint32_t handle, uint32_t width, uint32_t height,
    51                             int32_t hot_x, int32_t hot_y);
     50                            u32 handle, u32 width, u32 height,
     51                            s32 hot_x, s32 hot_y);
    5252static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
    5353
    54 /** Set a graphics mode.  Poke any required values into registers, do an HGSMI
     54/**
     55 * Set a graphics mode.  Poke any required values into registers, do an HGSMI
    5556 * mode set and tell the host we support advanced graphics functions.
    5657 */
    5758static void vbox_do_modeset(struct drm_crtc *crtc,
    58                             const struct drm_display_mode *mode)
    59 {
    60     struct vbox_crtc  *vbox_crtc = to_vbox_crtc(crtc);
    61     struct vbox_private *vbox;
    62     int width, height, bpp, pitch;
    63     unsigned crtc_id;
    64     uint16_t flags;
    65     int32_t x_offset, y_offset;
    66 
    67     vbox = crtc->dev->dev_private;
    68     width = mode->hdisplay ? mode->hdisplay : 640;
    69     height = mode->vdisplay ? mode->vdisplay : 480;
    70     crtc_id = vbox_crtc->crtc_id;
     59                            const struct drm_display_mode *mode)
     60{
     61        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     62        struct vbox_private *vbox;
     63        int width, height, bpp, pitch;
     64        unsigned int crtc_id;
     65        u16 flags;
     66        s32 x_offset, y_offset;
     67
     68        vbox = crtc->dev->dev_private;
     69        width = mode->hdisplay ? mode->hdisplay : 640;
     70        height = mode->vdisplay ? mode->vdisplay : 480;
     71        crtc_id = vbox_crtc->crtc_id;
    7172#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
    72     bpp  = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
    73     pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
     73        bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
     74        pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
    7475#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
    75     bpp  = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
    76     pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
     76        bpp = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
     77        pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
    7778#else
    78     bpp  = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
    79     pitch = crtc->enabled ? CRTC_FB(crtc)->pitch : width * bpp / 8;
     79        bpp = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
     80        pitch = crtc->enabled ? CRTC_FB(crtc)->pitch : width * bpp / 8;
    8081#endif
    81     x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
    82     y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
    83     /* This is the old way of setting graphics modes.  It assumed one screen
    84      * and a frame-buffer at the start of video RAM.  On older versions of
    85      * VirtualBox, certain parts of the code still assume that the first
    86      * screen is programmed this way, so try to fake it. */
    87     if (   vbox_crtc->crtc_id == 0
    88         && crtc->enabled
    89         && vbox_crtc->fb_offset / pitch < 0xffff - crtc->y
    90         && vbox_crtc->fb_offset % (bpp / 8) == 0)
    91         VBoxVideoSetModeRegisters(width, height, pitch * 8 / bpp,
     82        x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
     83        y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
     84
     85        /*
     86         * This is the old way of setting graphics modes.  It assumed one screen
     87         * and a frame-buffer at the start of video RAM.  On older versions of
     88         * VirtualBox, certain parts of the code still assume that the first
     89         * screen is programmed this way, so try to fake it.
     90         */
     91        if (vbox_crtc->crtc_id == 0 && crtc->enabled &&
     92            vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
     93            vbox_crtc->fb_offset % (bpp / 8) == 0)
     94                VBoxVideoSetModeRegisters(
     95                        width, height, pitch * 8 / bpp,
    9296#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
    93                           CRTC_FB(crtc)->format->cpp[0] * 8,
     97                        CRTC_FB(crtc)->format->cpp[0] * 8,
    9498#else
    95                           CRTC_FB(crtc)->bits_per_pixel,
     99                        CRTC_FB(crtc)->bits_per_pixel,
    96100#endif
    97                           0,
    98                           vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x,
    99                           vbox_crtc->fb_offset / pitch + crtc->y);
    100     flags = VBVA_SCREEN_F_ACTIVE;
    101     flags |= (crtc->enabled && !vbox_crtc->blanked ? 0 : VBVA_SCREEN_F_BLANK);
    102     flags |= (vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0);
    103     VBoxHGSMIProcessDisplayInfo(vbox->guest_pool, vbox_crtc->crtc_id,
    104                                 x_offset, y_offset,
    105                                 crtc->x * bpp / 8 + crtc->y * pitch,
    106                                 pitch, width, height,
    107                                 vbox_crtc->blanked ? 0 : bpp, flags);
     101                        0,
     102                        vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x,
     103                        vbox_crtc->fb_offset / pitch + crtc->y);
     104
     105        flags = VBVA_SCREEN_F_ACTIVE;
     106        flags |= (crtc->enabled && !vbox_crtc->blanked) ?
     107                 0 : VBVA_SCREEN_F_BLANK;
     108        flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
     109        VBoxHGSMIProcessDisplayInfo(vbox->guest_pool, vbox_crtc->crtc_id,
     110                                    x_offset, y_offset,
     111                                    crtc->x * bpp / 8 + crtc->y * pitch,
     112                                    pitch, width, height,
     113                                    vbox_crtc->blanked ? 0 : bpp, flags);
    108114}
    109115
    110116static int vbox_set_view(struct drm_crtc *crtc)
    111117{
    112     struct vbox_crtc   *vbox_crtc = to_vbox_crtc(crtc);
    113     struct vbox_private *vbox = crtc->dev->dev_private;
    114     void *p;
    115 
    116     /* Tell the host about the view.  This design originally targeted the
    117      * Windows XP driver architecture and assumed that each screen would have
    118      * a dedicated frame buffer with the command buffer following it, the whole
    119      * being a "view".  The host works out which screen a command buffer belongs
    120      * to by checking whether it is in the first view, then whether it is in the
    121      * second and so on.  The first match wins.  We cheat around this by making
    122      * the first view be the managed memory plus the first command buffer, the
    123      * second the same plus the second buffer and so on. */
    124     p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(VBVAINFOVIEW), HGSMI_CH_VBVA,
    125                              VBVA_INFO_VIEW);
    126     if (p)
    127     {
    128         VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
    129         pInfo->u32ViewIndex = vbox_crtc->crtc_id;
    130         pInfo->u32ViewOffset = vbox_crtc->fb_offset;
    131         pInfo->u32ViewSize =   vbox->available_vram_size - vbox_crtc->fb_offset
    132                              + vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
    133         pInfo->u32MaxScreenSize = vbox->available_vram_size - vbox_crtc->fb_offset;
    134         VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
    135         VBoxHGSMIBufferFree(vbox->guest_pool, p);
    136     }
    137     else
    138         return -ENOMEM;
    139     return 0;
     118        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     119        struct vbox_private *vbox = crtc->dev->dev_private;
     120        void *p;
     121
     122        /*
     123         * Tell the host about the view.  This design originally targeted the
     124         * Windows XP driver architecture and assumed that each screen would
     125         * have a dedicated frame buffer with the command buffer following it,
     126         * the whole being a "view".  The host works out which screen a command
     127         * buffer belongs to by checking whether it is in the first view, then
     128         * whether it is in the second and so on.  The first match wins.  We
     129         * cheat around this by making the first view be the managed memory
     130         * plus the first command buffer, the second the same plus the second
     131         * buffer and so on.
     132         */
     133        p = VBoxHGSMIBufferAlloc(vbox->guest_pool, sizeof(VBVAINFOVIEW),
     134                                 HGSMI_CH_VBVA, VBVA_INFO_VIEW);
     135        if (p) {
     136                VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *) p;
     137
     138                pInfo->u32ViewIndex = vbox_crtc->crtc_id;
     139                pInfo->u32ViewOffset = vbox_crtc->fb_offset;
     140                pInfo->u32ViewSize =
     141                    vbox->available_vram_size - vbox_crtc->fb_offset +
     142                    vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
     143                pInfo->u32MaxScreenSize =
     144                    vbox->available_vram_size - vbox_crtc->fb_offset;
     145                VBoxHGSMIBufferSubmit(vbox->guest_pool, p);
     146                VBoxHGSMIBufferFree(vbox->guest_pool, p);
     147        } else {
     148                return -ENOMEM;
     149        }
     150
     151        return 0;
    140152}
    141153
    142154static void vbox_crtc_load_lut(struct drm_crtc *crtc)
    143155{
    144 
    145156}
    146157
    147158static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
    148159{
    149     struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
    150     struct vbox_private *vbox = crtc->dev->dev_private;
    151 
    152     switch (mode) {
    153     case DRM_MODE_DPMS_ON:
    154         vbox_crtc->blanked = false;
    155         break;
    156     case DRM_MODE_DPMS_STANDBY:
    157     case DRM_MODE_DPMS_SUSPEND:
    158     case DRM_MODE_DPMS_OFF:
    159         vbox_crtc->blanked = true;
    160         break;
    161     }
    162     mutex_lock(&vbox->hw_mutex);
    163     vbox_do_modeset(crtc, &crtc->hwmode);
    164     mutex_unlock(&vbox->hw_mutex);
     160        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     161        struct vbox_private *vbox = crtc->dev->dev_private;
     162
     163        switch (mode) {
     164        case DRM_MODE_DPMS_ON:
     165                vbox_crtc->blanked = false;
     166                break;
     167        case DRM_MODE_DPMS_STANDBY:
     168        case DRM_MODE_DPMS_SUSPEND:
     169        case DRM_MODE_DPMS_OFF:
     170                vbox_crtc->blanked = true;
     171                break;
     172        }
     173
     174        mutex_lock(&vbox->hw_mutex);
     175        vbox_do_modeset(crtc, &crtc->hwmode);
     176        mutex_unlock(&vbox->hw_mutex);
    165177}
    166178
    167179static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
    168                 const struct drm_display_mode *mode,
    169                 struct drm_display_mode *adjusted_mode)
    170 {
    171     return true;
    172 }
    173 
    174 /* Try to map the layout of virtual screens to the range of the input device.
     180                                 const struct drm_display_mode *mode,
     181                                 struct drm_display_mode *adjusted_mode)
     182{
     183        return true;
     184}
     185
     186/*
     187 * Try to map the layout of virtual screens to the range of the input device.
    175188 * Return true if we need to re-set the crtc modes due to screen offset
    176  * changes. */
     189 * changes.
     190 */
    177191static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
    178192{
    179     struct drm_crtc *crtci;
    180     struct drm_connector *connectori;
    181     struct drm_framebuffer *fb1 = NULL;
    182     bool single_framebuffer = true;
    183     bool old_single_framebuffer = vbox->single_framebuffer;
    184     uint16_t width = 0, height = 0;
    185 
    186     /* Are we using an X.Org-style single large frame-buffer for all crtcs?
    187      * If so then screen layout can be deduced from the crtc offsets.
    188      * Same fall-back if this is the fbdev frame-buffer. */
    189     list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
    190         if (fb1 == NULL) {
    191             fb1 = CRTC_FB(crtci);
    192             if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
    193                 break;
    194         } else if (CRTC_FB(crtci) != NULL && fb1 != CRTC_FB(crtci))
    195             single_framebuffer = false;
    196     }
    197     if (single_framebuffer) {
    198         list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
    199             if (to_vbox_crtc(crtci)->crtc_id == 0) {
    200                 vbox->single_framebuffer = true;
    201                 vbox->input_mapping_width = CRTC_FB(crtci)->width;
    202                 vbox->input_mapping_height = CRTC_FB(crtci)->height;
    203                 return old_single_framebuffer != vbox->single_framebuffer;
    204             }
    205         }
    206     }
    207     /* Otherwise calculate the total span of all screens. */
    208     list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
    209                         head) {
    210         struct vbox_connector *vbox_connector = to_vbox_connector(connectori);
    211         struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
    212 
    213         width = max(width, (uint16_t) (vbox_crtc->x_hint +
    214                     vbox_connector->mode_hint.width));
    215         height = max(height, (uint16_t) (vbox_crtc->y_hint +
    216                     vbox_connector->mode_hint.height));
    217     }
    218     vbox->single_framebuffer = false;
    219     vbox->input_mapping_width = width;
    220     vbox->input_mapping_height = height;
    221     return old_single_framebuffer != vbox->single_framebuffer;
     193        struct drm_crtc *crtci;
     194        struct drm_connector *connectori;
     195        struct drm_framebuffer *fb1 = NULL;
     196        bool single_framebuffer = true;
     197        bool old_single_framebuffer = vbox->single_framebuffer;
     198        u16 width = 0, height = 0;
     199
     200        /*
     201         * Are we using an X.Org-style single large frame-buffer for all crtcs?
     202         * If so then screen layout can be deduced from the crtc offsets.
     203         * Same fall-back if this is the fbdev frame-buffer.
     204         */
     205        list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
     206                if (!fb1) {
     207                        fb1 = CRTC_FB(crtci);
     208                        if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
     209                                break;
     210                } else if (CRTC_FB(crtci) && fb1 != CRTC_FB(crtci)) {
     211                        single_framebuffer = false;
     212                }
     213        }
     214        if (single_framebuffer) {
     215                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
     216                                    head) {
     217                        if (to_vbox_crtc(crtci)->crtc_id == 0) {
     218                                vbox->single_framebuffer = true;
     219                                vbox->input_mapping_width =
     220                                    CRTC_FB(crtci)->width;
     221                                vbox->input_mapping_height =
     222                                    CRTC_FB(crtci)->height;
     223                                return old_single_framebuffer !=
     224                                    vbox->single_framebuffer;
     225                        }
     226                }
     227        }
     228        /* Otherwise calculate the total span of all screens. */
     229        list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
     230                            head) {
     231                struct vbox_connector *vbox_connector =
     232                    to_vbox_connector(connectori);
     233                struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
     234
     235                width = max_t(u16, width, vbox_crtc->x_hint +
     236                                          vbox_connector->mode_hint.width);
     237                height = max_t(u16, height, vbox_crtc->y_hint +
     238                                            vbox_connector->mode_hint.height);
     239        }
     240
     241        vbox->single_framebuffer = false;
     242        vbox->input_mapping_width = width;
     243        vbox->input_mapping_height = height;
     244
     245        return old_single_framebuffer != vbox->single_framebuffer;
    222246}
    223247
    224248static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
    225                 struct drm_framebuffer *old_fb,
    226                 int x, int y)
    227 {
    228     struct vbox_private *vbox = crtc->dev->dev_private;
    229     struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
    230     struct drm_gem_object *obj;
    231     struct vbox_framebuffer *vbox_fb;
    232     struct vbox_bo *bo;
    233     int ret;
    234     u64 gpu_addr;
    235 
    236     /* Unpin the previous fb. */
    237     if (old_fb) {
    238         vbox_fb = to_vbox_framebuffer(old_fb);
    239         obj = vbox_fb->obj;
    240         bo = gem_to_vbox_bo(obj);
    241         ret = vbox_bo_reserve(bo, false);
    242         if (ret)
    243             return ret;
    244         vbox_bo_unpin(bo);
    245         vbox_bo_unreserve(bo);
    246     }
    247 
    248     vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
    249     obj = vbox_fb->obj;
    250     bo = gem_to_vbox_bo(obj);
    251 
    252     ret = vbox_bo_reserve(bo, false);
    253     if (ret)
    254         return ret;
    255 
    256     ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
    257     if (ret) {
    258         vbox_bo_unreserve(bo);
    259         return ret;
    260     }
    261 
    262     if (&vbox->fbdev->afb == vbox_fb)
    263         vbox_fbdev_set_base(vbox, gpu_addr);
    264     vbox_bo_unreserve(bo);
    265 
    266     /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
    267     vbox_crtc->fb_offset = gpu_addr;
    268     if (vbox_set_up_input_mapping(vbox)) {
    269         struct drm_crtc *crtci;
    270 
    271         list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
    272             vbox_set_view(crtc);
    273             vbox_do_modeset(crtci, &crtci->mode);
    274         }
    275     }
    276     return 0;
     249                                 struct drm_framebuffer *old_fb, int x, int y)
     250{
     251        struct vbox_private *vbox = crtc->dev->dev_private;
     252        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     253        struct drm_gem_object *obj;
     254        struct vbox_framebuffer *vbox_fb;
     255        struct vbox_bo *bo;
     256        int ret;
     257        u64 gpu_addr;
     258
     259        /* Unpin the previous fb. */
     260        if (old_fb) {
     261                vbox_fb = to_vbox_framebuffer(old_fb);
     262                obj = vbox_fb->obj;
     263                bo = gem_to_vbox_bo(obj);
     264                ret = vbox_bo_reserve(bo, false);
     265                if (ret)
     266                        return ret;
     267
     268                vbox_bo_unpin(bo);
     269                vbox_bo_unreserve(bo);
     270        }
     271
     272        vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
     273        obj = vbox_fb->obj;
     274        bo = gem_to_vbox_bo(obj);
     275
     276        ret = vbox_bo_reserve(bo, false);
     277        if (ret)
     278                return ret;
     279
     280        ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
     281        if (ret) {
     282                vbox_bo_unreserve(bo);
     283                return ret;
     284        }
     285
     286        if (&vbox->fbdev->afb == vbox_fb)
     287                vbox_fbdev_set_base(vbox, gpu_addr);
     288        vbox_bo_unreserve(bo);
     289
     290        /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
     291        vbox_crtc->fb_offset = gpu_addr;
     292        if (vbox_set_up_input_mapping(vbox)) {
     293                struct drm_crtc *crtci;
     294
     295                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
     296                                    head) {
     297                        vbox_set_view(crtc);
     298                        vbox_do_modeset(crtci, &crtci->mode);
     299                }
     300        }
     301
     302        return 0;
    277303}
    278304
    279305static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
    280                  struct drm_framebuffer *old_fb)
    281 {
    282     return vbox_crtc_do_set_base(crtc, old_fb, x, y);
     306                                   struct drm_framebuffer *old_fb)
     307{
     308        return vbox_crtc_do_set_base(crtc, old_fb, x, y);
    283309}
    284310
    285311static int vbox_crtc_mode_set(struct drm_crtc *crtc,
    286                  struct drm_display_mode *mode,
    287                  struct drm_display_mode *adjusted_mode,
    288                  int x, int y,
    289                  struct drm_framebuffer *old_fb)
    290 {
    291     struct vbox_private *vbox = crtc->dev->dev_private;
    292     int rc = 0;
    293 
    294     vbox_crtc_mode_set_base(crtc, x, y, old_fb);
    295     mutex_lock(&vbox->hw_mutex);
    296     rc = vbox_set_view(crtc);
    297     if (!rc)
    298         vbox_do_modeset(crtc, mode);
    299     VBoxHGSMIUpdateInputMapping(vbox->guest_pool, 0, 0,
    300                                 vbox->input_mapping_width,
    301                                 vbox->input_mapping_height);
    302     mutex_unlock(&vbox->hw_mutex);
    303     return rc;
     312                              struct drm_display_mode *mode,
     313                              struct drm_display_mode *adjusted_mode,
     314                              int x, int y, struct drm_framebuffer *old_fb)
     315{
     316        struct vbox_private *vbox = crtc->dev->dev_private;
     317        int rc = 0;
     318
     319        vbox_crtc_mode_set_base(crtc, x, y, old_fb);
     320
     321        mutex_lock(&vbox->hw_mutex);
     322        rc = vbox_set_view(crtc);
     323        if (!rc)
     324                vbox_do_modeset(crtc, mode);
     325        VBoxHGSMIUpdateInputMapping(vbox->guest_pool, 0, 0,
     326                                    vbox->input_mapping_width,
     327                                    vbox->input_mapping_height);
     328        mutex_unlock(&vbox->hw_mutex);
     329
     330        return rc;
    304331}
    305332
    306333static void vbox_crtc_disable(struct drm_crtc *crtc)
    307334{
    308 
    309335}
    310336
    311337static void vbox_crtc_prepare(struct drm_crtc *crtc)
    312338{
    313 
    314339}
    315340
    316341static void vbox_crtc_commit(struct drm_crtc *crtc)
    317342{
    318 
    319 }
    320 
     343}
    321344
    322345static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
    323     .dpms = vbox_crtc_dpms,
    324     .mode_fixup = vbox_crtc_mode_fixup,
    325     .mode_set = vbox_crtc_mode_set,
    326     /* .mode_set_base = vbox_crtc_mode_set_base, */
    327     .disable = vbox_crtc_disable,
    328     .load_lut = vbox_crtc_load_lut,
    329     .prepare = vbox_crtc_prepare,
    330     .commit = vbox_crtc_commit,
    331 
     346        .dpms = vbox_crtc_dpms,
     347        .mode_fixup = vbox_crtc_mode_fixup,
     348        .mode_set = vbox_crtc_mode_set,
     349        /* .mode_set_base = vbox_crtc_mode_set_base, */
     350        .disable = vbox_crtc_disable,
     351        .load_lut = vbox_crtc_load_lut,
     352        .prepare = vbox_crtc_prepare,
     353        .commit = vbox_crtc_commit,
    332354};
    333355
    334356static void vbox_crtc_reset(struct drm_crtc *crtc)
    335357{
    336 
    337 }
    338 
     358}
    339359
    340360static void vbox_crtc_destroy(struct drm_crtc *crtc)
    341361{
    342     drm_crtc_cleanup(crtc);
    343     kfree(crtc);
     362        drm_crtc_cleanup(crtc);
     363        kfree(crtc);
    344364}
    345365
    346366static const struct drm_crtc_funcs vbox_crtc_funcs = {
    347     .cursor_move = vbox_cursor_move,
    348     .cursor_set2 = vbox_cursor_set2,
    349     .reset = vbox_crtc_reset,
    350     .set_config = drm_crtc_helper_set_config,
    351     /* .gamma_set = vbox_crtc_gamma_set, */
    352     .destroy = vbox_crtc_destroy,
     367        .cursor_move = vbox_cursor_move,
     368        .cursor_set2 = vbox_cursor_set2,
     369        .reset = vbox_crtc_reset,
     370        .set_config = drm_crtc_helper_set_config,
     371        /* .gamma_set = vbox_crtc_gamma_set, */
     372        .destroy = vbox_crtc_destroy,
    353373};
    354374
    355 static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned i)
    356 {
    357     struct vbox_crtc *vbox_crtc;
    358 
    359     vbox_crtc = kzalloc(sizeof(struct vbox_crtc), GFP_KERNEL);
    360     if (!vbox_crtc)
    361         return NULL;
    362     vbox_crtc->crtc_id = i;
    363 
    364     drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
    365     drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
    366     drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
    367 
    368     return vbox_crtc;
     375static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
     376{
     377        struct vbox_crtc *vbox_crtc;
     378
     379        vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
     380        if (!vbox_crtc)
     381                return NULL;
     382
     383        vbox_crtc->crtc_id = i;
     384
     385        drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
     386        drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
     387        drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
     388
     389        return vbox_crtc;
    369390}
    370391
    371392static void vbox_encoder_destroy(struct drm_encoder *encoder)
    372393{
    373     drm_encoder_cleanup(encoder);
    374     kfree(encoder);
     394        drm_encoder_cleanup(encoder);
     395        kfree(encoder);
    375396}
    376397
    377398#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
    378 static struct drm_encoder *drm_encoder_find(struct drm_device *dev, uint32_t id)
    379 {
    380      struct drm_mode_object *mo;
    381      mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
    382      return mo ? obj_to_encoder(mo) : NULL;
     399static struct drm_encoder *drm_encoder_find(struct drm_device *dev, u32 id)
     400{
     401        struct drm_mode_object *mo;
     402
     403        mo = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER);
     404        return mo ? obj_to_encoder(mo) : NULL;
    383405}
    384406#endif
    385407
    386 static struct drm_encoder *vbox_best_single_encoder(struct drm_connector *connector)
    387 {
    388     int enc_id = connector->encoder_ids[0];
    389 
    390     /* pick the encoder ids */
    391     if (enc_id)
    392         return drm_encoder_find(connector->dev, enc_id);
    393     return NULL;
    394 }
    395 
     408static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
     409                                                    *connector)
     410{
     411        int enc_id = connector->encoder_ids[0];
     412
     413        /* pick the encoder ids */
     414        if (enc_id)
     415                return drm_encoder_find(connector->dev, enc_id);
     416
     417        return NULL;
     418}
    396419
    397420static const struct drm_encoder_funcs vbox_enc_funcs = {
    398     .destroy = vbox_encoder_destroy,
     421        .destroy = vbox_encoder_destroy,
    399422};
    400423
    401424static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
    402425{
    403 
    404426}
    405427
    406428static bool vbox_mode_fixup(struct drm_encoder *encoder,
    407                const struct drm_display_mode *mode,
    408                struct drm_display_mode *adjusted_mode)
    409 {
    410     return true;
     429                            const struct drm_display_mode *mode,
     430                            struct drm_display_mode *adjusted_mode)
     431{
     432        return true;
    411433}
    412434
    413435static void vbox_encoder_mode_set(struct drm_encoder *encoder,
    414                    struct drm_display_mode *mode,
    415                    struct drm_display_mode *adjusted_mode)
     436                                  struct drm_display_mode *mode,
     437                                  struct drm_display_mode *adjusted_mode)
    416438{
    417439}
     
    419441static void vbox_encoder_prepare(struct drm_encoder *encoder)
    420442{
    421 
    422443}
    423444
    424445static void vbox_encoder_commit(struct drm_encoder *encoder)
    425446{
    426 
    427 }
    428 
     447}
    429448
    430449static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
    431     .dpms = vbox_encoder_dpms,
    432     .mode_fixup = vbox_mode_fixup,
    433     .prepare = vbox_encoder_prepare,
    434     .commit = vbox_encoder_commit,
    435     .mode_set = vbox_encoder_mode_set,
     450        .dpms = vbox_encoder_dpms,
     451        .mode_fixup = vbox_mode_fixup,
     452        .prepare = vbox_encoder_prepare,
     453        .commit = vbox_encoder_commit,
     454        .mode_set = vbox_encoder_mode_set,
    436455};
    437456
    438 static struct drm_encoder *vbox_encoder_init(struct drm_device *dev, unsigned i)
    439 {
    440     struct vbox_encoder *vbox_encoder;
    441 
    442     vbox_encoder = kzalloc(sizeof(struct vbox_encoder), GFP_KERNEL);
    443     if (!vbox_encoder)
    444         return NULL;
    445 
    446     drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
    447                      DRM_MODE_ENCODER_DAC
     457static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
     458                                             unsigned int i)
     459{
     460        struct vbox_encoder *vbox_encoder;
     461
     462        vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL);
     463        if (!vbox_encoder)
     464                return NULL;
     465
     466        drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
     467                         DRM_MODE_ENCODER_DAC
    448468#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
    449                     , NULL
     469                        , NULL
    450470#endif
    451                      );
    452     drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
    453 
    454     vbox_encoder->base.possible_crtcs = 1 << i;
    455     return &vbox_encoder->base;
    456 }
    457 
    458 /** Generate EDID data with a mode-unique serial number for the virtual
     471            );
     472        drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
     473
     474        vbox_encoder->base.possible_crtcs = 1 << i;
     475        return &vbox_encoder->base;
     476}
     477
     478/**
     479 * Generate EDID data with a mode-unique serial number for the virtual
    459480 *  monitor to try to persuade Unity that different modes correspond to
    460481 *  different monitors and it should not try to force the same resolution on
    461  *  them. */
     482 *  them.
     483 */
    462484static void vbox_set_edid(struct drm_connector *connector, int width,
    463                           int height)
    464 {
    465     enum { EDID_SIZE = 128 };
    466     unsigned char edid[EDID_SIZE] = {
    467         0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
    468         0x58, 0x58, /* manufacturer (VBX) */
    469         0x00, 0x00, /* product code */
    470         0x00, 0x00,0x00, 0x00, /* serial number goes here */
    471         0x01, /* week of manufacture */
    472         0x00, /* year of manufacture */
    473         0x01, 0x03, /* EDID version */
    474         0x80, /* capabilities - digital */
    475         0x00, /* horiz. res in cm, zero for projectors */
    476         0x00, /* vert. res in cm */
    477         0x78, /* display gamma (120 == 2.2). */
    478         0xEE, /* features (standby, suspend, off, RGB, standard colour space,
    479                * preferred timing mode) */
    480         0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
    481             /* chromaticity for standard colour space. */
    482         0x00, 0x00, 0x00, /* no default timings */
    483         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    484         0x01, 0x01, 0x01, 0x01, /* no standard timings */
    485         0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02, 0x02, 0x02,
    486         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
    487         0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
    488         0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
    489         0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
    490         0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
    491         'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
    492         0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
    493         0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    494         0x20,
    495         0x00, /* number of extensions */
    496         0x00 /* checksum goes here */
    497     };
    498     int clock = (width + 6) * (height + 6) * 60 / 10000;
    499     unsigned i;
    500     unsigned sum = 0;
    501 
    502     edid[12] = width & 0xff;
    503     edid[13] = width >> 8;
    504     edid[14] = height & 0xff;
    505     edid[15] = height >> 8;
    506     edid[54] = clock & 0xff;
    507     edid[55] = clock >> 8;
    508     edid[56] = width & 0xff;
    509     edid[58] = (width >> 4) & 0xf0;
    510     edid[59] = height & 0xff;
    511     edid[61] = (height >> 4) & 0xf0;
    512     for (i = 0; i < EDID_SIZE - 1; ++i)
    513         sum += edid[i];
    514     edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
    515     drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
     485                          int height)
     486{
     487        enum { EDID_SIZE = 128 };
     488        unsigned char edid[EDID_SIZE] = {
     489                0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
     490                0x58, 0x58,     /* manufacturer (VBX) */
     491                0x00, 0x00,     /* product code */
     492                0x00, 0x00, 0x00, 0x00, /* serial number goes here */
     493                0x01,           /* week of manufacture */
     494                0x00,           /* year of manufacture */
     495                0x01, 0x03,     /* EDID version */
     496                0x80,           /* capabilities - digital */
     497                0x00,           /* horiz. res in cm, zero for projectors */
     498                0x00,           /* vert. res in cm */
     499                0x78,           /* display gamma (120 == 2.2). */
     500                0xEE,           /* features (standby, suspend, off, RGB, std */
     501                                /* colour space, preferred timing mode) */
     502                0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
     503                /* chromaticity for standard colour space. */
     504                0x00, 0x00, 0x00,       /* no default timings */
     505                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
     506                    0x01, 0x01,
     507                0x01, 0x01, 0x01, 0x01, /* no standard timings */
     508                0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02,
     509                    0x02, 0x02,
     510                /* descriptor block 1 goes below */
     511                0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     512                /* descriptor block 2, monitor ranges */
     513                0x00, 0x00, 0x00, 0xFD, 0x00,
     514                0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20,
     515                    0x20, 0x20,
     516                /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
     517                0x20,
     518                /* descriptor block 3, monitor name */
     519                0x00, 0x00, 0x00, 0xFC, 0x00,
     520                'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r',
     521                '\n',
     522                /* descriptor block 4: dummy data */
     523                0x00, 0x00, 0x00, 0x10, 0x00,
     524                0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
     525                0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
     526                0x20,
     527                0x00,           /* number of extensions */
     528                0x00            /* checksum goes here */
     529        };
     530        int clock = (width + 6) * (height + 6) * 60 / 10000;
     531        unsigned int i, sum = 0;
     532
     533        edid[12] = width & 0xff;
     534        edid[13] = width >> 8;
     535        edid[14] = height & 0xff;
     536        edid[15] = height >> 8;
     537        edid[54] = clock & 0xff;
     538        edid[55] = clock >> 8;
     539        edid[56] = width & 0xff;
     540        edid[58] = (width >> 4) & 0xf0;
     541        edid[59] = height & 0xff;
     542        edid[61] = (height >> 4) & 0xf0;
     543        for (i = 0; i < EDID_SIZE - 1; ++i)
     544                sum += edid[i];
     545        edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
     546        drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
    516547}
    517548
    518549static int vbox_get_modes(struct drm_connector *connector)
    519550{
    520     struct vbox_connector *vbox_connector = NULL;
    521     struct drm_display_mode *mode = NULL;
    522     struct vbox_private *vbox = NULL;
    523     unsigned num_modes = 0;
    524     int preferred_width, preferred_height;
    525 
    526     vbox_connector = to_vbox_connector(connector);
    527     vbox = connector->dev->dev_private;
    528     /* Heuristic: we do not want to tell the host that we support dynamic
    529      * resizing unless we feel confident that the user space client using
    530      * the video driver can handle hot-plug events.  So the first time modes
    531      * are queried after a "master" switch we tell the host that we do not,
    532      * and immediately after we send the client a hot-plug notification as
    533      * a test to see if they will respond and query again.
    534      * That is also the reason why capabilities are reported to the host at
    535      * this place in the code rather than elsewhere.
    536      * We need to report the flags location before reporting the IRQ
    537      * capability. */
    538     VBoxHGSMIReportFlagsLocation(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
    539                                                      HOST_FLAGS_OFFSET);
    540     if (vbox_connector->vbox_crtc->crtc_id == 0)
    541         vbox_report_caps(vbox);
    542     if (!vbox->initial_mode_queried) {
    543         if (vbox_connector->vbox_crtc->crtc_id == 0) {
    544             vbox->initial_mode_queried = true;
    545             vbox_report_hotplug(vbox);
    546         }
    547         return drm_add_modes_noedid(connector, 800, 600);
    548     }
    549     num_modes = drm_add_modes_noedid(connector, 2560, 1600);
    550     preferred_width = vbox_connector->mode_hint.width ? vbox_connector->mode_hint.width : 1024;
    551     preferred_height = vbox_connector->mode_hint.height ? vbox_connector->mode_hint.height : 768;
    552     mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height, 60, false,
    553                          false, false);
    554     if (mode)
    555     {
    556         mode->type |= DRM_MODE_TYPE_PREFERRED;
    557         drm_mode_probed_add(connector, mode);
    558         ++num_modes;
    559     }
    560     vbox_set_edid(connector, preferred_width, preferred_height);
     551        struct vbox_connector *vbox_connector = NULL;
     552        struct drm_display_mode *mode = NULL;
     553        struct vbox_private *vbox = NULL;
     554        unsigned int num_modes = 0;
     555        int preferred_width, preferred_height;
     556
     557        vbox_connector = to_vbox_connector(connector);
     558        vbox = connector->dev->dev_private;
     559        /*
     560         * Heuristic: we do not want to tell the host that we support dynamic
     561         * resizing unless we feel confident that the user space client using
     562         * the video driver can handle hot-plug events.  So the first time modes
     563         * are queried after a "master" switch we tell the host that we do not,
     564         * and immediately after we send the client a hot-plug notification as
     565         * a test to see if they will respond and query again.
     566         * That is also the reason why capabilities are reported to the host at
     567         * this place in the code rather than elsewhere.
     568         * We need to report the flags location before reporting the IRQ
     569         * capability.
     570         */
     571        VBoxHGSMIReportFlagsLocation(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
     572                                     HOST_FLAGS_OFFSET);
     573        if (vbox_connector->vbox_crtc->crtc_id == 0)
     574                vbox_report_caps(vbox);
     575        if (!vbox->initial_mode_queried) {
     576                if (vbox_connector->vbox_crtc->crtc_id == 0) {
     577                        vbox->initial_mode_queried = true;
     578                        vbox_report_hotplug(vbox);
     579                }
     580                return drm_add_modes_noedid(connector, 800, 600);
     581        }
     582        num_modes = drm_add_modes_noedid(connector, 2560, 1600);
     583        preferred_width = vbox_connector->mode_hint.width ?
     584                          vbox_connector->mode_hint.width : 1024;
     585        preferred_height = vbox_connector->mode_hint.height ?
     586                           vbox_connector->mode_hint.height : 768;
     587        mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height,
     588                            60, false, false, false);
     589        if (mode) {
     590                mode->type |= DRM_MODE_TYPE_PREFERRED;
     591                drm_mode_probed_add(connector, mode);
     592                ++num_modes;
     593        }
     594        vbox_set_edid(connector, preferred_width, preferred_height);
    561595#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
    562     drm_object_property_set_value(&connector->base,
    563         vbox->dev->mode_config.suggested_x_property,
    564         vbox_connector->vbox_crtc->x_hint);
    565     drm_object_property_set_value(&connector->base,
    566         vbox->dev->mode_config.suggested_y_property,
    567         vbox_connector->vbox_crtc->y_hint);
     596        drm_object_property_set_value(
     597                &connector->base, vbox->dev->mode_config.suggested_x_property,
     598                vbox_connector->vbox_crtc->x_hint);
     599        drm_object_property_set_value(
     600                &connector->base, vbox->dev->mode_config.suggested_y_property,
     601                vbox_connector->vbox_crtc->y_hint);
    568602#endif
    569     return num_modes;
     603
     604        return num_modes;
    570605}
    571606
    572607static int vbox_mode_valid(struct drm_connector *connector,
    573               struct drm_display_mode *mode)
    574 {
    575     return MODE_OK;
     608                           struct drm_display_mode *mode)
     609{
     610        return MODE_OK;
    576611}
    577612
    578613static void vbox_connector_destroy(struct drm_connector *connector)
    579614{
    580     struct vbox_connector *vbox_connector = NULL;
    581 
    582     vbox_connector = to_vbox_connector(connector);
     615        struct vbox_connector *vbox_connector = NULL;
     616
     617        vbox_connector = to_vbox_connector(connector);
    583618#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
    584     drm_sysfs_connector_remove(connector);
     619        drm_sysfs_connector_remove(connector);
    585620#else
    586     drm_connector_unregister(connector);
     621        drm_connector_unregister(connector);
    587622#endif
    588     drm_connector_cleanup(connector);
    589     kfree(connector);
     623        drm_connector_cleanup(connector);
     624        kfree(connector);
    590625}
    591626
     
    593628vbox_connector_detect(struct drm_connector *connector, bool force)
    594629{
    595     struct vbox_connector *vbox_connector = NULL;
    596 
    597     (void) force;
    598     vbox_connector = to_vbox_connector(connector);
    599     return vbox_connector->mode_hint.disconnected ?
    600                 connector_status_disconnected : connector_status_connected;
    601 }
    602 
    603 static int vbox_fill_modes(struct drm_connector *connector, uint32_t max_x, uint32_t max_y)
    604 {
    605     struct vbox_connector *vbox_connector;
    606     struct drm_device *dev;
    607     struct drm_display_mode *mode, *iterator;
    608 
    609     vbox_connector = to_vbox_connector(connector);
    610     dev = vbox_connector->base.dev;
    611     list_for_each_entry_safe(mode, iterator, &connector->modes, head)
    612     {
    613         list_del(&mode->head);
    614         drm_mode_destroy(dev, mode);
    615     }
    616     return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
     630        struct vbox_connector *vbox_connector = NULL;
     631
     632        (void)force;
     633        vbox_connector = to_vbox_connector(connector);
     634
     635        return vbox_connector->mode_hint.disconnected ?
     636            connector_status_disconnected : connector_status_connected;
     637}
     638
     639static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
     640                           u32 max_y)
     641{
     642        struct vbox_connector *vbox_connector;
     643        struct drm_device *dev;
     644        struct drm_display_mode *mode, *iterator;
     645
     646        vbox_connector = to_vbox_connector(connector);
     647        dev = vbox_connector->base.dev;
     648        list_for_each_entry_safe(mode, iterator, &connector->modes, head) {
     649                list_del(&mode->head);
     650                drm_mode_destroy(dev, mode);
     651        }
     652
     653        return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
    617654}
    618655
    619656static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
    620     .mode_valid = vbox_mode_valid,
    621     .get_modes = vbox_get_modes,
    622     .best_encoder = vbox_best_single_encoder,
     657        .mode_valid = vbox_mode_valid,
     658        .get_modes = vbox_get_modes,
     659        .best_encoder = vbox_best_single_encoder,
    623660};
    624661
    625662static const struct drm_connector_funcs vbox_connector_funcs = {
    626     .dpms = drm_helper_connector_dpms,
    627     .detect = vbox_connector_detect,
    628     .fill_modes = vbox_fill_modes,
    629     .destroy = vbox_connector_destroy,
     663        .dpms = drm_helper_connector_dpms,
     664        .detect = vbox_connector_detect,
     665        .fill_modes = vbox_fill_modes,
     666        .destroy = vbox_connector_destroy,
    630667};
    631668
    632669static int vbox_connector_init(struct drm_device *dev,
    633                                struct vbox_crtc *vbox_crtc,
    634                                struct drm_encoder *encoder)
    635 {
    636     struct vbox_connector *vbox_connector;
    637     struct drm_connector *connector;
    638 
    639     vbox_connector = kzalloc(sizeof(struct vbox_connector), GFP_KERNEL);
    640     if (!vbox_connector)
    641         return -ENOMEM;
    642 
    643     connector = &vbox_connector->base;
    644     vbox_connector->vbox_crtc = vbox_crtc;
    645 
    646     drm_connector_init(dev, connector, &vbox_connector_funcs,
    647                        DRM_MODE_CONNECTOR_VGA);
    648     drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
    649 
    650     connector->interlace_allowed = 0;
    651     connector->doublescan_allowed = 0;
     670                               struct vbox_crtc *vbox_crtc,
     671                               struct drm_encoder *encoder)
     672{
     673        struct vbox_connector *vbox_connector;
     674        struct drm_connector *connector;
     675
     676        vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL);
     677        if (!vbox_connector)
     678                return -ENOMEM;
     679
     680        connector = &vbox_connector->base;
     681        vbox_connector->vbox_crtc = vbox_crtc;
     682
     683        drm_connector_init(dev, connector, &vbox_connector_funcs,
     684                           DRM_MODE_CONNECTOR_VGA);
     685        drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
     686
     687        connector->interlace_allowed = 0;
     688        connector->doublescan_allowed = 0;
    652689
    653690#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
    654     drm_mode_create_suggested_offset_properties(dev);
    655     drm_object_attach_property(&connector->base,
    656                                dev->mode_config.suggested_x_property, -1);
    657     drm_object_attach_property(&connector->base,
    658                                dev->mode_config.suggested_y_property, -1);
     691        drm_mode_create_suggested_offset_properties(dev);
     692        drm_object_attach_property(&connector->base,
     693                                   dev->mode_config.suggested_x_property, -1);
     694        drm_object_attach_property(&connector->base,
     695                                   dev->mode_config.suggested_y_property, -1);
    659696#endif
    660697#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
    661     drm_sysfs_connector_add(connector);
     698        drm_sysfs_connector_add(connector);
    662699#else
    663     drm_connector_register(connector);
     700        drm_connector_register(connector);
    664701#endif
    665702
    666     drm_mode_connector_attach_encoder(connector, encoder);
    667 
    668     return 0;
     703        drm_mode_connector_attach_encoder(connector, encoder);
     704
     705        return 0;
    669706}
    670707
    671708int vbox_mode_init(struct drm_device *dev)
    672709{
    673     struct vbox_private *vbox = dev->dev_private;
    674     struct drm_encoder *encoder;
    675     struct vbox_crtc *vbox_crtc;
    676     unsigned i;
    677     /* vbox_cursor_init(dev); */
    678     for (i = 0; i < vbox->num_crtcs; ++i)
    679     {
    680         vbox_crtc = vbox_crtc_init(dev, i);
    681         if (!vbox_crtc)
    682             return -ENOMEM;
    683         encoder = vbox_encoder_init(dev, i);
    684         if (!encoder)
    685             return -ENOMEM;
    686         vbox_connector_init(dev, vbox_crtc, encoder);
    687     }
    688     return 0;
     710        struct vbox_private *vbox = dev->dev_private;
     711        struct drm_encoder *encoder;
     712        struct vbox_crtc *vbox_crtc;
     713        unsigned int i;
     714
     715        /* vbox_cursor_init(dev); */
     716        for (i = 0; i < vbox->num_crtcs; ++i) {
     717                vbox_crtc = vbox_crtc_init(dev, i);
     718                if (!vbox_crtc)
     719                        return -ENOMEM;
     720                encoder = vbox_encoder_init(dev, i);
     721                if (!encoder)
     722                        return -ENOMEM;
     723                vbox_connector_init(dev, vbox_crtc, encoder);
     724        }
     725
     726        return 0;
    689727}
    690728
    691729void vbox_mode_fini(struct drm_device *dev)
    692730{
    693     /* vbox_cursor_fini(dev); */
    694 }
    695 
    696 
    697 /** Copy the ARGB image and generate the mask, which is needed in case the host
    698  *  does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
    699  *  if the corresponding alpha value in the ARGB image is greater than 0xF0. */
    700 static void copy_cursor_image(u8 *src, u8 *dst, int width, int height,
    701                               size_t mask_size)
    702 {
    703     unsigned i, j;
    704     size_t line_size = (width + 7) / 8;
    705 
    706     memcpy(dst + mask_size, src, width * height * 4);
    707     for (i = 0; i < height; ++i)
    708         for (j = 0; j < width; ++j)
    709             if (((uint32_t *)src)[i * width + j] > 0xf0000000)
    710                 dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
     731        /* vbox_cursor_fini(dev); */
     732}
     733
     734/**
     735 * Copy the ARGB image and generate the mask, which is needed in case the host
     736 * does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
     737 * if the corresponding alpha value in the ARGB image is greater than 0xF0.
     738 */
     739static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
     740                              size_t mask_size)
     741{
     742        size_t line_size = (width + 7) / 8;
     743        u32 i, j;
     744
     745        memcpy(dst + mask_size, src, width * height * 4);
     746        for (i = 0; i < height; ++i)
     747                for (j = 0; j < width; ++j)
     748                        if (((u32 *)src)[i * width + j] > 0xf0000000)
     749                                dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
    711750}
    712751
    713752static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
    714                             uint32_t handle, uint32_t width, uint32_t height,
    715                             int32_t hot_x, int32_t hot_y)
    716 {
    717     struct vbox_private *vbox = crtc->dev->dev_private;
    718     struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
    719     struct drm_gem_object *obj;
    720     struct vbox_bo *bo;
    721     int ret, rc;
    722     struct ttm_bo_kmap_obj uobj_map;
    723     u8 *src;
    724     u8 *dst = NULL;
    725     u32 caps = 0;
    726     size_t data_size, mask_size;
    727     bool src_isiomem;
    728 
    729     /* Re-set this regularly as in 5.0.20 and earlier the information was lost
    730      * on save and restore. */
    731     VBoxHGSMIUpdateInputMapping(vbox->guest_pool, 0, 0,
    732                                 vbox->input_mapping_width,
    733                                 vbox->input_mapping_height);
    734     if (!handle) {
    735         bool cursor_enabled = false;
    736         struct drm_crtc *crtci;
    737 
    738         /* Hide cursor. */
    739         vbox_crtc->cursor_enabled = false;
    740         list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head)
    741             if (to_vbox_crtc(crtci)->cursor_enabled)
    742                 cursor_enabled = true;
    743         if (!cursor_enabled)
    744             VBoxHGSMIUpdatePointerShape(vbox->guest_pool, 0, 0, 0, 0, 0, NULL, 0);
    745         return 0;
    746     }
    747     vbox_crtc->cursor_enabled = true;
    748     if (   width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT
    749         || width == 0 || height == 0)
    750         return -EINVAL;
    751     rc = VBoxQueryConfHGSMI(vbox->guest_pool,
    752                             VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
    753     ret = rc == VINF_SUCCESS ? 0 : rc == VERR_NO_MEMORY ? -ENOMEM : -EINVAL;
    754     if (ret)
    755         return ret;
    756     if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE))
    757         /* -EINVAL means cursor_set2() not supported, -EAGAIN means
    758          * retry at once. */
    759         return -EBUSY;
     753                            u32 handle, u32 width, u32 height,
     754                            s32 hot_x, s32 hot_y)
     755{
     756        struct vbox_private *vbox = crtc->dev->dev_private;
     757        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
     758        struct drm_gem_object *obj;
     759        struct vbox_bo *bo;
     760        int ret, rc;
     761        struct ttm_bo_kmap_obj uobj_map;
     762        u8 *src;
     763        u8 *dst = NULL;
     764        u32 caps = 0;
     765        size_t data_size, mask_size;
     766        bool src_isiomem;
     767
     768        /*
     769         * Re-set this regularly as in 5.0.20 and earlier the information was
     770         * lost on save and restore.
     771         */
     772        VBoxHGSMIUpdateInputMapping(vbox->guest_pool, 0, 0,
     773                                    vbox->input_mapping_width,
     774                                    vbox->input_mapping_height);
     775        if (!handle) {
     776                bool cursor_enabled = false;
     777                struct drm_crtc *crtci;
     778
     779                /* Hide cursor. */
     780                vbox_crtc->cursor_enabled = false;
     781                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
     782                                    head)
     783                        if (to_vbox_crtc(crtci)->cursor_enabled)
     784                                cursor_enabled = true;
     785
     786                if (!cursor_enabled)
     787                        VBoxHGSMIUpdatePointerShape(vbox->guest_pool, 0, 0, 0,
     788                                                    0, 0, NULL, 0);
     789                return 0;
     790        }
     791        vbox_crtc->cursor_enabled = true;
     792        if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
     793            width == 0 || height == 0)
     794                return -EINVAL;
     795        rc = VBoxQueryConfHGSMI(vbox->guest_pool,
     796                                VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
     797        ret = rc == VINF_SUCCESS ? 0 : rc == VERR_NO_MEMORY ? -ENOMEM : -EINVAL;
     798        if (ret)
     799                return ret;
     800
     801        if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE))
     802                /*
     803                 * -EINVAL means cursor_set2() not supported, -EAGAIN means
     804                 * retry at once.
     805                 */
     806                return -EBUSY;
    760807
    761808#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
    762     obj = drm_gem_object_lookup(file_priv, handle);
     809        obj = drm_gem_object_lookup(file_priv, handle);
    763810#else
    764     obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
     811        obj = drm_gem_object_lookup(crtc->dev, file_priv, handle);
    765812#endif
    766     if (obj)
    767     {
    768         bo = gem_to_vbox_bo(obj);
    769         ret = vbox_bo_reserve(bo, false);
    770         if (!ret)
    771         {
    772             /* The mask must be calculated based on the alpha channel, one bit
    773              * per ARGB word, and must be 32-bit padded. */
    774             mask_size  = ((width + 7) / 8 * height + 3) & ~3;
    775             data_size = width * height * 4 + mask_size;
    776             vbox->cursor_hot_x = min((uint32_t)max(hot_x, 0), width);
    777             vbox->cursor_hot_y = min((uint32_t)max(hot_y, 0), height);
    778             vbox->cursor_width = width;
    779             vbox->cursor_height = height;
    780             vbox->cursor_data_size = data_size;
    781             dst = vbox->cursor_data;
    782             ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
    783             if (!ret)
    784             {
    785                 src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
    786                 if (!src_isiomem)
    787                 {
    788                     uint32_t flags =   VBOX_MOUSE_POINTER_VISIBLE
    789                                       | VBOX_MOUSE_POINTER_SHAPE
    790                                       | VBOX_MOUSE_POINTER_ALPHA;
    791                     copy_cursor_image(src, dst, width, height, mask_size);
    792                     rc = VBoxHGSMIUpdatePointerShape(vbox->guest_pool, flags,
    793                                                      vbox->cursor_hot_x,
    794                                                      vbox->cursor_hot_y,
    795                                                      width, height, dst,
    796                                                      data_size);
    797                     ret =   rc == VINF_SUCCESS ? 0
    798                           : rc == VERR_NO_MEMORY ? -ENOMEM
    799                           : rc == VERR_NOT_SUPPORTED ? -EBUSY
    800                           : -EINVAL;
    801                 }
    802                 else
    803                     DRM_ERROR("src cursor bo should be in main memory\n");
    804                 ttm_bo_kunmap(&uobj_map);
    805             }
    806             else
    807                 vbox->cursor_data_size = 0;
    808             vbox_bo_unreserve(bo);
    809         }
    810         drm_gem_object_unreference_unlocked(obj);
    811     }
    812     else
    813     {
    814         DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
    815         ret = -ENOENT;
    816     }
    817     return ret;
    818 }
    819 
    820 static int vbox_cursor_move(struct drm_crtc *crtc,
    821                int x, int y)
    822 {
    823     struct vbox_private *vbox = crtc->dev->dev_private;
    824     uint32_t flags =   VBOX_MOUSE_POINTER_VISIBLE
    825                       | VBOX_MOUSE_POINTER_SHAPE
    826                       | VBOX_MOUSE_POINTER_ALPHA;
    827     int32_t crtc_x = vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
    828     int32_t crtc_y = vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
    829     uint32_t host_x, host_y;
    830     uint32_t hot_x = 0;
    831     uint32_t hot_y = 0;
    832     int rc;
    833 
    834     /* We compare these to unsigned later and don't need to handle negative. */
    835     if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
    836         return 0;
    837     rc = VBoxHGSMICursorPosition(vbox->guest_pool, true, x + crtc_x,
    838                                  y + crtc_y, &host_x, &host_y);
    839     /* Work around a bug after save and restore in 5.0.20 and earlier. */
    840     if (RT_FAILURE(rc) || (host_x == 0 && host_y == 0))
    841         return   rc == VINF_SUCCESS ? 0
    842                : rc == VERR_NO_MEMORY ? -ENOMEM
    843                : -EINVAL;
    844     if (x + crtc_x < host_x)
    845         hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
    846     if (y + crtc_y < host_y)
    847         hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
    848     if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
    849         return 0;
    850     vbox->cursor_hot_x = hot_x;
    851     vbox->cursor_hot_y = hot_y;
    852     rc = VBoxHGSMIUpdatePointerShape(vbox->guest_pool, flags, hot_x, hot_y,
    853                                      vbox->cursor_width, vbox->cursor_height,
    854                                      vbox->cursor_data,
    855                                      vbox->cursor_data_size);
    856     return   rc == VINF_SUCCESS ? 0
    857            : rc == VERR_NO_MEMORY ? -ENOMEM
    858            : rc == VERR_NOT_SUPPORTED ? -EBUSY
    859            : -EINVAL;
    860 }
     813        if (obj) {
     814                bo = gem_to_vbox_bo(obj);
     815                ret = vbox_bo_reserve(bo, false);
     816                if (!ret) {
     817                        /*
     818                         * The mask must be calculated based on the alpha
     819                         * channel, one bit per ARGB word, and must be 32-bit
     820                         * padded.
     821                         */
     822                        mask_size = ((width + 7) / 8 * height + 3) & ~3;
     823                        data_size = width * height * 4 + mask_size;
     824                        vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
     825                        vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
     826                        vbox->cursor_width = width;
     827                        vbox->cursor_height = height;
     828                        vbox->cursor_data_size = data_size;
     829                        dst = vbox->cursor_data;
     830                        ret =
     831                            ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages,
     832                                        &uobj_map);
     833                        if (!ret) {
     834                                src =
     835                                    ttm_kmap_obj_virtual(&uobj_map,
     836                                                         &src_isiomem);
     837                                if (!src_isiomem) {
     838                                        u32 flags =
     839                                            VBOX_MOUSE_POINTER_VISIBLE |
     840                                            VBOX_MOUSE_POINTER_SHAPE |
     841                                            VBOX_MOUSE_POINTER_ALPHA;
     842                                        copy_cursor_image(src, dst, width,
     843                                                          height, mask_size);
     844                                        rc = VBoxHGSMIUpdatePointerShape(
     845                                                vbox->guest_pool, flags,
     846                                                vbox->cursor_hot_x,
     847                                                vbox->cursor_hot_y,
     848                                                width, height, dst, data_size);
     849                                        ret =
     850                                            rc == VINF_SUCCESS ? 0 : rc ==
     851                                            VERR_NO_MEMORY ? -ENOMEM : rc ==
     852                                            VERR_NOT_SUPPORTED ? -EBUSY :
     853                                            -EINVAL;
     854                                } else {
     855                                        DRM_ERROR("src cursor bo should be in main memory\n");
     856                                }
     857                                ttm_bo_kunmap(&uobj_map);
     858                        } else {
     859                                vbox->cursor_data_size = 0;
     860                        }
     861                        vbox_bo_unreserve(bo);
     862                }
     863                drm_gem_object_unreference_unlocked(obj);
     864        } else {
     865                DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
     866                ret = -ENOENT;
     867        }
     868
     869        return ret;
     870}
     871
     872static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
     873{
     874        struct vbox_private *vbox = crtc->dev->dev_private;
     875        u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
     876            VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
     877        s32 crtc_x =
     878            vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
     879        s32 crtc_y =
     880            vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
     881        u32 host_x, host_y;
     882        u32 hot_x = 0;
     883        u32 hot_y = 0;
     884        int rc;
     885
     886        /*
     887         * We compare these to unsigned later and don't
     888         * need to handle negative.
     889         */
     890        if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
     891                return 0;
     892
     893        rc = VBoxHGSMICursorPosition(vbox->guest_pool, true, x + crtc_x,
     894                                     y + crtc_y, &host_x, &host_y);
     895        /* Work around a bug after save and restore in 5.0.20 and earlier. */
     896        if (RT_FAILURE(rc) || (host_x == 0 && host_y == 0))
     897                return rc == VINF_SUCCESS ? 0
     898                    : rc == VERR_NO_MEMORY ? -ENOMEM : -EINVAL;
     899        if (x + crtc_x < host_x)
     900                hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
     901        if (y + crtc_y < host_y)
     902                hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
     903        if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
     904                return 0;
     905        vbox->cursor_hot_x = hot_x;
     906        vbox->cursor_hot_y = hot_y;
     907        rc = VBoxHGSMIUpdatePointerShape(vbox->guest_pool, flags, hot_x, hot_y,
     908                                         vbox->cursor_width,
     909                                         vbox->cursor_height, vbox->cursor_data,
     910                                         vbox->cursor_data_size);
     911        return rc == VINF_SUCCESS ? 0 : rc == VERR_NO_MEMORY ? -ENOMEM : rc ==
     912            VERR_NOT_SUPPORTED ? -EBUSY : -EINVAL;
     913}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette