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 2535c4bbdfSmrgstatic RESTYPE present_event_type; 2635c4bbdfSmrg 2735c4bbdfSmrgstatic int 2835c4bbdfSmrgpresent_free_event(void *data, XID id) 2935c4bbdfSmrg{ 3035c4bbdfSmrg present_event_ptr present_event = (present_event_ptr) data; 3135c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(present_event->window); 3235c4bbdfSmrg present_event_ptr *previous, current; 3335c4bbdfSmrg 3435c4bbdfSmrg for (previous = &window_priv->events; (current = *previous); previous = ¤t->next) { 3535c4bbdfSmrg if (current == present_event) { 3635c4bbdfSmrg *previous = present_event->next; 3735c4bbdfSmrg break; 3835c4bbdfSmrg } 3935c4bbdfSmrg } 4035c4bbdfSmrg free((void *) present_event); 4135c4bbdfSmrg return 1; 4235c4bbdfSmrg 4335c4bbdfSmrg} 4435c4bbdfSmrg 4535c4bbdfSmrgvoid 4635c4bbdfSmrgpresent_free_events(WindowPtr window) 4735c4bbdfSmrg{ 4835c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 4935c4bbdfSmrg present_event_ptr event; 5035c4bbdfSmrg 5135c4bbdfSmrg if (!window_priv) 5235c4bbdfSmrg return; 5335c4bbdfSmrg 5435c4bbdfSmrg while ((event = window_priv->events)) 5535c4bbdfSmrg FreeResource(event->id, RT_NONE); 5635c4bbdfSmrg} 5735c4bbdfSmrg 5835c4bbdfSmrgstatic void 5935c4bbdfSmrgpresent_event_swap(xGenericEvent *from, xGenericEvent *to) 6035c4bbdfSmrg{ 6135c4bbdfSmrg *to = *from; 6235c4bbdfSmrg swaps(&to->sequenceNumber); 6335c4bbdfSmrg swapl(&to->length); 6435c4bbdfSmrg swaps(&to->evtype); 6535c4bbdfSmrg switch (from->evtype) { 6635c4bbdfSmrg case PresentConfigureNotify: { 6735c4bbdfSmrg xPresentConfigureNotify *c = (xPresentConfigureNotify *) to; 6835c4bbdfSmrg 6935c4bbdfSmrg swapl(&c->eid); 7035c4bbdfSmrg swapl(&c->window); 7135c4bbdfSmrg swaps(&c->x); 7235c4bbdfSmrg swaps(&c->y); 7335c4bbdfSmrg swaps(&c->width); 7435c4bbdfSmrg swaps(&c->height); 7535c4bbdfSmrg swaps(&c->off_x); 7635c4bbdfSmrg swaps(&c->off_y); 7735c4bbdfSmrg swaps(&c->pixmap_width); 7835c4bbdfSmrg swaps(&c->pixmap_height); 7935c4bbdfSmrg swapl(&c->pixmap_flags); 8035c4bbdfSmrg break; 8135c4bbdfSmrg } 8235c4bbdfSmrg case PresentCompleteNotify: 8335c4bbdfSmrg { 8435c4bbdfSmrg xPresentCompleteNotify *c = (xPresentCompleteNotify *) to; 8535c4bbdfSmrg swapl(&c->eid); 8635c4bbdfSmrg swapl(&c->window); 8735c4bbdfSmrg swapl(&c->serial); 8835c4bbdfSmrg swapll(&c->ust); 8935c4bbdfSmrg swapll(&c->msc); 901b5d61b8Smrg break; 9135c4bbdfSmrg } 9235c4bbdfSmrg case PresentIdleNotify: 9335c4bbdfSmrg { 9435c4bbdfSmrg xPresentIdleNotify *c = (xPresentIdleNotify *) to; 9535c4bbdfSmrg swapl(&c->eid); 9635c4bbdfSmrg swapl(&c->window); 9735c4bbdfSmrg swapl(&c->serial); 9835c4bbdfSmrg swapl(&c->idle_fence); 991b5d61b8Smrg break; 10035c4bbdfSmrg } 10135c4bbdfSmrg } 10235c4bbdfSmrg} 10335c4bbdfSmrg 10435c4bbdfSmrgvoid 105eee80088Smrgpresent_send_config_notify(WindowPtr window, int x, int y, int w, int h, 106eee80088Smrg int bw, WindowPtr sibling, CARD32 flags) 10735c4bbdfSmrg{ 10835c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 10935c4bbdfSmrg 11035c4bbdfSmrg if (window_priv) { 11135c4bbdfSmrg xPresentConfigureNotify cn = { 11235c4bbdfSmrg .type = GenericEvent, 11335c4bbdfSmrg .extension = present_request, 11435c4bbdfSmrg .length = (sizeof(xPresentConfigureNotify) - 32) >> 2, 11535c4bbdfSmrg .evtype = PresentConfigureNotify, 11635c4bbdfSmrg .eid = 0, 11735c4bbdfSmrg .window = window->drawable.id, 11835c4bbdfSmrg .x = x, 11935c4bbdfSmrg .y = y, 12035c4bbdfSmrg .width = w, 12135c4bbdfSmrg .height = h, 12235c4bbdfSmrg .off_x = 0, 12335c4bbdfSmrg .off_y = 0, 12435c4bbdfSmrg .pixmap_width = w, 12535c4bbdfSmrg .pixmap_height = h, 126eee80088Smrg .pixmap_flags = flags 12735c4bbdfSmrg }; 12835c4bbdfSmrg present_event_ptr event; 12935c4bbdfSmrg 13035c4bbdfSmrg for (event = window_priv->events; event; event = event->next) { 13135c4bbdfSmrg if (event->mask & (1 << PresentConfigureNotify)) { 13235c4bbdfSmrg cn.eid = event->id; 13335c4bbdfSmrg WriteEventsToClient(event->client, 1, (xEvent *) &cn); 13435c4bbdfSmrg } 13535c4bbdfSmrg } 13635c4bbdfSmrg } 13735c4bbdfSmrg} 13835c4bbdfSmrg 13935c4bbdfSmrgstatic present_complete_notify_proc complete_notify; 14035c4bbdfSmrg 14135c4bbdfSmrgvoid 14235c4bbdfSmrgpresent_register_complete_notify(present_complete_notify_proc proc) 14335c4bbdfSmrg{ 14435c4bbdfSmrg complete_notify = proc; 14535c4bbdfSmrg} 14635c4bbdfSmrg 14735c4bbdfSmrgvoid 14835c4bbdfSmrgpresent_send_complete_notify(WindowPtr window, CARD8 kind, CARD8 mode, CARD32 serial, uint64_t ust, uint64_t msc) 14935c4bbdfSmrg{ 15035c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 15135c4bbdfSmrg 15235c4bbdfSmrg if (window_priv) { 15335c4bbdfSmrg xPresentCompleteNotify cn = { 15435c4bbdfSmrg .type = GenericEvent, 15535c4bbdfSmrg .extension = present_request, 15635c4bbdfSmrg .length = (sizeof(xPresentCompleteNotify) - 32) >> 2, 15735c4bbdfSmrg .evtype = PresentCompleteNotify, 15835c4bbdfSmrg .kind = kind, 15935c4bbdfSmrg .mode = mode, 16035c4bbdfSmrg .eid = 0, 16135c4bbdfSmrg .window = window->drawable.id, 16235c4bbdfSmrg .serial = serial, 16335c4bbdfSmrg .ust = ust, 16435c4bbdfSmrg .msc = msc, 16535c4bbdfSmrg }; 16635c4bbdfSmrg present_event_ptr event; 16735c4bbdfSmrg 16835c4bbdfSmrg for (event = window_priv->events; event; event = event->next) { 16935c4bbdfSmrg if (event->mask & PresentCompleteNotifyMask) { 17035c4bbdfSmrg cn.eid = event->id; 17135c4bbdfSmrg WriteEventsToClient(event->client, 1, (xEvent *) &cn); 17235c4bbdfSmrg } 17335c4bbdfSmrg } 17435c4bbdfSmrg } 17535c4bbdfSmrg if (complete_notify) 17635c4bbdfSmrg (*complete_notify)(window, kind, mode, serial, ust, msc); 17735c4bbdfSmrg} 17835c4bbdfSmrg 17935c4bbdfSmrgvoid 18035c4bbdfSmrgpresent_send_idle_notify(WindowPtr window, CARD32 serial, PixmapPtr pixmap, struct present_fence *idle_fence) 18135c4bbdfSmrg{ 18235c4bbdfSmrg present_window_priv_ptr window_priv = present_window_priv(window); 18335c4bbdfSmrg 18435c4bbdfSmrg if (window_priv) { 18535c4bbdfSmrg xPresentIdleNotify in = { 18635c4bbdfSmrg .type = GenericEvent, 18735c4bbdfSmrg .extension = present_request, 18835c4bbdfSmrg .length = (sizeof(xPresentIdleNotify) - 32) >> 2, 18935c4bbdfSmrg .evtype = PresentIdleNotify, 19035c4bbdfSmrg .eid = 0, 19135c4bbdfSmrg .window = window->drawable.id, 19235c4bbdfSmrg .serial = serial, 19335c4bbdfSmrg .pixmap = pixmap->drawable.id, 19435c4bbdfSmrg .idle_fence = present_fence_id(idle_fence) 19535c4bbdfSmrg }; 19635c4bbdfSmrg present_event_ptr event; 19735c4bbdfSmrg 19835c4bbdfSmrg for (event = window_priv->events; event; event = event->next) { 19935c4bbdfSmrg if (event->mask & PresentIdleNotifyMask) { 20035c4bbdfSmrg in.eid = event->id; 20135c4bbdfSmrg WriteEventsToClient(event->client, 1, (xEvent *) &in); 20235c4bbdfSmrg } 20335c4bbdfSmrg } 20435c4bbdfSmrg } 20535c4bbdfSmrg} 20635c4bbdfSmrg 20735c4bbdfSmrgint 20835c4bbdfSmrgpresent_select_input(ClientPtr client, XID eid, WindowPtr window, CARD32 mask) 20935c4bbdfSmrg{ 2101b5d61b8Smrg present_window_priv_ptr window_priv; 21135c4bbdfSmrg present_event_ptr event; 2121b5d61b8Smrg int ret; 2131b5d61b8Smrg 2141b5d61b8Smrg /* Check to see if we're modifying an existing event selection */ 2151b5d61b8Smrg ret = dixLookupResourceByType((void **) &event, eid, present_event_type, 2161b5d61b8Smrg client, DixWriteAccess); 2171b5d61b8Smrg if (ret == Success) { 2181b5d61b8Smrg /* Match error for the wrong window; also don't modify some other 2191b5d61b8Smrg * client's event selection 2201b5d61b8Smrg */ 2211b5d61b8Smrg if (event->window != window || event->client != client) 2221b5d61b8Smrg return BadMatch; 22335c4bbdfSmrg 22435c4bbdfSmrg if (mask) 2251b5d61b8Smrg event->mask = mask; 2261b5d61b8Smrg else 2271b5d61b8Smrg FreeResource(eid, RT_NONE); 22835c4bbdfSmrg return Success; 22935c4bbdfSmrg } 2301b5d61b8Smrg if (ret != BadValue) 2311b5d61b8Smrg return ret; 2321b5d61b8Smrg 2331b5d61b8Smrg if (mask == 0) 2341b5d61b8Smrg return Success; 2351b5d61b8Smrg 2361b5d61b8Smrg LEGAL_NEW_RESOURCE(eid, client); 2371b5d61b8Smrg 2381b5d61b8Smrg window_priv = present_get_window_priv(window, TRUE); 2391b5d61b8Smrg if (!window_priv) 2401b5d61b8Smrg return BadAlloc; 24135c4bbdfSmrg 24235c4bbdfSmrg event = calloc (1, sizeof (present_event_rec)); 24335c4bbdfSmrg if (!event) 24435c4bbdfSmrg return BadAlloc; 24535c4bbdfSmrg 24635c4bbdfSmrg event->client = client; 24735c4bbdfSmrg event->window = window; 24835c4bbdfSmrg event->id = eid; 24935c4bbdfSmrg event->mask = mask; 25035c4bbdfSmrg 25135c4bbdfSmrg event->next = window_priv->events; 25235c4bbdfSmrg window_priv->events = event; 25335c4bbdfSmrg 25435c4bbdfSmrg if (!AddResource(event->id, present_event_type, (void *) event)) 25535c4bbdfSmrg return BadAlloc; 25635c4bbdfSmrg 25735c4bbdfSmrg return Success; 25835c4bbdfSmrg} 25935c4bbdfSmrg 26035c4bbdfSmrgBool 26135c4bbdfSmrgpresent_event_init(void) 26235c4bbdfSmrg{ 26335c4bbdfSmrg present_event_type = CreateNewResourceType(present_free_event, "PresentEvent"); 26435c4bbdfSmrg if (!present_event_type) 26535c4bbdfSmrg return FALSE; 26635c4bbdfSmrg 26735c4bbdfSmrg GERegisterExtension(present_request, present_event_swap); 26835c4bbdfSmrg return TRUE; 26935c4bbdfSmrg} 270