present_screen.c revision ed6184df
135c4bbdfSmrg/* 235c4bbdfSmrg * Copyright © 2013 Keith Packard 335c4bbdfSmrg * 435c4bbdfSmrg * Permission to use, copy, modify, distribute, and sell this software and its 535c4bbdfSmrg * documentation for any purpose is hereby granted without fee, provided that 635c4bbdfSmrg * the above copyright notice appear in all copies and that both that copyright 735c4bbdfSmrg * notice and this permission notice appear in supporting documentation, and 835c4bbdfSmrg * that the name of the copyright holders not be used in advertising or 935c4bbdfSmrg * publicity pertaining to distribution of the software without specific, 1035c4bbdfSmrg * written prior permission. The copyright holders make no representations 1135c4bbdfSmrg * about the suitability of this software for any purpose. It is provided "as 1235c4bbdfSmrg * is" without express or implied warranty. 1335c4bbdfSmrg * 1435c4bbdfSmrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1535c4bbdfSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1635c4bbdfSmrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1735c4bbdfSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1835c4bbdfSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1935c4bbdfSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2035c4bbdfSmrg * OF THIS SOFTWARE. 2135c4bbdfSmrg */ 2235c4bbdfSmrg 2335c4bbdfSmrg#include "present_priv.h" 2435c4bbdfSmrg 2535c4bbdfSmrgint present_request; 2635c4bbdfSmrgDevPrivateKeyRec present_screen_private_key; 2735c4bbdfSmrgDevPrivateKeyRec present_window_private_key; 2835c4bbdfSmrg 2935c4bbdfSmrg/* 3035c4bbdfSmrg * Get a pointer to a present window private, creating if necessary 3135c4bbdfSmrg */ 3235c4bbdfSmrgpresent_window_priv_ptr 3335c4bbdfSmrgpresent_get_window_priv(WindowPtr window, Bool create) 3435c4bbdfSmrg{ 3535c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 3635c4bbdfSmrg 3735c4bbdfSmrg if (!create || window_priv != NULL) 3835c4bbdfSmrg return window_priv; 3935c4bbdfSmrg window_priv = calloc (1, sizeof (present_window_priv_rec)); 4035c4bbdfSmrg if (!window_priv) 4135c4bbdfSmrg return NULL; 4235c4bbdfSmrg xorg_list_init(&window_priv->vblank); 4335c4bbdfSmrg xorg_list_init(&window_priv->notifies); 441b5d61b8Smrg 451b5d61b8Smrg window_priv->window = window; 4635c4bbdfSmrg window_priv->crtc = PresentCrtcNeverSet; 4735c4bbdfSmrg dixSetPrivate(&window->devPrivates, &present_window_private_key, window_priv); 4835c4bbdfSmrg return window_priv; 4935c4bbdfSmrg} 5035c4bbdfSmrg 5135c4bbdfSmrg/* 5235c4bbdfSmrg * Hook the close screen function to clean up our screen private 5335c4bbdfSmrg */ 5435c4bbdfSmrgstatic Bool 5535c4bbdfSmrgpresent_close_screen(ScreenPtr screen) 5635c4bbdfSmrg{ 5735c4bbdfSmrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 5835c4bbdfSmrg 59ed6184dfSmrg if (screen_priv->flip_destroy) 60ed6184dfSmrg screen_priv->flip_destroy(screen); 6135c4bbdfSmrg 6235c4bbdfSmrg unwrap(screen_priv, screen, CloseScreen); 6335c4bbdfSmrg (*screen->CloseScreen) (screen); 6435c4bbdfSmrg free(screen_priv); 6535c4bbdfSmrg return TRUE; 6635c4bbdfSmrg} 6735c4bbdfSmrg 6835c4bbdfSmrg/* 6935c4bbdfSmrg * Free any queued presentations for this window 7035c4bbdfSmrg */ 7135c4bbdfSmrgstatic void 7235c4bbdfSmrgpresent_free_window_vblank(WindowPtr window) 7335c4bbdfSmrg{ 741b5d61b8Smrg ScreenPtr screen = window->drawable.pScreen; 751b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 7635c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 7735c4bbdfSmrg present_vblank_ptr vblank, tmp; 7835c4bbdfSmrg 7935c4bbdfSmrg xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) { 801b5d61b8Smrg screen_priv->abort_vblank(window->drawable.pScreen, window, vblank->crtc, vblank->event_id, vblank->target_msc); 8135c4bbdfSmrg present_vblank_destroy(vblank); 8235c4bbdfSmrg } 8335c4bbdfSmrg} 8435c4bbdfSmrg 8535c4bbdfSmrg/* 8635c4bbdfSmrg * Hook the close window function to clean up our window private 8735c4bbdfSmrg */ 8835c4bbdfSmrgstatic Bool 8935c4bbdfSmrgpresent_destroy_window(WindowPtr window) 9035c4bbdfSmrg{ 9135c4bbdfSmrg Bool ret; 9235c4bbdfSmrg ScreenPtr screen = window->drawable.pScreen; 9335c4bbdfSmrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 9435c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 9535c4bbdfSmrg 9635c4bbdfSmrg if (window_priv) { 9735c4bbdfSmrg present_clear_window_notifies(window); 9835c4bbdfSmrg present_free_events(window); 9935c4bbdfSmrg present_free_window_vblank(window); 1001b5d61b8Smrg 101ed6184dfSmrg screen_priv->clear_window_flip(window); 1021b5d61b8Smrg 10335c4bbdfSmrg free(window_priv); 10435c4bbdfSmrg } 10535c4bbdfSmrg unwrap(screen_priv, screen, DestroyWindow); 10635c4bbdfSmrg if (screen->DestroyWindow) 10735c4bbdfSmrg ret = screen->DestroyWindow (window); 10835c4bbdfSmrg else 10935c4bbdfSmrg ret = TRUE; 11035c4bbdfSmrg wrap(screen_priv, screen, DestroyWindow, present_destroy_window); 11135c4bbdfSmrg return ret; 11235c4bbdfSmrg} 11335c4bbdfSmrg 11435c4bbdfSmrg/* 11535c4bbdfSmrg * Hook the config notify screen function to deliver present config notify events 11635c4bbdfSmrg */ 11735c4bbdfSmrgstatic int 11835c4bbdfSmrgpresent_config_notify(WindowPtr window, 11935c4bbdfSmrg int x, int y, int w, int h, int bw, 12035c4bbdfSmrg WindowPtr sibling) 12135c4bbdfSmrg{ 12235c4bbdfSmrg int ret; 12335c4bbdfSmrg ScreenPtr screen = window->drawable.pScreen; 12435c4bbdfSmrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 12535c4bbdfSmrg 12635c4bbdfSmrg present_send_config_notify(window, x, y, w, h, bw, sibling); 12735c4bbdfSmrg 12835c4bbdfSmrg unwrap(screen_priv, screen, ConfigNotify); 12935c4bbdfSmrg if (screen->ConfigNotify) 13035c4bbdfSmrg ret = screen->ConfigNotify (window, x, y, w, h, bw, sibling); 13135c4bbdfSmrg else 13235c4bbdfSmrg ret = 0; 13335c4bbdfSmrg wrap(screen_priv, screen, ConfigNotify, present_config_notify); 13435c4bbdfSmrg return ret; 13535c4bbdfSmrg} 13635c4bbdfSmrg 13735c4bbdfSmrg/* 13835c4bbdfSmrg * Hook the clip notify screen function to un-flip as necessary 13935c4bbdfSmrg */ 14035c4bbdfSmrg 14135c4bbdfSmrgstatic void 14235c4bbdfSmrgpresent_clip_notify(WindowPtr window, int dx, int dy) 14335c4bbdfSmrg{ 14435c4bbdfSmrg ScreenPtr screen = window->drawable.pScreen; 14535c4bbdfSmrg present_screen_priv_ptr screen_priv = present_screen_priv(screen); 14635c4bbdfSmrg 1471b5d61b8Smrg screen_priv->check_flip_window(window); 14835c4bbdfSmrg unwrap(screen_priv, screen, ClipNotify) 14935c4bbdfSmrg if (screen->ClipNotify) 15035c4bbdfSmrg screen->ClipNotify (window, dx, dy); 15135c4bbdfSmrg wrap(screen_priv, screen, ClipNotify, present_clip_notify); 15235c4bbdfSmrg} 15335c4bbdfSmrg 154ed6184dfSmrgBool 1551b5d61b8Smrgpresent_screen_register_priv_keys(void) 15635c4bbdfSmrg{ 15735c4bbdfSmrg if (!dixRegisterPrivateKey(&present_screen_private_key, PRIVATE_SCREEN, 0)) 15835c4bbdfSmrg return FALSE; 15935c4bbdfSmrg 16035c4bbdfSmrg if (!dixRegisterPrivateKey(&present_window_private_key, PRIVATE_WINDOW, 0)) 16135c4bbdfSmrg return FALSE; 16235c4bbdfSmrg 1631b5d61b8Smrg return TRUE; 1641b5d61b8Smrg} 1651b5d61b8Smrg 166ed6184dfSmrgpresent_screen_priv_ptr 1671b5d61b8Smrgpresent_screen_priv_init(ScreenPtr screen) 1681b5d61b8Smrg{ 1691b5d61b8Smrg present_screen_priv_ptr screen_priv; 1701b5d61b8Smrg 1711b5d61b8Smrg screen_priv = calloc(1, sizeof (present_screen_priv_rec)); 1721b5d61b8Smrg if (!screen_priv) 1731b5d61b8Smrg return NULL; 1741b5d61b8Smrg 1751b5d61b8Smrg wrap(screen_priv, screen, CloseScreen, present_close_screen); 1761b5d61b8Smrg wrap(screen_priv, screen, DestroyWindow, present_destroy_window); 1771b5d61b8Smrg wrap(screen_priv, screen, ConfigNotify, present_config_notify); 1781b5d61b8Smrg wrap(screen_priv, screen, ClipNotify, present_clip_notify); 1791b5d61b8Smrg 1801b5d61b8Smrg dixSetPrivate(&screen->devPrivates, &present_screen_private_key, screen_priv); 1811b5d61b8Smrg 1821b5d61b8Smrg return screen_priv; 1831b5d61b8Smrg} 1841b5d61b8Smrg 1851b5d61b8Smrg/* 1861b5d61b8Smrg * Initialize a screen for use with present in default screen flip mode (scmd) 1871b5d61b8Smrg */ 1881b5d61b8Smrgint 1891b5d61b8Smrgpresent_screen_init(ScreenPtr screen, present_screen_info_ptr info) 1901b5d61b8Smrg{ 1911b5d61b8Smrg if (!present_screen_register_priv_keys()) 1921b5d61b8Smrg return FALSE; 1931b5d61b8Smrg 1941b5d61b8Smrg if (!present_screen_priv(screen)) { 1951b5d61b8Smrg present_screen_priv_ptr screen_priv = present_screen_priv_init(screen); 1961b5d61b8Smrg if (!screen_priv) 1971b5d61b8Smrg return FALSE; 1981b5d61b8Smrg 1991b5d61b8Smrg screen_priv->info = info; 2001b5d61b8Smrg present_scmd_init_mode_hooks(screen_priv); 20135c4bbdfSmrg 20235c4bbdfSmrg present_fake_screen_init(screen); 20335c4bbdfSmrg } 20435c4bbdfSmrg 20535c4bbdfSmrg return TRUE; 20635c4bbdfSmrg} 20735c4bbdfSmrg 20835c4bbdfSmrg/* 20935c4bbdfSmrg * Initialize the present extension 21035c4bbdfSmrg */ 21135c4bbdfSmrgvoid 21235c4bbdfSmrgpresent_extension_init(void) 21335c4bbdfSmrg{ 21435c4bbdfSmrg ExtensionEntry *extension; 21535c4bbdfSmrg int i; 21635c4bbdfSmrg 21735c4bbdfSmrg#ifdef PANORAMIX 21835c4bbdfSmrg if (!noPanoramiXExtension) 21935c4bbdfSmrg return; 22035c4bbdfSmrg#endif 22135c4bbdfSmrg 22235c4bbdfSmrg extension = AddExtension(PRESENT_NAME, PresentNumberEvents, PresentNumberErrors, 22335c4bbdfSmrg proc_present_dispatch, sproc_present_dispatch, 22435c4bbdfSmrg NULL, StandardMinorOpcode); 22535c4bbdfSmrg if (!extension) 22635c4bbdfSmrg goto bail; 22735c4bbdfSmrg 22835c4bbdfSmrg present_request = extension->base; 22935c4bbdfSmrg 23035c4bbdfSmrg if (!present_init()) 23135c4bbdfSmrg goto bail; 23235c4bbdfSmrg 23335c4bbdfSmrg if (!present_event_init()) 23435c4bbdfSmrg goto bail; 23535c4bbdfSmrg 23635c4bbdfSmrg for (i = 0; i < screenInfo.numScreens; i++) { 23735c4bbdfSmrg if (!present_screen_init(screenInfo.screens[i], NULL)) 23835c4bbdfSmrg goto bail; 23935c4bbdfSmrg } 24035c4bbdfSmrg return; 24135c4bbdfSmrg 24235c4bbdfSmrgbail: 24335c4bbdfSmrg FatalError("Cannot initialize Present extension"); 24435c4bbdfSmrg} 245