Skip to content

Commit daa5773

Browse files
committed
Merge branch 'release/1.10.x'
2 parents 2288ffc + 239dc40 commit daa5773

File tree

6 files changed

+262
-40
lines changed

6 files changed

+262
-40
lines changed

dtool/src/interrogate/interfaceMakerPythonNative.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ get_slotted_function_def(Object *obj, Function *func, FunctionRemap *remap,
431431
return true;
432432
}
433433

434+
if (method_name == "operator |=") {
435+
def._answer_location = "nb_inplace_or";
436+
def._wrapper_type = WT_inplace_binary_operator;
437+
return true;
438+
}
439+
434440
if (method_name == "__ipow__") {
435441
def._answer_location = "nb_inplace_power";
436442
def._wrapper_type = WT_inplace_ternary_operator;

panda/src/cocoadisplay/cocoaGraphicsWindow.mm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@
16181618
if ([event type] == NSKeyDown) {
16191619
// Translate it to a unicode character for keystrokes. I would use
16201620
// interpretKeyEvents and insertText, but that doesn't handle dead keys.
1621-
TISInputSourceRef input_source = TISCopyCurrentKeyboardInputSource();
1621+
TISInputSourceRef input_source = TISCopyCurrentKeyboardLayoutInputSource();
16221622
CFDataRef layout_data = (CFDataRef)TISGetInputSourceProperty(input_source, kTISPropertyUnicodeKeyLayoutData);
16231623
const UCKeyboardLayout *layout = (const UCKeyboardLayout *)CFDataGetBytePtr(layout_data);
16241624

@@ -1827,7 +1827,7 @@
18271827
const UCKeyboardLayout *layout;
18281828

18291829
// Get the current keyboard layout data.
1830-
input_source = TISCopyCurrentKeyboardInputSource();
1830+
input_source = TISCopyCurrentKeyboardLayoutInputSource();
18311831
layout_data = (CFDataRef) TISGetInputSourceProperty(input_source, kTISPropertyUnicodeKeyLayoutData);
18321832
layout = (const UCKeyboardLayout *)CFDataGetBytePtr(layout_data);
18331833

panda/src/device/ioKitInputDevice.cxx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@
2222
#include "mouseButton.h"
2323

2424
static void removal_callback(void *ctx, IOReturn result, void *sender) {
25-
IOKitInputDevice *input_device = (IOKitInputDevice *)ctx;
25+
// We need to hold a reference to this because it may otherwise be destroyed
26+
// during the call to on_remove().
27+
PT(IOKitInputDevice) input_device = (IOKitInputDevice *)ctx;
2628
nassertv(input_device != nullptr);
29+
nassertv(input_device->test_ref_count_integrity());
2730
input_device->on_remove();
2831
}
2932

panda/src/putil/sparseArray.cxx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ compare_to(const SparseArray &other) const {
262262
return -1;
263263
}
264264

265-
--ai;
266-
--bi;
265+
++ai;
266+
++bi;
267267
}
268268

269269
if (ai != _subranges.rend()) {
@@ -440,9 +440,9 @@ do_remove_range(int begin, int end) {
440440
if (si == _subranges.end()) {
441441
if (!_subranges.empty()) {
442442
si = _subranges.begin() + _subranges.size() - 1;
443-
if ((*si)._end >= begin) {
443+
if ((*si)._end > begin) {
444444
// The new range shortens the last element of the array on the right.
445-
end = std::min(end, (*si)._begin);
445+
end = std::max(begin, (*si)._begin);
446446
(*si)._end = end;
447447
// It might also shorten it on the left; fall through.
448448
} else {
@@ -462,10 +462,10 @@ do_remove_range(int begin, int end) {
462462
if (si != _subranges.begin()) {
463463
Subranges::iterator si2 = si;
464464
--si2;
465-
if ((*si2)._end >= begin) {
465+
if ((*si2)._end > begin) {
466466
// The new range shortens an element within the array on the right
467467
// (but does not intersect the next element).
468-
end = std::min(end, (*si2)._begin);
468+
end = std::max(begin, (*si2)._begin);
469469
(*si2)._end = end;
470470
// It might also shorten it on the left; fall through.
471471
si = si2;
@@ -488,7 +488,7 @@ do_remove_range(int begin, int end) {
488488
}
489489

490490
// Check if the new range removes any elements to the left.
491-
while (begin <= (*si)._begin) {
491+
while (begin <= (*si)._begin || (*si)._begin >= (*si)._end) {
492492
if (si == _subranges.begin()) {
493493
_subranges.erase(si);
494494
return;
@@ -500,6 +500,7 @@ do_remove_range(int begin, int end) {
500500
}
501501

502502
(*si)._end = std::min((*si)._end, begin);
503+
nassertv((*si)._end > (*si)._begin);
503504
}
504505

505506
/**

panda/src/x11display/x11GraphicsWindow.cxx

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,13 @@ set_properties_now(WindowProperties &properties) {
589589
// OK, first figure out which CRTC the window is on. It may be on more
590590
// than one, actually, so grab a point in the center in order to figure
591591
// out which one it's more-or-less mostly on.
592-
LPoint2i center = _properties.get_origin() + _properties.get_size() / 2;
592+
LPoint2i center(0, 0);
593+
if (_properties.has_origin()) {
594+
center = _properties.get_origin();
595+
if (_properties.has_size()) {
596+
center += _properties.get_size() / 2;
597+
}
598+
}
593599
int x, y, width, height;
594600
x11_pipe->find_fullscreen_crtc(center, x, y, width, height);
595601

@@ -628,7 +634,7 @@ set_properties_now(WindowProperties &properties) {
628634
// We may need to change the screen resolution. The code below is
629635
// suboptimal; in the future, we probably want to only touch the CRTC
630636
// that the window is on.
631-
XRRScreenConfiguration *conf = _XRRGetScreenInfo(_display, _xwindow);
637+
XRRScreenConfiguration *conf = _XRRGetScreenInfo(_display, _xwindow ? _xwindow : x11_pipe->get_root());
632638
SizeID old_size_id = x11_pipe->_XRRConfigCurrentConfiguration(conf, &_orig_rotation);
633639
SizeID new_size_id = (SizeID) -1;
634640
int num_sizes = 0;
@@ -1010,34 +1016,6 @@ open_window() {
10101016
// Make sure we are not making X11 calls from other threads.
10111017
LightReMutexHolder holder(x11GraphicsPipe::_x_mutex);
10121018

1013-
if (_properties.get_fullscreen() && x11_pipe->_have_xrandr) {
1014-
XRRScreenConfiguration* conf = _XRRGetScreenInfo(_display, x11_pipe->get_root());
1015-
if (_orig_size_id == (SizeID) -1) {
1016-
_orig_size_id = x11_pipe->_XRRConfigCurrentConfiguration(conf, &_orig_rotation);
1017-
}
1018-
int num_sizes, new_size_id = -1;
1019-
XRRScreenSize *xrrs;
1020-
xrrs = x11_pipe->_XRRSizes(_display, 0, &num_sizes);
1021-
for (int i = 0; i < num_sizes; ++i) {
1022-
if (xrrs[i].width == _properties.get_x_size() &&
1023-
xrrs[i].height == _properties.get_y_size()) {
1024-
new_size_id = i;
1025-
}
1026-
}
1027-
if (new_size_id == -1) {
1028-
x11display_cat.error()
1029-
<< "Videocard has no supported display resolutions at specified res ("
1030-
<< _properties.get_x_size() << " x " << _properties.get_y_size() <<")\n";
1031-
_orig_size_id = -1;
1032-
return false;
1033-
}
1034-
if (new_size_id != _orig_size_id) {
1035-
_XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
1036-
} else {
1037-
_orig_size_id = -1;
1038-
}
1039-
}
1040-
10411019
X11_Window parent_window = x11_pipe->get_root();
10421020
WindowHandle *window_handle = _properties.get_parent_window();
10431021
if (window_handle != nullptr) {

tests/putil/test_sparsearray.py

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
from panda3d import core
2+
3+
4+
def test_sparse_array_set_bit_to():
5+
"""Tests SparseArray behavior for set_bit_to()."""
6+
7+
s = core.SparseArray()
8+
s.set_bit_to(5, True)
9+
assert s.get_bit(5)
10+
11+
s = core.SparseArray.all_on()
12+
s.set_bit_to(5, False)
13+
assert not s.get_bit(5)
14+
15+
16+
def test_sparse_array_clear():
17+
"""Tests SparseArray behavior for clear()."""
18+
19+
s = core.SparseArray.all_on()
20+
s.clear()
21+
assert s.is_zero()
22+
assert not s.is_inverse()
23+
assert s.get_num_subranges() == 0
24+
assert s.get_num_on_bits() == 0
25+
assert s.get_num_bits() == 0
26+
27+
s = core.SparseArray()
28+
s.set_range(5, 10)
29+
s.clear()
30+
assert s.is_zero()
31+
assert not s.is_inverse()
32+
assert s.get_num_subranges() == 0
33+
assert s.get_num_on_bits() == 0
34+
assert s.get_num_bits() == 0
35+
36+
37+
def test_sparse_array_clear_range():
38+
# Not using parametrize because there are too many values for that.
39+
for mask in range(0x7f):
40+
for begin in range(8):
41+
for size in range(8):
42+
b = core.BitArray(mask)
43+
s = core.SparseArray(b)
44+
45+
s.clear_range(begin, size)
46+
b.clear_range(begin, size)
47+
48+
assert core.BitArray(s) == b
49+
assert s == core.SparseArray(b)
50+
51+
52+
def test_sparse_array_set_clear_ranges():
53+
"""Tests SparseArray behavior for setting and clearing ranges."""
54+
55+
# test clear_range with single overlapping on-range
56+
# (clear_range extends beyond highest on-bit)
57+
s = core.SparseArray()
58+
s.set_range(2, 3)
59+
s.clear_range(3, 3)
60+
assert s.get_bit(2)
61+
assert not s.get_bit(3)
62+
63+
# same as above, using set_range_to
64+
s = core.SparseArray()
65+
s.set_range_to(True, 2, 3)
66+
s.set_range_to(False, 3, 3)
67+
assert s.get_bit(2)
68+
assert not s.get_bit(3)
69+
70+
# test clear_range using off-range which overlaps two on-ranges
71+
# (lowest off-bit in lowest on-range, highest off-bit in highest on-range)
72+
s = core.SparseArray()
73+
s.set_range(2, 3)
74+
s.set_range(7, 3)
75+
s.clear_range(3, 6)
76+
assert s.get_bit(2)
77+
assert not s.get_bit(3)
78+
assert not s.get_bit(8)
79+
assert s.get_bit(9)
80+
81+
# same as above, using set_range_to
82+
s = core.SparseArray()
83+
s.set_range_to(True, 2, 3)
84+
s.set_range_to(True, 7, 3)
85+
s.set_range_to(False, 3, 6)
86+
assert s.get_bit(2)
87+
assert not s.get_bit(3)
88+
assert not s.get_bit(8)
89+
assert s.get_bit(9)
90+
91+
92+
def test_sparse_array_set_range():
93+
"""Tests SparseArray behavior for set_range()."""
94+
95+
# test set_range with single overlapping off-range
96+
# (set_range extends beyond highest off-bit)
97+
s = core.SparseArray.all_on()
98+
s.clear_range(2, 3)
99+
s.set_range(3, 3)
100+
assert not s.get_bit(2)
101+
assert s.get_bit(3)
102+
103+
# same as above, using set_range_to
104+
s = core.SparseArray.all_on()
105+
s.set_range_to(False, 2, 3)
106+
s.set_range_to(True, 3, 3)
107+
assert not s.get_bit(2)
108+
assert s.get_bit(3)
109+
110+
# test set_range using on-range which overlaps two off-ranges
111+
# (lowest on-bit in lowest off-range, highest on-bit in highest off-range)
112+
s = core.SparseArray.all_on()
113+
s.clear_range(2, 3)
114+
s.clear_range(7, 3)
115+
s.set_range(3, 6)
116+
assert not s.get_bit(2)
117+
assert s.get_bit(3)
118+
assert s.get_bit(8)
119+
assert not s.get_bit(9)
120+
121+
# same as above, using set_range_to
122+
s = core.SparseArray.all_on()
123+
s.set_range_to(False, 2, 3)
124+
s.set_range_to(False, 7, 3)
125+
s.set_range_to(True, 3, 6)
126+
assert not s.get_bit(2)
127+
assert s.get_bit(3)
128+
assert s.get_bit(8)
129+
assert not s.get_bit(9)
130+
131+
132+
def test_sparse_array_bits_in_common():
133+
"""Tests SparseArray behavior for has_bits_in_common()."""
134+
135+
s = core.SparseArray()
136+
t = core.SparseArray()
137+
s.set_range(2, 4)
138+
t.set_range(5, 4)
139+
assert s.has_bits_in_common(t)
140+
141+
s = core.SparseArray()
142+
t = core.SparseArray()
143+
s.set_range(2, 4)
144+
t.set_range(6, 4)
145+
assert not s.has_bits_in_common(t)
146+
147+
148+
def test_sparse_array_operations():
149+
"""Tests SparseArray behavior for various operations."""
150+
151+
# test bitshift to left
152+
s = core.SparseArray()
153+
s.set_bit(2)
154+
t = s << 2
155+
assert t.get_bit(4)
156+
assert not t.get_bit(2)
157+
158+
# test bitshift to right
159+
s = core.SparseArray()
160+
s.set_bit(4)
161+
t = s >> 2
162+
assert t.get_bit(2)
163+
assert not t.get_bit(4)
164+
165+
# test bitwise AND
166+
s = core.SparseArray()
167+
t = core.SparseArray()
168+
s.set_bit(2)
169+
s.set_bit(3)
170+
t.set_bit(1)
171+
t.set_bit(3)
172+
u = s & t
173+
assert not u.get_bit(0)
174+
assert not u.get_bit(1)
175+
assert not u.get_bit(2)
176+
assert u.get_bit(3)
177+
178+
# test bitwise OR
179+
s = core.SparseArray()
180+
t = core.SparseArray()
181+
s.set_bit(2)
182+
s.set_bit(3)
183+
t.set_bit(1)
184+
t.set_bit(3)
185+
u = s | t
186+
assert not u.get_bit(0)
187+
assert u.get_bit(1)
188+
assert u.get_bit(2)
189+
assert u.get_bit(3)
190+
191+
# test bitwise XOR
192+
s = core.SparseArray()
193+
t = core.SparseArray()
194+
s.set_bit(2)
195+
s.set_bit(3)
196+
t.set_bit(1)
197+
t.set_bit(3)
198+
u = s ^ t
199+
assert not u.get_bit(0)
200+
assert u.get_bit(1)
201+
assert u.get_bit(2)
202+
assert not u.get_bit(3)
203+
204+
205+
def test_sparse_array_augm_assignment():
206+
"""Tests SparseArray behavior for augmented assignments."""
207+
208+
# test in-place bitshift to left
209+
s = t = core.SparseArray()
210+
t <<= 2
211+
assert s is t
212+
213+
# test in-place bitshift to right
214+
s = t = core.SparseArray()
215+
t >>= 2
216+
assert s is t
217+
218+
# test in-place bitwise AND
219+
s = t = core.SparseArray()
220+
u = core.SparseArray()
221+
t &= u
222+
assert s is t
223+
224+
# test in-place bitwise OR
225+
s = t = core.SparseArray()
226+
u = core.SparseArray()
227+
t |= u
228+
assert s is t
229+
230+
# test in-place bitwise XOR
231+
s = t = core.SparseArray()
232+
u = core.SparseArray()
233+
t ^= u
234+
assert s is t

0 commit comments

Comments
 (0)