RSS

(root)/iphone/tappity : /tappity/source/Tappity.m (revision 49)

To get this branch, use:
bzr branch /browse/iphone/tappity
Line Revision Contents
1 46
//
2
//  Tappity.m
3
//  tappity
4
//
5
//  Created by döme on 25.10.2009.
6
//  Copyright 2009 __MyCompanyName__. All rights reserved.
7
//
8
9 47
10
#include <stdint.h>
11
#include <sys/socket.h>
12
#include <fcntl.h>
13
#include <termios.h>
14
#include <netinet/in.h>
15
#include <arpa/inet.h>
16
17
18 46
#import "Tappity.h"
19
20 49
//#import "GraphicsServices.h"
21 46
22
NSString* TapIdKey		= @"tapId";
23
NSString* TapTouchesKey = @"tapTouches";
24
NSString* TapGSEventKey = @"tapGSEvent";
25
NSString* TapTouchPhaseKey = @"tapTouchPhase";
26
NSString* TapRecordedEventKey = @"tapRecordedEvent";
27 48
NSString* TapAccelerationKey = @"tapAcceleration";
28
NSString* TapCompassKey = @"tapCompass";
29
NSString* TapLocationKey = @"tapLocation";
30
31
32
@interface Tappity (Private)
33
- (void) dataReceived: (NSData*) data;
34
@end
35 47
36 46
@implementation Tappity
37
38 47
- (BOOL) threadActive: (id) key
39
{
40
	return [[activeThreads objectForKey: key] boolValue];
41
}
42
43
- (void) threadWillExit: (id) key
44
{
45
	@synchronized (self)
46
	{
47
		[activeThreads removeObjectForKey: key];
48 49
		
49
		if (![activeThreads count])
50
		{
51
			close(commsSocket);
52
			commsSocket = -1;
53
			
54
			
55
		}
56 47
	}
57
}
58
59
- (void) receivingThread: (id) info
60
{
61
	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
62
63
	@synchronized(self)
64
	{
65
		[self retain];
66
	}
67
68
	while ([self threadActive: info])
69
	{
70
		struct timeval tv;
71
		fd_set readfds;
72
		fd_set writefds;
73
		fd_set errorfds;
74 49
		int socket = -1;
75 47
		int maxSocket = -1;
76 49
		
77
		@synchronized(self)
78
		{
79
			socket = commsSocket;
80
		}
81 47
82
		tv.tv_sec = 1;
83
		tv.tv_usec = 0;
84
85
		FD_ZERO(&readfds);
86
		FD_ZERO(&writefds);
87
		FD_ZERO(&errorfds);
88
89 49
		FD_SET(socket, &readfds);
90
		FD_SET(socket, &errorfds);
91
		maxSocket = MAX(maxSocket, socket);
92 47
		
93
		if (maxSocket < 0)
94
		{
95
			//printf("No sockets, sleeping for a bit...\n");
96
			usleep(1000000);
97
			continue;
98
		}
99
100
		if (select(maxSocket+1, &readfds, &writefds, &errorfds, &tv) < 0)
101
		{
102
			perror("select");
103
			break;
104
		}
105
106 49
		if (FD_ISSET(socket, &readfds))
107 47
		{
108
			//NSLog(@"receiving...");
109
			if (!expectedMessageSize)
110
			{
111
				uint32_t buf = 0;
112
				int actuallyRead = 0;
113
			
114 49
				actuallyRead = recv(socket, &buf, sizeof(uint32_t), MSG_PEEK);
115 47
				
116
				if (actuallyRead == sizeof(uint32_t))
117
				{
118 49
					actuallyRead = recv(socket, &buf, sizeof(uint32_t), 0);
119 47
					expectedMessageSize = ntohl(buf);
120
					currentData = [[NSMutableData alloc] initWithLength: expectedMessageSize];
121
				}
122 48
				else if (actuallyRead == -1)
123
				{
124
					//close(commsSocket);
125
					//self->commsSocket = 0;
126
					if (errno != ETIMEDOUT)
127
					{
128
						printf("Connection dropped with error.\n");
129
						break;
130
					}
131 47
				}
132 49
				else if (actuallyRead == 0)
133
				{
134
					printf("remote socket closed.\n");
135
					break;
136
				}
137 47
			}
138
			else
139
			{
140
				size_t readAmount = expectedMessageSize - currentlyRead;
141
				int actuallyRead = 0;
142
			
143 49
				actuallyRead = recv(socket, [currentData mutableBytes] + currentlyRead, readAmount, 0);
144 47
				if (actuallyRead == -1)
145
				{
146
					printf("Connection dropped with error.\n");
147
					break;
148
				}
149 49
				else if (actuallyRead == 0)
150
				{
151
					printf("remote socket closed.\n");
152
					break;
153
				}
154
155 47
				currentlyRead += actuallyRead;
156
				
157
				if (currentlyRead == expectedMessageSize)
158
				{
159
					@synchronized(self)
160
					{
161
						expectedMessageSize = 0;
162
						/*
163
						if (!receivedPackets)
164
							receivedPackets = [[NSMutableArray alloc] init];
165
						[receivedPackets addObject: currentData];
166
						[currentData release];
167
						*/
168
						
169
					}
170 48
171
					if (receiveDataOnMainThread)
172
						[self performSelectorOnMainThread: @selector(dataReceived:) withObject: currentData waitUntilDone: NO];
173
					else
174
						[self dataReceived: currentData];
175
176 47
					currentData = nil;
177
					currentlyRead = 0;
178
				}
179
			}
180
181
		}
182
	}
183
	
184
	[self threadWillExit: info];
185
186
	@synchronized(self)
187
	{
188
		[self release];
189
	}
190
191
	[info release];
192
	[pool drain];
193
}
194
195
196
- (void) runThreadWithSelector: (SEL) selector
197
{
198
	@synchronized(self)
199
	{
200
		if (!activeThreads)
201
			activeThreads = [[NSMutableDictionary alloc] init];
202
		id number = [NSNumber numberWithInt: threadIds++];
203
204
		[activeThreads setObject: [NSNumber numberWithBool: YES] forKey: number];
205
		[NSThread detachNewThreadSelector: selector toTarget: self withObject: [number retain]];
206
	}
207
}
208
209
- (void) sendData: (NSData*) tapData
210
{		
211
	[sendLock lock];
212
213
	if (!sendQueue)
214
		sendQueue = [[NSMutableArray alloc] init];
215
216
	[sendQueue addObject: tapData];
217
	
218
	[sendLock signal];
219
	[sendLock unlock];
220
		
221
}
222
223
224
- (void) sendingThread: (id) info
225
{
226
	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
227
228
	@synchronized(self)
229
	{
230
		[self retain];
231
	}
232
233
	while ([self threadActive: info])
234
	{
235
		[sendLock lock];
236
			while (![sendQueue count])
237
				[sendLock wait];
238
				
239
		//NSLog(@"sending");
240
		
241
		NSData* data = [[sendQueue objectAtIndex: 0] retain];
242
		[sendQueue removeObjectAtIndex: 0];
243
		
244
		[sendLock unlock];
245
246
		size_t sizeToSend = 4;
247
		size_t dataSent = 0;
248
		uint32_t header = htonl([data length]);
249
		int err = 0;
250 49
		int socket = -1;
251
		
252
		@synchronized(self)
253
		{
254
			socket = commsSocket;
255
		}
256 47
257
		while (dataSent < sizeToSend)
258
		{
259 49
			if ((err = send(socket, &header + dataSent, sizeToSend - dataSent, 0)) == -1)
260 47
			{
261
				perror("send");
262
				break;
263
			}
264
			else
265
				dataSent += err;
266
		}
267
		
268
		if (err != -1)
269
		{
270
			sizeToSend = [data length];
271
			dataSent = 0;
272
			while (dataSent < sizeToSend)
273
			{
274 49
				if ((err = send(socket, [data bytes] + dataSent, sizeToSend - dataSent, 0)) == -1)
275 47
				{
276
					perror("send");
277
					break;
278
				}
279
				else
280
					dataSent += err;
281
					
282
			}
283
		}
284
		[data release];
285
		
286
		if (err == -1)
287
			break;
288
		
289
	}
290
	
291
292
	[self threadWillExit: info];
293
294
	@synchronized(self)
295
	{
296
		[self release];
297
	}
298
299
	[info release];
300
	[pool drain];
301
}
302
303 46
@end
304
305
@implementation UITouch (Synthesize)
306
307
- (id)initInView:(UIView *)view
308
{
309
    self = [super init];
310
    if (self != nil)
311
    {
312
        CGRect frameInWindow;
313
        if ([view isKindOfClass:[UIWindow class]])
314
        {
315
            frameInWindow = view.frame;
316
        }
317
        else
318
        {
319
            frameInWindow =
320
                [view.window convertRect:view.frame fromView:view.superview];
321
        }
322
         
323
        _tapCount = 1;
324
        _locationInWindow =
325
            CGPointMake(
326
                frameInWindow.origin.x + 0.5 * frameInWindow.size.width,
327
                frameInWindow.origin.y + 0.5 * frameInWindow.size.height);
328
        _previousLocationInWindow = _locationInWindow;
329
330
        UIView *target = [view.window hitTest:_locationInWindow withEvent:nil];
331
        _view = [target retain];
332
        _window = [view.window retain];
333
        _phase = UITouchPhaseBegan;
334
        _touchFlags._firstTouchForView = 1;
335
        _touchFlags._isTap = 1;
336
        _timestamp = [NSDate timeIntervalSinceReferenceDate];
337
    }
338
    return self;
339
}
340
341
- (void)changeToPhase:(UITouchPhase)phase
342
{
343
    _phase = phase;
344
    _timestamp = [NSDate timeIntervalSinceReferenceDate];
345
}
346
347
@end
348
349 49
350
/*
351 46
void _printGSPathPoint(GSTouchPointRef p)
352
{
353
//	printf("P: 0x%08X 0x%08X 0x%08X 0x%08X (%G, %G)\n", p->unk0, p->unk1, p->unk2, p->unk5, p->x, p->y);
354
	printf("P: 0x%08X %7G %7G (%G, %G)\n", p->unk0, p->unk1, p->touchSize, p->x, p->y);
355
}
356
357
void _printGSEvent(UIEvent* event)
358
{
359
	GSEvent* e = [event _gsEvent];
360
//	printf("%p, %p\n", event, e);
361
//	printf("0x%08X  0x%08X  0x%08X\n", e->unk1, e->unk2, e->unk3);
362
363
//	printf("type0 0x%08X  type1 0x%08X  r3 0x%08X\n", e->type0, e->type1, e->r3);
364
//	printf("type10 0x%08X  r11 0x%08X  type12 0x%08X\n", e->type10, e->r11, e->type12);
365
//	printf("gesture12 0x%08X  gesture14 0x%08X\n", e->gesture13, e->gesture14);
366
367
//	printf("avg0 (%5G, %5G),  avg1 (%5G, %5G)\n", e->avgX0, e->avgY0, e->avgX1, e->avgY1);
368
//	printf("(%d) %d\n", e->numInitialTouches, e->numCurrentTouches);
369
//	printf("unk16 0x%08X  unk17 0x%08X  unk18 0x%08X  unk19 0x%08X\n", e->unk16, e->unk17, e->unk18, e->unk19);
370
//	printf("r20 0x%08X  r21 0x%08X\n", e->r20, e->r21);
371
	printf("points %d\n", e->numPoints);
372
373
//	printf("unk9 0x%08X  unk10 0x%08X unk11 0x%08X unk12 0x%08X\n", e->unk9, e->unk10, e->unk11, e->unk12);
374
//	printf("%u.%u\n", e->timestamp_s, e->timestamp_ns);
375
//	printf("%G\n", (double)e->timestamp*1e-9);
376
//	printf("unk12 0x%08X  unk13 0x%08X  unk14 0x%08X  unk15 0x%08X\n", e->unk12, e->unk13, e->unk14, e->unk15);
377
	for(size_t i = 0; i < e->numPoints; ++i)
378
		_printGSPathPoint(e->points+i);
379
	printf("\n");
380
}
381
382
@implementation GSEvent
383
@end
384 49
*/
385 46

Loggerhead 1.17 is a web-based interface for Bazaar branches