2 * Copyright 2012 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 * Copyright © 2002 Keith Packard
25 * Permission to use, copy, modify, distribute, and sell this software and its
26 * documentation for any purpose is hereby granted without fee, provided that
27 * the above copyright notice appear in all copies and that both that
28 * copyright notice and this permission notice appear in supporting
29 * documentation, and that the name of Keith Packard not be used in
30 * advertising or publicity pertaining to distribution of the software without
31 * specific, written prior permission. Keith Packard makes no
32 * representations about the suitability of this software for any purpose. It
33 * is provided "as is" without express or implied warranty.
35 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
36 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
37 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
38 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
39 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
40 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
41 * PERFORMANCE OF THIS SOFTWARE.
44 #ifdef HAVE_DIX_CONFIG_H
45 #include <dix-config.h>
48 #include "xibarriers.h"
49 #include "scrnintstr.h"
50 #include "cursorstr.h"
51 #include "dixevents.h"
53 #include "mipointer.h"
55 #include "windowstr.h"
58 #include "exglobals.h"
62 RESTYPE PointerBarrierType
;
64 static DevPrivateKeyRec BarrierScreenPrivateKeyRec
;
66 #define BarrierScreenPrivateKey (&BarrierScreenPrivateKeyRec)
68 typedef struct PointerBarrierClient
*PointerBarrierClientPtr
;
70 struct PointerBarrierDevice
{
71 struct xorg_list entry
;
80 struct PointerBarrierClient
{
84 struct PointerBarrier barrier
;
85 struct xorg_list entry
;
86 /* num_devices/device_ids are devices the barrier applies to */
88 int *device_ids
; /* num_devices */
90 /* per_device keeps track of devices actually blocked by barriers */
91 struct xorg_list per_device
;
94 typedef struct _BarrierScreen
{
95 struct xorg_list barriers
;
96 } BarrierScreenRec
, *BarrierScreenPtr
;
98 #define GetBarrierScreen(s) ((BarrierScreenPtr)dixLookupPrivate(&(s)->devPrivates, BarrierScreenPrivateKey))
99 #define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
100 #define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
102 static struct PointerBarrierDevice
*AllocBarrierDevice(void)
104 struct PointerBarrierDevice
*pbd
= NULL
;
106 pbd
= malloc(sizeof(struct PointerBarrierDevice
));
110 pbd
->deviceid
= -1; /* must be set by caller */
111 pbd
->barrier_event_id
= 1;
112 pbd
->release_event_id
= 0;
115 xorg_list_init(&pbd
->entry
);
120 static void FreePointerBarrierClient(struct PointerBarrierClient
*c
)
122 struct PointerBarrierDevice
*pbd
= NULL
, *tmp
= NULL
;
124 xorg_list_for_each_entry_safe(pbd
, tmp
, &c
->per_device
, entry
) {
130 static struct PointerBarrierDevice
*GetBarrierDevice(struct PointerBarrierClient
*c
, int deviceid
)
132 struct PointerBarrierDevice
*pbd
= NULL
;
134 xorg_list_for_each_entry(pbd
, &c
->per_device
, entry
) {
135 if (pbd
->deviceid
== deviceid
)
144 barrier_is_horizontal(const struct PointerBarrier
*barrier
)
146 return barrier
->y1
== barrier
->y2
;
150 barrier_is_vertical(const struct PointerBarrier
*barrier
)
152 return barrier
->x1
== barrier
->x2
;
156 * @return The set of barrier movement directions the movement vector
157 * x1/y1 → x2/y2 represents.
160 barrier_get_direction(int x1
, int y1
, int x2
, int y2
)
164 /* which way are we trying to go */
166 direction
|= BarrierPositiveX
;
168 direction
|= BarrierNegativeX
;
170 direction
|= BarrierPositiveY
;
172 direction
|= BarrierNegativeY
;
178 * Test if the barrier may block movement in the direction defined by
179 * x1/y1 → x2/y2. This function only tests whether the directions could be
180 * blocked, it does not test if the barrier actually blocks the movement.
182 * @return TRUE if the barrier blocks the direction of movement or FALSE
186 barrier_is_blocking_direction(const struct PointerBarrier
* barrier
,
189 /* Barriers define which way is ok, not which way is blocking */
190 return (barrier
->directions
& direction
) != direction
;
194 inside_segment(int v
, int v1
, int v2
)
196 if (v1
< 0 && v2
< 0) /* line */
198 else if (v1
< 0) /* ray */
200 else if (v2
< 0) /* ray */
202 else /* line segment */
203 return v
>= v1
&& v
<= v2
;
206 #define T(v, a, b) (((float)v) - (a)) / ((b) - (a))
207 #define F(t, a, b) ((t) * ((a) - (b)) + (a))
210 * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
211 * barrier. A movement vector with the startpoint or endpoint adjacent to
212 * the barrier itself counts as intersecting.
214 * @param x1 X start coordinate of movement vector
215 * @param y1 Y start coordinate of movement vector
216 * @param x2 X end coordinate of movement vector
217 * @param y2 Y end coordinate of movement vector
218 * @param[out] distance The distance between the start point and the
219 * intersection with the barrier (if applicable).
220 * @return TRUE if the barrier intersects with the given vector
223 barrier_is_blocking(const struct PointerBarrier
* barrier
,
224 int x1
, int y1
, int x2
, int y2
, double *distance
)
226 if (barrier_is_vertical(barrier
)) {
228 t
= T(barrier
->x1
, x1
, x2
);
232 /* Edge case: moving away from barrier. */
233 if (x2
> x1
&& t
== 0)
237 if (!inside_segment(y
, barrier
->y1
, barrier
->y2
))
240 *distance
= sqrt((pow(y
- y1
, 2) + pow(barrier
->x1
- x1
, 2)));
245 t
= T(barrier
->y1
, y1
, y2
);
249 /* Edge case: moving away from barrier. */
250 if (y2
> y1
&& t
== 0)
254 if (!inside_segment(x
, barrier
->x1
, barrier
->x2
))
257 *distance
= sqrt((pow(x
- x1
, 2) + pow(barrier
->y1
- y1
, 2)));
262 #define HIT_EDGE_EXTENTS 2
264 barrier_inside_hit_box(struct PointerBarrier
*barrier
, int x
, int y
)
273 dir
= ~(barrier
->directions
);
275 if (barrier_is_vertical(barrier
)) {
276 if (dir
& BarrierPositiveX
)
277 x1
-= HIT_EDGE_EXTENTS
;
278 if (dir
& BarrierNegativeX
)
279 x2
+= HIT_EDGE_EXTENTS
;
281 if (barrier_is_horizontal(barrier
)) {
282 if (dir
& BarrierPositiveY
)
283 y1
-= HIT_EDGE_EXTENTS
;
284 if (dir
& BarrierNegativeY
)
285 y2
+= HIT_EDGE_EXTENTS
;
288 return x
>= x1
&& x
<= x2
&& y
>= y1
&& y
<= y2
;
292 barrier_blocks_device(struct PointerBarrierClient
*client
,
298 /* Clients with no devices are treated as
299 * if they specified XIAllDevices. */
300 if (client
->num_devices
== 0)
303 master_id
= GetMaster(dev
, POINTER_OR_FLOAT
)->id
;
305 for (i
= 0; i
< client
->num_devices
; i
++) {
306 int device_id
= client
->device_ids
[i
];
307 if (device_id
== XIAllDevices
||
308 device_id
== XIAllMasterDevices
||
309 device_id
== master_id
)
317 * Find the nearest barrier client that is blocking movement from x1/y1 to x2/y2.
319 * @param dir Only barriers blocking movement in direction dir are checked
320 * @param x1 X start coordinate of movement vector
321 * @param y1 Y start coordinate of movement vector
322 * @param x2 X end coordinate of movement vector
323 * @param y2 Y end coordinate of movement vector
324 * @return The barrier nearest to the movement origin that blocks this movement.
326 static struct PointerBarrierClient
*
327 barrier_find_nearest(BarrierScreenPtr cs
, DeviceIntPtr dev
,
329 int x1
, int y1
, int x2
, int y2
)
331 struct PointerBarrierClient
*c
, *nearest
= NULL
;
332 double min_distance
= INT_MAX
; /* can't get higher than that in X anyway */
334 xorg_list_for_each_entry(c
, &cs
->barriers
, entry
) {
335 struct PointerBarrier
*b
= &c
->barrier
;
336 struct PointerBarrierDevice
*pbd
;
339 pbd
= GetBarrierDevice(c
, dev
->id
);
343 if (!barrier_is_blocking_direction(b
, dir
))
346 if (!barrier_blocks_device(c
, dev
))
349 if (barrier_is_blocking(b
, x1
, y1
, x2
, y2
, &distance
)) {
350 if (min_distance
> distance
) {
351 min_distance
= distance
;
361 * Clamp to the given barrier given the movement direction specified in dir.
363 * @param barrier The barrier to clamp to
364 * @param dir The movement direction
365 * @param[out] x The clamped x coordinate.
366 * @param[out] y The clamped x coordinate.
369 barrier_clamp_to_barrier(struct PointerBarrier
*barrier
, int dir
, int *x
,
372 if (barrier_is_vertical(barrier
)) {
373 if ((dir
& BarrierNegativeX
) & ~barrier
->directions
)
375 if ((dir
& BarrierPositiveX
) & ~barrier
->directions
)
376 *x
= barrier
->x1
- 1;
378 if (barrier_is_horizontal(barrier
)) {
379 if ((dir
& BarrierNegativeY
) & ~barrier
->directions
)
381 if ((dir
& BarrierPositiveY
) & ~barrier
->directions
)
382 *y
= barrier
->y1
- 1;
387 input_constrain_cursor(DeviceIntPtr dev
, ScreenPtr screen
,
388 int current_x
, int current_y
,
389 int dest_x
, int dest_y
,
390 int *out_x
, int *out_y
,
391 int *nevents
, InternalEvent
* events
)
393 /* Clamped coordinates here refer to screen edge clamping. */
394 BarrierScreenPtr cs
= GetBarrierScreen(screen
);
398 struct PointerBarrier
*nearest
= NULL
;
399 PointerBarrierClientPtr c
;
400 Time ms
= GetTimeInMillis();
402 .header
= ET_Internal
,
404 .length
= sizeof (BarrierEvent
),
408 .dx
= dest_x
- current_x
,
409 .dy
= dest_y
- current_y
,
410 .root
= screen
->root
->drawable
.id
,
412 InternalEvent
*barrier_events
= events
;
418 if (xorg_list_is_empty(&cs
->barriers
) || IsFloating(dev
))
422 * This function is only called for slave devices, but pointer-barriers
423 * are for master-devices only. Flip the device to the master here,
424 * continue with that.
426 master
= GetMaster(dev
, MASTER_POINTER
);
429 * Given the origin and the movement vector, get the nearest barrier
430 * to the origin that is blocking the movement.
431 * Clamp to that barrier.
432 * Then, check from the clamped intersection to the original
433 * destination, again finding the nearest barrier and clamping.
435 dir
= barrier_get_direction(current_x
, current_y
, x
, y
);
439 struct PointerBarrierDevice
*pbd
;
441 c
= barrier_find_nearest(cs
, master
, dir
, current_x
, current_y
, x
, y
);
445 nearest
= &c
->barrier
;
447 pbd
= GetBarrierDevice(c
, master
->id
);
448 new_sequence
= !pbd
->hit
;
453 if (pbd
->barrier_event_id
== pbd
->release_event_id
)
456 ev
.type
= ET_BarrierHit
;
457 barrier_clamp_to_barrier(nearest
, dir
, &x
, &y
);
459 if (barrier_is_vertical(nearest
)) {
460 dir
&= ~(BarrierNegativeX
| BarrierPositiveX
);
463 else if (barrier_is_horizontal(nearest
)) {
464 dir
&= ~(BarrierNegativeY
| BarrierPositiveY
);
469 ev
.event_id
= pbd
->barrier_event_id
;
470 ev
.barrierid
= c
->id
;
472 ev
.dt
= new_sequence
? 0 : ms
- pbd
->last_timestamp
;
473 ev
.window
= c
->window
;
474 pbd
->last_timestamp
= ms
;
476 /* root x/y is filled in later */
478 barrier_events
->barrier_event
= ev
;
483 xorg_list_for_each_entry(c
, &cs
->barriers
, entry
) {
484 struct PointerBarrierDevice
*pbd
;
487 pbd
= GetBarrierDevice(c
, master
->id
);
492 if (barrier_inside_hit_box(&c
->barrier
, x
, y
))
497 ev
.type
= ET_BarrierLeave
;
499 if (pbd
->barrier_event_id
== pbd
->release_event_id
)
500 flags
|= XIBarrierPointerReleased
;
503 ev
.event_id
= pbd
->barrier_event_id
;
504 ev
.barrierid
= c
->id
;
506 ev
.dt
= ms
- pbd
->last_timestamp
;
507 ev
.window
= c
->window
;
508 pbd
->last_timestamp
= ms
;
510 /* root x/y is filled in later */
512 barrier_events
->barrier_event
= ev
;
516 /* If we've left the hit box, this is the
517 * start of a new event ID. */
518 pbd
->barrier_event_id
++;
527 sort_min_max(INT16
*a
, INT16
*b
)
530 if (*a
< 0 || *b
< 0)
539 CreatePointerBarrierClient(ClientPtr client
,
540 xXFixesCreatePointerBarrierReq
* stuff
,
541 PointerBarrierClientPtr
*client_out
)
549 struct PointerBarrierClient
*ret
;
553 size
= sizeof(*ret
) + sizeof(DeviceIntPtr
) * stuff
->num_devices
;
560 xorg_list_init(&ret
->per_device
);
562 err
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixReadAccess
);
563 if (err
!= Success
) {
564 client
->errorValue
= stuff
->window
;
568 screen
= pWin
->drawable
.pScreen
;
569 cs
= GetBarrierScreen(screen
);
571 ret
->screen
= screen
;
572 ret
->window
= stuff
->window
;
573 ret
->num_devices
= stuff
->num_devices
;
574 if (ret
->num_devices
> 0)
575 ret
->device_ids
= (int*)&ret
[1];
577 ret
->device_ids
= NULL
;
579 in_devices
= (CARD16
*) &stuff
[1];
580 for (i
= 0; i
< stuff
->num_devices
; i
++) {
581 int device_id
= in_devices
[i
];
584 if ((err
= dixLookupDevice (&device
, device_id
,
585 client
, DixReadAccess
))) {
586 client
->errorValue
= device_id
;
590 if (!IsMaster (device
)) {
591 client
->errorValue
= device_id
;
596 ret
->device_ids
[i
] = device_id
;
599 /* Alloc one per master pointer, they're the ones that can be blocked */
600 xorg_list_init(&ret
->per_device
);
601 nt_list_for_each_entry(dev
, inputInfo
.devices
, next
) {
602 struct PointerBarrierDevice
*pbd
;
604 if (dev
->type
!= MASTER_POINTER
)
607 pbd
= AllocBarrierDevice();
612 pbd
->deviceid
= dev
->id
;
614 xorg_list_add(&pbd
->entry
, &ret
->per_device
);
617 ret
->id
= stuff
->barrier
;
618 ret
->barrier
.x1
= stuff
->x1
;
619 ret
->barrier
.x2
= stuff
->x2
;
620 ret
->barrier
.y1
= stuff
->y1
;
621 ret
->barrier
.y2
= stuff
->y2
;
622 sort_min_max(&ret
->barrier
.x1
, &ret
->barrier
.x2
);
623 sort_min_max(&ret
->barrier
.y1
, &ret
->barrier
.y2
);
624 ret
->barrier
.directions
= stuff
->directions
& 0x0f;
625 if (barrier_is_horizontal(&ret
->barrier
))
626 ret
->barrier
.directions
&= ~(BarrierPositiveX
| BarrierNegativeX
);
627 if (barrier_is_vertical(&ret
->barrier
))
628 ret
->barrier
.directions
&= ~(BarrierPositiveY
| BarrierNegativeY
);
629 xorg_list_add(&ret
->entry
, &cs
->barriers
);
636 FreePointerBarrierClient(ret
);
641 BarrierFreeBarrier(void *data
, XID id
)
643 struct PointerBarrierClient
*c
;
644 Time ms
= GetTimeInMillis();
645 DeviceIntPtr dev
= NULL
;
648 c
= container_of(data
, struct PointerBarrierClient
, barrier
);
651 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
652 struct PointerBarrierDevice
*pbd
;
655 .header
= ET_Internal
,
656 .type
= ET_BarrierLeave
,
657 .length
= sizeof (BarrierEvent
),
663 .root
= screen
->root
->drawable
.id
,
670 .flags
= XIBarrierPointerReleased
,
674 if (dev
->type
!= MASTER_POINTER
)
677 pbd
= GetBarrierDevice(c
, dev
->id
);
681 ev
.deviceid
= dev
->id
;
682 ev
.event_id
= pbd
->barrier_event_id
;
683 ev
.dt
= ms
- pbd
->last_timestamp
;
685 GetSpritePosition(dev
, &root_x
, &root_y
);
689 mieqEnqueue(dev
, (InternalEvent
*) &ev
);
692 xorg_list_del(&c
->entry
);
694 FreePointerBarrierClient(c
);
698 static void add_master_func(pointer res
, XID id
, pointer devid
)
700 struct PointerBarrier
*b
;
701 struct PointerBarrierClient
*barrier
;
702 struct PointerBarrierDevice
*pbd
;
703 int *deviceid
= devid
;
706 barrier
= container_of(b
, struct PointerBarrierClient
, barrier
);
709 pbd
= AllocBarrierDevice();
710 pbd
->deviceid
= *deviceid
;
712 xorg_list_add(&pbd
->entry
, &barrier
->per_device
);
715 static void remove_master_func(pointer res
, XID id
, pointer devid
)
717 struct PointerBarrierDevice
*pbd
;
718 struct PointerBarrierClient
*barrier
;
719 struct PointerBarrier
*b
;
721 int *deviceid
= devid
;
723 Time ms
= GetTimeInMillis();
725 rc
= dixLookupDevice(&dev
, *deviceid
, serverClient
, DixSendAccess
);
730 barrier
= container_of(b
, struct PointerBarrierClient
, barrier
);
732 pbd
= GetBarrierDevice(barrier
, *deviceid
);
736 .header
= ET_Internal
,
737 .type
=ET_BarrierLeave
,
738 .length
= sizeof (BarrierEvent
),
740 .deviceid
= *deviceid
,
744 .root
= barrier
->screen
->root
->drawable
.id
,
745 .window
= barrier
->window
,
746 .dt
= ms
- pbd
->last_timestamp
,
747 .flags
= XIBarrierPointerReleased
,
748 .event_id
= pbd
->barrier_event_id
,
749 .barrierid
= barrier
->id
,
752 mieqEnqueue(dev
, (InternalEvent
*) &ev
);
755 xorg_list_del(&pbd
->entry
);
759 void XIBarrierNewMasterDevice(ClientPtr client
, int deviceid
)
761 FindClientResourcesByType(client
, PointerBarrierType
, add_master_func
, &deviceid
);
764 void XIBarrierRemoveMasterDevice(ClientPtr client
, int deviceid
)
766 FindClientResourcesByType(client
, PointerBarrierType
, remove_master_func
, &deviceid
);
770 XICreatePointerBarrier(ClientPtr client
,
771 xXFixesCreatePointerBarrierReq
* stuff
)
774 struct PointerBarrierClient
*barrier
;
775 struct PointerBarrier b
;
782 if (!barrier_is_horizontal(&b
) && !barrier_is_vertical(&b
))
785 /* no 0-sized barriers */
786 if (barrier_is_horizontal(&b
) && barrier_is_vertical(&b
))
789 /* no infinite barriers on the wrong axis */
790 if (barrier_is_horizontal(&b
) && (b
.y1
< 0 || b
.y2
< 0))
793 if (barrier_is_vertical(&b
) && (b
.x1
< 0 || b
.x2
< 0))
796 if ((err
= CreatePointerBarrierClient(client
, stuff
, &barrier
)))
799 if (!AddResource(stuff
->barrier
, PointerBarrierType
, &barrier
->barrier
))
806 XIDestroyPointerBarrier(ClientPtr client
,
807 xXFixesDestroyPointerBarrierReq
* stuff
)
812 err
= dixLookupResourceByType((void **) &barrier
, stuff
->barrier
,
813 PointerBarrierType
, client
, DixDestroyAccess
);
814 if (err
!= Success
) {
815 client
->errorValue
= stuff
->barrier
;
819 if (CLIENT_ID(stuff
->barrier
) != client
->index
)
822 FreeResource(stuff
->barrier
, RT_NONE
);
827 SProcXIBarrierReleasePointer(ClientPtr client
)
829 xXIBarrierReleasePointerInfo
*info
;
830 REQUEST(xXIBarrierReleasePointerReq
);
833 info
= (xXIBarrierReleasePointerInfo
*) &stuff
[1];
835 swaps(&stuff
->length
);
836 swapl(&stuff
->num_barriers
);
837 for (i
= 0; i
< stuff
->num_barriers
; i
++, info
++) {
838 swaps(&info
->deviceid
);
839 swapl(&info
->barrier
);
840 swapl(&info
->eventid
);
843 return (ProcXIBarrierReleasePointer(client
));
847 ProcXIBarrierReleasePointer(ClientPtr client
)
851 struct PointerBarrierClient
*barrier
;
852 struct PointerBarrier
*b
;
853 xXIBarrierReleasePointerInfo
*info
;
855 REQUEST(xXIBarrierReleasePointerReq
);
856 REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq
);
858 info
= (xXIBarrierReleasePointerInfo
*) &stuff
[1];
859 for (i
= 0; i
< stuff
->num_barriers
; i
++, info
++) {
860 struct PointerBarrierDevice
*pbd
;
862 CARD32 barrier_id
, event_id
;
863 _X_UNUSED CARD32 device_id
;
865 barrier_id
= info
->barrier
;
866 event_id
= info
->eventid
;
868 err
= dixLookupDevice(&dev
, info
->deviceid
, client
, DixReadAccess
);
869 if (err
!= Success
) {
870 client
->errorValue
= BadDevice
;
874 err
= dixLookupResourceByType((void **) &b
, barrier_id
,
875 PointerBarrierType
, client
, DixReadAccess
);
876 if (err
!= Success
) {
877 client
->errorValue
= barrier_id
;
881 if (CLIENT_ID(barrier_id
) != client
->index
)
885 barrier
= container_of(b
, struct PointerBarrierClient
, barrier
);
887 pbd
= GetBarrierDevice(barrier
, dev
->id
);
889 if (pbd
->barrier_event_id
== event_id
)
890 pbd
->release_event_id
= event_id
;
901 if (!dixRegisterPrivateKey(&BarrierScreenPrivateKeyRec
, PRIVATE_SCREEN
, 0))
904 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
905 ScreenPtr pScreen
= screenInfo
.screens
[i
];
908 cs
= (BarrierScreenPtr
) calloc(1, sizeof(BarrierScreenRec
));
911 xorg_list_init(&cs
->barriers
);
912 SetBarrierScreen(pScreen
, cs
);
915 PointerBarrierType
= CreateNewResourceType(BarrierFreeBarrier
,
918 return PointerBarrierType
;
925 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
926 ScreenPtr pScreen
= screenInfo
.screens
[i
];
927 BarrierScreenPtr cs
= GetBarrierScreen(pScreen
);
929 SetBarrierScreen(pScreen
, NULL
);