xorg_crtc.c revision 54af54277a7a469ed2b9821ef6ed7ed464381f91
13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen/*
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * All Rights Reserved.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Permission is hereby granted, free of charge, to any person obtaining a
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * copy of this software and associated documentation files (the
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * "Software"), to deal in the Software without restriction, including
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * without limitation the rights to use, copy, modify, merge, publish,
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * distribute, sub license, and/or sell copies of the Software, and to
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * permit persons to whom the Software is furnished to do so, subject to
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * the following conditions:
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * The above copyright notice and this permission notice (including the
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * next paragraph) shall be included in all copies or substantial portions
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * of the Software.
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *
253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen *
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Author: Alan Hourihane <alanh@tungstengraphics.com>
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Author: Jakob Bornecrantz <wallbraker@gmail.com>
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <unistd.h>
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string.h>
333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <assert.h>
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <stdlib.h>
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <math.h>
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <stdint.h>
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "xorg-server.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <xf86.h>
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <xf86i2c.h>
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <xf86Crtc.h>
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <cursorstr.h>
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "xorg_tracker.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "xf86Modes.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef HAVE_XEXTPROTO_71
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <X11/extensions/dpmsconst.h>
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define DPMS_SERVER
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <X11/extensions/dpms.h>
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "util/u_inlines.h"
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "util/u_rect.h"
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef HAVE_LIBKMS
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "libkms.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct crtc_private
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeCrtcPtr drm_crtc;
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* hwcursor */
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct pipe_texture *cursor_tex;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct kms_bo *cursor_bo;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned cursor_handle;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstatic void
723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsencrtc_dpms(xf86CrtcPtr crtc, int mode)
733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen{
743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    /* ScrnInfoPtr pScrn = crtc->scrn; */
753f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    switch (mode) {
773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    case DPMSModeOn:
783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    case DPMSModeStandby:
793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    case DPMSModeSuspend:
803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	break;
813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    case DPMSModeOff:
823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	break;
833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen}
853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstatic Bool
873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsencrtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen		    Rotation rotation, int x, int y)
893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen{
903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    modesettingPtr ms = modesettingPTR(crtc->scrn);
923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    xf86OutputPtr output = NULL;
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    drmModeConnectorPtr drm_connector;
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    struct crtc_private *crtcp = crtc->driver_private;
953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drmModeModeInfo drm_mode;
973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    int i, ret;
983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    for (i = 0; i < config->num_output; output = NULL, i++) {
1003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	output = config->output[i];
1013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	if (output->crtc == crtc)
1033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	    break;
1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    }
1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!output)
1073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	return FALSE;
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_connector = output->driver_private;
1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.clock = mode->Clock;
1123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.hdisplay = mode->HDisplay;
1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.hsync_start = mode->HSyncStart;
1143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.hsync_end = mode->HSyncEnd;
1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.htotal = mode->HTotal;
1163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vdisplay = mode->VDisplay;
1173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vsync_start = mode->VSyncStart;
1183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vsync_end = mode->VSyncEnd;
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vtotal = mode->VTotal;
1203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.flags = mode->Flags;
1213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.hskew = mode->HSkew;
1223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vscan = mode->VScan;
1233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    drm_mode.vrefresh = mode->VRefresh;
1243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    if (!mode->name)
1253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	xf86SetModeDefaultName(mode);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch			 &drm_connector->connector_id, 1, &drm_mode);
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ret)
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	return FALSE;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    crtc->x = x;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    crtc->y = y;
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    crtc->mode = *mode;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    crtc->rotation = rotation;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return TRUE;
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	       int size)
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* XXX: hockup */
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void *
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* ScrnInfoPtr pScrn = crtc->scrn; */
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic PixmapPtr
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* ScrnInfoPtr pScrn = crtc->scrn; */
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickcrtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick{
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* ScrnInfoPtr pScrn = crtc->scrn; */
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick/*
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Cursor functions
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickcrtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick{
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    /* XXX: See if this one is needed, as we only support ARGB cursors */
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickcrtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned char *ptr;
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct pipe_transfer *transfer;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!crtcp->cursor_tex) {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	struct pipe_texture templat;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	unsigned pitch;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	memset(&templat, 0, sizeof(templat));
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.target = PIPE_TEXTURE_2D;
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.last_level = 0;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.depth0 = 1;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	templat.width0 = 64;
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	templat.height0 = 64;
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
2143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen						       &templat);
2153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	ms->api->local_handle_from_texture(ms->api,
2163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen					   ms->screen,
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					   crtcp->cursor_tex,
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					   &pitch,
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					   &crtcp->cursor_handle);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					    0, 0, 0,
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					    PIPE_TRANSFER_WRITE,
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch					    0, 0, 64, 64);
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ptr = ms->screen->transfer_map(ms->screen, transfer);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    util_copy_rect(ptr, crtcp->cursor_tex->format,
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch		   transfer->stride, 0, 0,
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch		   64, 64, (void*)image, 64 * 4, 0, 0);
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ms->screen->transfer_unmap(ms->screen, transfer);
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ms->screen->tex_transfer_destroy(transfer);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if HAVE_LIBKMS
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsencrtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen{
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unsigned char *ptr;
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!crtcp->cursor_bo) {
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	unsigned attr[8];
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[0] = KMS_BO_TYPE;
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#else
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen	attr[1] = KMS_BO_TYPE_CURSOR;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[2] = KMS_WIDTH;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[3] = 64;
2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick	attr[4] = KMS_HEIGHT;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[5] = 64;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	attr[6] = 0;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (kms_bo_create(ms->kms, attr, &crtcp->cursor_bo))
25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen	   return;
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen	if (kms_bo_get_prop(crtcp->cursor_bo, KMS_HANDLE,
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch			    &crtcp->cursor_handle))
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	    goto err_bo_destroy;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kms_bo_map(crtcp->cursor_bo, (void**)&ptr);
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    memcpy(ptr, image, 64*64*4);
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kms_bo_unmap(crtcp->cursor_bo);
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdocherr_bo_destroy:
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    kms_bo_destroy(&crtcp->cursor_bo);
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    /* Older X servers have cursor reference counting bugs leading to use of
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     * freed memory and consequently random crashes. Should be fixed as of
2843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen     * xserver 1.8, but this workaround shouldn't hurt anyway.
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     */
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (config->cursor)
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       config->cursor->refcnt++;
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ms->cursor)
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       FreeCursor(ms->cursor, None);
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ms->cursor = config->cursor;
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ms->screen)
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtc_load_cursor_argb_ga3d(crtc, image);
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifdef HAVE_LIBKMS
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else if (ms->kms)
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtc_load_cursor_argb_kms(crtc, image);
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_show_cursor(xf86CrtcPtr crtc)
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (crtcp->cursor_tex || crtcp->cursor_bo)
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch			 crtcp->cursor_handle, 64, 64);
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_hide_cursor(xf86CrtcPtr crtc)
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(crtc->scrn);
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    struct crtc_private *crtcp = crtc->driver_private;
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/**
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Called at vt leave
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochxorg_crtc_cursor_destroy(xf86CrtcPtr crtc)
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (crtcp->cursor_tex)
33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen	pipe_texture_reference(&crtcp->cursor_tex, NULL);
33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#ifdef HAVE_LIBKMS
33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (crtcp->cursor_bo)
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	kms_bo_destroy(&crtcp->cursor_bo);
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/*
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch * Misc functions
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch */
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochcrtc_destroy(xf86CrtcPtr crtc)
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp = crtc->driver_private;
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    xorg_crtc_cursor_destroy(crtc);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeFreeCrtc(crtcp->drm_crtc);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    xfree(crtcp);
3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    crtc->driver_private = NULL;
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const xf86CrtcFuncsRec crtc_funcs = {
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .dpms = crtc_dpms,
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .set_mode_major = crtc_set_mode_major,
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .set_cursor_colors = crtc_set_cursor_colors,
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .set_cursor_position = crtc_set_cursor_position,
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .show_cursor = crtc_show_cursor,
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .hide_cursor = crtc_hide_cursor,
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .load_cursor_argb = crtc_load_cursor_argb,
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .shadow_create = crtc_shadow_create,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .shadow_allocate = crtc_shadow_allocate,
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .shadow_destroy = crtc_shadow_destroy,
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .gamma_set = crtc_gamma_set,
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    .destroy = crtc_destroy,
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochxorg_crtc_init(ScrnInfoPtr pScrn)
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch{
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    modesettingPtr ms = modesettingPTR(pScrn);
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    xf86CrtcPtr crtc;
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeResPtr res;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeCrtcPtr drm_crtc = NULL;
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    struct crtc_private *crtcp;
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int c;
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    res = drmModeGetResources(ms->fd);
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (res == 0) {
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	ErrorF("Failed drmModeGetResources %d\n", errno);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	return;
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (c = 0; c < res->count_crtcs; c++) {
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]);
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	if (!drm_crtc)
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	    continue;
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtc = xf86CrtcCreate(pScrn, &crtc_funcs);
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	if (crtc == NULL)
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	    goto out;
3983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
3993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	crtcp = xcalloc(1, sizeof(struct crtc_private));
4003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	if (!crtcp) {
4013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen	    xf86CrtcDestroy(crtc);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	    goto out;
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	}
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtcp->drm_crtc = drm_crtc;
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch	crtc->driver_private = crtcp;
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  out:
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    drmModeFreeResources(res);
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch/* vim: set sw=4 ts=8 sts=4: */
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch