35
36 /**
37 * Per-screen XSETTINGS.
38 */
39 public class XSettings {
40
41 /**
42 */
43 private long serial = -1;
44
45
46 /**
47 * Update these settings with <code>data</code> obtained from
48 * XSETTINGS manager.
49 *
50 * @param data settings data obtained from
51 * <code>_XSETTINGS_SETTINGS</code> window property of the
52 * settings manager.
53 * @return a <code>Map</code> of changed settings.
54 */
55 public Map update(byte[] data) {
56 return (new Update(data)).update();
57 }
58
59
60 /**
61 * TBS ...
62 */
63 class Update {
64
65 /* byte order mark */
66 private static final int LITTLE_ENDIAN = 0;
67 private static final int BIG_ENDIAN = 1;
68
69 /* setting type */
70 private static final int TYPE_INTEGER = 0;
71 private static final int TYPE_STRING = 1;
72 private static final int TYPE_COLOR = 2;
73
74 private byte[] data;
75 private int dlen;
76 private int idx;
77 private boolean isLittle;
78 private long serial = -1;
79 private int nsettings = 0;
80 private boolean isValid;
81
82 private HashMap updatedSettings;
83
84
85 /**
86 * Construct an Update object for the data read from
87 * <code>_XSETTINGS_SETTINGS</code> property of the XSETTINGS
88 * selection owner.
89 *
90 * @param data <code>_XSETTINGS_SETTINGS</code> contents.
91 */
92 Update(byte[] data) {
93 this.data = data;
94
95 dlen = data.length;
96 if (dlen < 12) {
97 // XXX: debug trace?
98 return;
99 }
100
101 // first byte gives endianness of the data
102 // next 3 bytes are unused (pad to 32 bit)
103 idx = 0;
104 isLittle = (getCARD8() == LITTLE_ENDIAN);
105
106 idx = 4;
107 serial = getCARD32();
108
109 // N_SETTINGS is actually CARD32 (i.e. unsigned), but
110 // since java doesn't have an unsigned int type, and
111 // N_SETTINGS cannot realistically exceed 2^31 (so we
112 // gonna use int anyway), just read it as INT32.
113 idx = 8;
114 nsettings = getINT32();
115
116 updatedSettings = new HashMap();
117
118 isValid = true;
119 }
120
121
122 private void needBytes(int n)
123 throws IndexOutOfBoundsException
124 {
125 if (idx + n <= dlen) {
126 return;
127 }
128
129 throw new IndexOutOfBoundsException("at " + idx
130 + " need " + n
131 + " length " + dlen);
132 }
133
134
135 private int getCARD8()
136 throws IndexOutOfBoundsException
196 private String getString(int len)
197 throws IndexOutOfBoundsException
198 {
199 needBytes(len);
200
201 String str = null;
202 try {
203 str = new String(data, idx, len, "UTF-8");
204 } catch (UnsupportedEncodingException e) {
205 // XXX: cannot happen, "UTF-8" is always supported
206 }
207
208 idx = (idx + len + 3) & ~0x3;
209 return str;
210 }
211
212
213 /**
214 * Update settings.
215 */
216 public Map update() {
217 if (!isValid) {
218 return null;
219 }
220
221 synchronized (XSettings.this) {
222 long currentSerial = XSettings.this.serial;
223
224 if (this.serial <= currentSerial) {
225 return null;
226 }
227
228 for (int i = 0; i < nsettings && idx < dlen; ++i) {
229 updateOne(currentSerial);
230 }
231
232 XSettings.this.serial = this.serial;
233 }
234
235 return updatedSettings;
236 }
|
35
36 /**
37 * Per-screen XSETTINGS.
38 */
39 public class XSettings {
40
41 /**
42 */
43 private long serial = -1;
44
45
46 /**
47 * Update these settings with <code>data</code> obtained from
48 * XSETTINGS manager.
49 *
50 * @param data settings data obtained from
51 * <code>_XSETTINGS_SETTINGS</code> window property of the
52 * settings manager.
53 * @return a <code>Map</code> of changed settings.
54 */
55 public Map<String, Object> update(byte[] data) {
56 return (new Update(data)).update();
57 }
58
59
60 /**
61 * TBS ...
62 */
63 class Update {
64
65 /* byte order mark */
66 private static final int LITTLE_ENDIAN = 0;
67 private static final int BIG_ENDIAN = 1;
68
69 /* setting type */
70 private static final int TYPE_INTEGER = 0;
71 private static final int TYPE_STRING = 1;
72 private static final int TYPE_COLOR = 2;
73
74 private byte[] data;
75 private int dlen;
76 private int idx;
77 private boolean isLittle;
78 private long serial = -1;
79 private int nsettings = 0;
80 private boolean isValid;
81
82 private HashMap<String, Object> updatedSettings;
83
84
85 /**
86 * Construct an Update object for the data read from
87 * <code>_XSETTINGS_SETTINGS</code> property of the XSETTINGS
88 * selection owner.
89 *
90 * @param data <code>_XSETTINGS_SETTINGS</code> contents.
91 */
92 Update(byte[] data) {
93 this.data = data;
94
95 dlen = data.length;
96 if (dlen < 12) {
97 // XXX: debug trace?
98 return;
99 }
100
101 // first byte gives endianness of the data
102 // next 3 bytes are unused (pad to 32 bit)
103 idx = 0;
104 isLittle = (getCARD8() == LITTLE_ENDIAN);
105
106 idx = 4;
107 serial = getCARD32();
108
109 // N_SETTINGS is actually CARD32 (i.e. unsigned), but
110 // since java doesn't have an unsigned int type, and
111 // N_SETTINGS cannot realistically exceed 2^31 (so we
112 // gonna use int anyway), just read it as INT32.
113 idx = 8;
114 nsettings = getINT32();
115
116 updatedSettings = new HashMap<>();
117
118 isValid = true;
119 }
120
121
122 private void needBytes(int n)
123 throws IndexOutOfBoundsException
124 {
125 if (idx + n <= dlen) {
126 return;
127 }
128
129 throw new IndexOutOfBoundsException("at " + idx
130 + " need " + n
131 + " length " + dlen);
132 }
133
134
135 private int getCARD8()
136 throws IndexOutOfBoundsException
196 private String getString(int len)
197 throws IndexOutOfBoundsException
198 {
199 needBytes(len);
200
201 String str = null;
202 try {
203 str = new String(data, idx, len, "UTF-8");
204 } catch (UnsupportedEncodingException e) {
205 // XXX: cannot happen, "UTF-8" is always supported
206 }
207
208 idx = (idx + len + 3) & ~0x3;
209 return str;
210 }
211
212
213 /**
214 * Update settings.
215 */
216 public Map<String, Object> update() {
217 if (!isValid) {
218 return null;
219 }
220
221 synchronized (XSettings.this) {
222 long currentSerial = XSettings.this.serial;
223
224 if (this.serial <= currentSerial) {
225 return null;
226 }
227
228 for (int i = 0; i < nsettings && idx < dlen; ++i) {
229 updateOne(currentSerial);
230 }
231
232 XSettings.this.serial = this.serial;
233 }
234
235 return updatedSettings;
236 }
|