Subversion Repositories Kolibri OS

Rev

Rev 6296 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <drm/drmP.h>
  2. #include "i915_drv.h"
  3. #include "intel_drv.h"
  4. #include <syscall.h>
  5. #include <display.h>
  6.  
  7. static struct mutex cursor_lock;
  8.  
  9. static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
  10. {
  11.     struct drm_crtc *crtc = os_display->crtc;
  12.     struct drm_plane_state *cursor_state = crtc->cursor->state;
  13.  
  14.     x-= cursor->hot_x;
  15.     y-= cursor->hot_y;
  16.  
  17.     crtc->cursor_x = x;
  18.     crtc->cursor_y = y;
  19.  
  20.     cursor_state->crtc_x = x;
  21.     cursor_state->crtc_y = y;
  22.  
  23.     intel_crtc_update_cursor(crtc, 1);
  24. };
  25.  
  26. static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
  27. {
  28.     struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
  29.     struct drm_crtc   *crtc = os_display->crtc;
  30.     struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
  31.  
  32.     cursor_t *old;
  33.  
  34.     old = os_display->cursor;
  35.  
  36.     mutex_lock(&cursor_lock);
  37.  
  38.     os_display->cursor = cursor;
  39.  
  40.     if (!dev_priv->info.cursor_needs_physical)
  41.        intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
  42.     else
  43.         intel_crtc->cursor_addr = (addr_t)cursor->cobj;
  44.  
  45.     intel_crtc->base.cursor->state->crtc_w = 64;
  46.     intel_crtc->base.cursor->state->crtc_h = 64;
  47.     intel_crtc->base.cursor->state->rotation = 0;
  48.     mutex_unlock(&cursor_lock);
  49.  
  50.     move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y);
  51.     return old;
  52. };
  53.  
  54. static void __stdcall restore_cursor(int x, int y){};
  55. static void disable_mouse(void){};
  56.  
  57. static void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
  58. {
  59.     struct drm_i915_gem_object *obj = cursor->cobj;
  60.     list_del(&cursor->list);
  61.  
  62.     i915_gem_object_ggtt_unpin(cursor->cobj);
  63.  
  64.     mutex_lock(&main_device->struct_mutex);
  65.     drm_gem_object_unreference(&obj->base);
  66.     mutex_unlock(&main_device->struct_mutex);
  67.  
  68.     __DestroyObject(cursor);
  69. };
  70.  
  71. static int init_cursor(cursor_t *cursor)
  72. {
  73.     display_t *display = GetDisplay();
  74.     struct drm_i915_private *dev_priv = display->ddev->dev_private;
  75.     struct drm_i915_gem_object *obj;
  76.     uint32_t *bits;
  77.     uint32_t *src;
  78.     void     *mapped;
  79.  
  80.     int       i,j;
  81.     int       ret;
  82.  
  83.     if (dev_priv->info.cursor_needs_physical)
  84.     {
  85.         bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
  86.         if (unlikely(bits == NULL))
  87.             return ENOMEM;
  88.         cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
  89.     }
  90.     else
  91.     {
  92.         obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
  93.         if (unlikely(obj == NULL))
  94.             return -ENOMEM;
  95.  
  96.         ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
  97.         if (ret) {
  98.             drm_gem_object_unreference(&obj->base);
  99.             return ret;
  100.         }
  101.  
  102.         ret = i915_gem_object_set_to_gtt_domain(obj, true);
  103.         if (ret)
  104.         {
  105.             i915_gem_object_ggtt_unpin(obj);
  106.             drm_gem_object_unreference(&obj->base);
  107.             return ret;
  108.         }
  109. /* You don't need to worry about fragmentation issues.
  110.  * GTT space is continuous. I guarantee it.                           */
  111.  
  112.         mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
  113.                     KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
  114.  
  115.         if (unlikely(bits == NULL))
  116.         {
  117.             i915_gem_object_ggtt_unpin(obj);
  118.             drm_gem_object_unreference(&obj->base);
  119.             return -ENOMEM;
  120.         };
  121.         cursor->cobj = obj;
  122.     };
  123.  
  124.     src = cursor->data;
  125.  
  126.     for(i = 0; i < 32; i++)
  127.     {
  128.         for(j = 0; j < 32; j++)
  129.             *bits++ = *src++;
  130.         for(j = 32; j < KMS_CURSOR_WIDTH; j++)
  131.             *bits++ = 0;
  132.     }
  133.     for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
  134.         *bits++ = 0;
  135.  
  136.     FreeKernelSpace(mapped);
  137.     KernelFree(cursor->data);
  138.     cursor->data = bits;
  139.     cursor->header.destroy = destroy_cursor;
  140.  
  141.     return 0;
  142. }
  143.  
  144. void init_system_cursors(struct drm_device *dev)
  145. {
  146.     cursor_t  *cursor;
  147.     display_t *display;
  148.     u32      ifl;
  149.  
  150.     display = GetDisplay();
  151.  
  152.     mutex_init(&cursor_lock);
  153.     mutex_lock(&dev->struct_mutex);
  154.  
  155.     ifl = safe_cli();
  156.     {
  157.         list_for_each_entry(cursor, &display->cursors, list)
  158.         {
  159.             init_cursor(cursor);
  160.         };
  161.  
  162.         display->restore_cursor(0,0);
  163.         display->init_cursor    = init_cursor;
  164.         display->select_cursor  = select_cursor_kms;
  165.         display->show_cursor    = NULL;
  166.         display->move_cursor    = move_cursor_kms;
  167.         display->restore_cursor = restore_cursor;
  168.         display->disable_mouse  = disable_mouse;
  169.         display->crtc->cursor_x = display->width/2;
  170.         display->crtc->cursor_y = display->height/2;
  171.  
  172.         select_cursor_kms(display->cursor);
  173.     };
  174.     safe_sti(ifl);
  175.  
  176.     mutex_unlock(&dev->struct_mutex);
  177. }
  178.