diff options
author | Eric Anholt <eric@anholt.net> | 2010-02-24 17:54:13 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-02-24 17:54:13 -0800 |
commit | 529bf185fbcb9f7705b315a5106054ee25c1c77f (patch) | |
tree | c56c4c106f8cca5882024825168799ccab927cb2 | |
parent | 633c7033170b0e9b468dbee444b94922f6c30940 (diff) | |
download | xf86-video-intel-529bf185fbcb9f7705b315a5106054ee25c1c77f.tar.gz xf86-video-intel-529bf185fbcb9f7705b315a5106054ee25c1c77f.tar.bz2 xf86-video-intel-529bf185fbcb9f7705b315a5106054ee25c1c77f.zip |
In frame event handling, track drawable id instead of drawable pointer.
Windows aren't refcounted, so if the event came in after the window
was destroyed, we'd dereference garbage and segfault.
-rw-r--r-- | src/i830_dri.c | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/src/i830_dri.c b/src/i830_dri.c index 028f9fd30..64aeb762d 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -394,7 +394,7 @@ enum DRI2FrameEventType { }; typedef struct _DRI2FrameEvent { - DrawablePtr pDraw; + XID drawable_id; ClientPtr client; enum DRI2FrameEventType type; int frame; @@ -472,7 +472,7 @@ I830DRI2ScheduleFlip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, if (!flip_info) return FALSE; - flip_info->pDraw = draw; + flip_info->drawable_id = draw->id; flip_info->client = client; flip_info->type = DRI2_SWAP; flip_info->event_complete = func; @@ -505,17 +505,29 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data) { DRI2FrameEventPtr event = event_data; - DrawablePtr pDraw = event->pDraw; - ScreenPtr screen = pDraw->pScreen; - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; - intel_screen_private *intel = intel_get_screen_private(scrn); + DrawablePtr drawable; + ScreenPtr screen; + ScrnInfoPtr scrn; + intel_screen_private *intel; + int status; + + status = dixLookupDrawable(&drawable, event->drawable_id, serverClient, + M_ANY, DixWriteAccess); + if (status != Success) { + xfree(event); + return; + } + + screen = drawable->pScreen; + scrn = xf86Screens[screen->myNum]; + intel = intel_get_screen_private(scrn); switch (event->type) { case DRI2_FLIP: /* If we can still flip... */ - if (DRI2CanFlip(pDraw) && !intel->shadow_present && + if (DRI2CanFlip(drawable) && !intel->shadow_present && intel->use_pageflipping && - I830DRI2ScheduleFlip(event->client, pDraw, event->front, + I830DRI2ScheduleFlip(event->client, drawable, event->front, event->back, event->event_complete, event->event_data)) { break; @@ -524,8 +536,8 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec, case DRI2_SWAP: { int swap_type; - if (DRI2CanExchange(pDraw)) { - I830DRI2ExchangeBuffers(pDraw, + if (DRI2CanExchange(drawable)) { + I830DRI2ExchangeBuffers(drawable, event->front, event->back); swap_type = DRI2_EXCHANGE_COMPLETE; } else { @@ -534,21 +546,21 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec, box.x1 = 0; box.y1 = 0; - box.x2 = pDraw->width; - box.y2 = pDraw->height; + box.x2 = drawable->width; + box.y2 = drawable->height; REGION_INIT(pScreen, ®ion, &box, 0); - I830DRI2CopyRegion(pDraw, + I830DRI2CopyRegion(drawable, ®ion, event->front, event->back); swap_type = DRI2_BLIT_COMPLETE; } - DRI2SwapComplete(event->client, pDraw, frame, tv_sec, tv_usec, + DRI2SwapComplete(event->client, drawable, frame, tv_sec, tv_usec, swap_type, event->event_complete, event->event_data); break; } case DRI2_WAITMSC: - DRI2WaitMSCComplete(event->client, pDraw, + DRI2WaitMSCComplete(event->client, drawable, frame, tv_sec, tv_usec); break; default: @@ -565,14 +577,25 @@ void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data) { DRI2FrameEventPtr flip = event_data; - DrawablePtr pDraw = flip->pDraw; - ScreenPtr screen = pDraw->pScreen; - ScrnInfoPtr scrn = xf86Screens[screen->myNum]; + DrawablePtr drawable; + ScreenPtr screen; + ScrnInfoPtr scrn; + int status; + + status = dixLookupDrawable(&drawable, flip->drawable_id, serverClient, + M_ANY, DixWriteAccess); + if (status != Success) { + xfree(flip); + return; + } + + screen = drawable->pScreen; + scrn = xf86Screens[screen->myNum]; /* We assume our flips arrive in order, so we don't check the frame */ switch (flip->type) { case DRI2_SWAP: - DRI2SwapComplete(flip->client, pDraw, frame, tv_sec, tv_usec, + DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec, DRI2_FLIP_COMPLETE, flip->event_complete, flip->event_data); break; @@ -641,7 +664,7 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, return TRUE; } - swap_info->pDraw = draw; + swap_info->drawable_id = draw->id; swap_info->client = client; swap_info->event_complete = func; swap_info->event_data = data; @@ -817,7 +840,7 @@ I830DRI2ScheduleWaitMSC(ClientPtr client, DrawablePtr draw, CARD64 target_msc, return TRUE; } - wait_info->pDraw = draw; + wait_info->drawable_id = draw->id; wait_info->client = client; wait_info->type = DRI2_WAITMSC; |