2 * Copyright © 2013 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 #ifdef HAVE_XORG_CONFIG_H
24 #include <xorg-config.h>
27 #include "present_priv.h"
30 DevPrivateKeyRec present_screen_private_key
;
31 DevPrivateKeyRec present_window_private_key
;
34 * Get a pointer to a present window private, creating if necessary
36 present_window_priv_ptr
37 present_get_window_priv(WindowPtr window
, Bool create
)
39 present_window_priv_ptr window_priv
= present_window_priv(window
);
41 if (!create
|| window_priv
!= NULL
)
43 window_priv
= calloc (1, sizeof (present_window_priv_rec
));
46 xorg_list_init(&window_priv
->vblank
);
47 xorg_list_init(&window_priv
->notifies
);
48 dixSetPrivate(&window
->devPrivates
, &present_window_private_key
, window_priv
);
53 * Hook the close screen function to clean up our screen private
56 present_close_screen(ScreenPtr screen
)
58 present_screen_priv_ptr screen_priv
= present_screen_priv(screen
);
60 present_flip_destroy(screen
);
62 unwrap(screen_priv
, screen
, CloseScreen
);
63 (*screen
->CloseScreen
) (screen
);
69 * Free any queued presentations for this window
72 present_free_window_vblank(WindowPtr window
)
74 present_window_priv_ptr window_priv
= present_window_priv(window
);
75 present_vblank_ptr vblank
, tmp
;
77 xorg_list_for_each_entry_safe(vblank
, tmp
, &window_priv
->vblank
, window_list
) {
78 present_abort_vblank(window
->drawable
.pScreen
, vblank
->crtc
, vblank
->event_id
, vblank
->target_msc
);
79 present_vblank_destroy(vblank
);
84 * Clean up any pending or current flips for this window
87 present_clear_window_flip(WindowPtr window
)
89 ScreenPtr screen
= window
->drawable
.pScreen
;
90 present_screen_priv_ptr screen_priv
= present_screen_priv(screen
);
91 present_vblank_ptr flip_pending
= screen_priv
->flip_pending
;
93 if (flip_pending
&& flip_pending
->window
== window
) {
94 assert (flip_pending
->abort_flip
);
95 flip_pending
->window
= NULL
;
97 if (screen_priv
->flip_window
== window
)
98 screen_priv
->flip_window
= NULL
;
102 * Hook the close window function to clean up our window private
105 present_destroy_window(WindowPtr window
)
108 ScreenPtr screen
= window
->drawable
.pScreen
;
109 present_screen_priv_ptr screen_priv
= present_screen_priv(screen
);
110 present_window_priv_ptr window_priv
= present_window_priv(window
);
113 present_clear_window_notifies(window
);
114 present_free_events(window
);
115 present_free_window_vblank(window
);
116 present_clear_window_flip(window
);
119 unwrap(screen_priv
, screen
, DestroyWindow
);
120 if (screen
->DestroyWindow
)
121 ret
= screen
->DestroyWindow (window
);
124 wrap(screen_priv
, screen
, DestroyWindow
, present_destroy_window
);
129 * Hook the config notify screen function to deliver present config notify events
132 present_config_notify(WindowPtr window
,
133 int x
, int y
, int w
, int h
, int bw
,
137 ScreenPtr screen
= window
->drawable
.pScreen
;
138 present_screen_priv_ptr screen_priv
= present_screen_priv(screen
);
140 present_send_config_notify(window
, x
, y
, w
, h
, bw
, sibling
);
142 unwrap(screen_priv
, screen
, ConfigNotify
);
143 if (screen
->ConfigNotify
)
144 ret
= screen
->ConfigNotify (window
, x
, y
, w
, h
, bw
, sibling
);
147 wrap(screen_priv
, screen
, ConfigNotify
, present_config_notify
);
152 * Hook the clip notify screen function to un-flip as necessary
156 present_clip_notify(WindowPtr window
, int dx
, int dy
)
158 ScreenPtr screen
= window
->drawable
.pScreen
;
159 present_screen_priv_ptr screen_priv
= present_screen_priv(screen
);
161 present_check_flip_window(window
);
162 unwrap(screen_priv
, screen
, ClipNotify
)
163 if (screen
->ClipNotify
)
164 screen
->ClipNotify (window
, dx
, dy
);
165 wrap(screen_priv
, screen
, ClipNotify
, present_clip_notify
);
169 * Initialize a screen for use with present
172 present_screen_init(ScreenPtr screen
, present_screen_info_ptr info
)
174 if (!dixRegisterPrivateKey(&present_screen_private_key
, PRIVATE_SCREEN
, 0))
177 if (!dixRegisterPrivateKey(&present_window_private_key
, PRIVATE_WINDOW
, 0))
180 if (!present_screen_priv(screen
)) {
181 present_screen_priv_ptr screen_priv
= calloc(1, sizeof (present_screen_priv_rec
));
185 wrap(screen_priv
, screen
, CloseScreen
, present_close_screen
);
186 wrap(screen_priv
, screen
, DestroyWindow
, present_destroy_window
);
187 wrap(screen_priv
, screen
, ConfigNotify
, present_config_notify
);
188 wrap(screen_priv
, screen
, ClipNotify
, present_clip_notify
);
190 screen_priv
->info
= info
;
192 dixSetPrivate(&screen
->devPrivates
, &present_screen_private_key
, screen_priv
);
194 present_fake_screen_init(screen
);
201 * Initialize the present extension
204 present_extension_init(void)
206 ExtensionEntry
*extension
;
210 if (!noPanoramiXExtension
)
214 extension
= AddExtension(PRESENT_NAME
, PresentNumberEvents
, PresentNumberErrors
,
215 proc_present_dispatch
, sproc_present_dispatch
,
216 NULL
, StandardMinorOpcode
);
220 present_request
= extension
->base
;
225 if (!present_event_init())
228 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
229 if (!present_screen_init(screenInfo
.screens
[i
], NULL
))
235 FatalError("Cannot initialize Present extension");