added a simple LinkedList
This commit is contained in:
		| @ -588,3 +588,141 @@ extend Apex | |||||||
| 		^Association new key: self value: object | 		^Association new key: self value: object | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | ## ------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | class Link(Object) | ||||||
|  | { | ||||||
|  | 	dcl prev next value. | ||||||
|  | 	 | ||||||
|  | 	method(#class) new: value | ||||||
|  | 	{ | ||||||
|  | 		| x |  | ||||||
|  | 		x := self new. | ||||||
|  | 		x value: value. | ||||||
|  | 		^x | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method prev { ^self.prev } | ||||||
|  | 	method next { ^self.next } | ||||||
|  | 	method value { ^self.value } | ||||||
|  | 	method prev: link { self.prev := link } | ||||||
|  | 	method next: link { self.next := link } | ||||||
|  | 	method value: value { self.value := value } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class LinkedList(Collection) | ||||||
|  | { | ||||||
|  | 	dcl first last tally. | ||||||
|  |  | ||||||
|  | 	method initialize | ||||||
|  | 	{ | ||||||
|  | 		self.tally := 0. | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method size | ||||||
|  | 	{ | ||||||
|  | 		^self.tally | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method first | ||||||
|  | 	{ | ||||||
|  | 		^self.first | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method last | ||||||
|  | 	{ | ||||||
|  | 		^self.last | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method insertLink: link at: pos | ||||||
|  | 	{ | ||||||
|  | 		if (pos isNil) | ||||||
|  | 		{ | ||||||
|  | 			(* add link at the back *) | ||||||
|  | 			if (self.tally == 0) | ||||||
|  | 			{ | ||||||
|  | 				self.first := link. | ||||||
|  | 				self.last := link. | ||||||
|  | 				link prev: nil. | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				link prev: self.last. | ||||||
|  | 				self.last next: link. | ||||||
|  | 				self.last := link. | ||||||
|  | 			}. | ||||||
|  | 			link next: nil. | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			(* insert the link before pos *) | ||||||
|  | 			link next: pos. | ||||||
|  | 			link prev: pos prev. | ||||||
|  | 			if (pos prev notNil) { pos prev next: link } | ||||||
|  | 			else { self.first := link }. | ||||||
|  | 			pos prev: link | ||||||
|  | 		}. | ||||||
|  |  | ||||||
|  | 		self.tally := self.tally + 1. | ||||||
|  | 		^link | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method insert: value at: pos | ||||||
|  | 	{ | ||||||
|  | 		^self insertLink: (Link new: value) at: pos | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method addFirst: value | ||||||
|  | 	{ | ||||||
|  | 		^self insert: value at: self.first | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method addLast: value | ||||||
|  | 	{ | ||||||
|  | 		^self insert: value at: nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method addFirstLink: link | ||||||
|  | 	{ | ||||||
|  | 		^self insertLink: link at: self.first | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method addLastLink: link | ||||||
|  | 	{ | ||||||
|  | 		^self insertLink: link at: nil | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method removeLink: link | ||||||
|  | 	{ | ||||||
|  | 		if (link next notNil) { link next prev: link prev } | ||||||
|  | 		else { self.last := link prev }. | ||||||
|  | 		 | ||||||
|  | 		if (link prev notNil) { link prev next: link next } | ||||||
|  | 		else { self.first := link next }. | ||||||
|  | 		 | ||||||
|  | 		self.tally := self.tally - 1. | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method removeFirst | ||||||
|  | 	{ | ||||||
|  | 		^self removeLink: self.first | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	method removeLast | ||||||
|  | 	{ | ||||||
|  | 		^self removeLink: self.last | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method do: block | ||||||
|  | 	{ | ||||||
|  | 		| link next | | ||||||
|  | 		link := self.first. | ||||||
|  | 		while (link notNil) | ||||||
|  | 		{ | ||||||
|  | 			next := link next. | ||||||
|  | 			block value: link value. | ||||||
|  | 			link := next. | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -187,65 +187,105 @@ class Number(Magnitude) | |||||||
| 		self primitiveFailed. | 		self primitiveFailed. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method to: end by: step do: aBlock | 	method to: end by: step do: block | ||||||
| 	{ | 	{ | ||||||
| 		| i | | 		| i | | ||||||
| 		i := self. | 		i := self. | ||||||
|  | 		(* | ||||||
| 		(step > 0)  | 		(step > 0)  | ||||||
| 			ifTrue: [ | 			ifTrue: [ | ||||||
| 				[ i <= end ] whileTrue: [  | 				[ i <= end ] whileTrue: [  | ||||||
| 					aBlock value: i. | 					block value: i. | ||||||
| 					i := i + step. | 					i := i + step. | ||||||
| 				]. | 				]. | ||||||
| 			] | 			] | ||||||
| 			ifFalse: [ | 			ifFalse: [ | ||||||
| 				[ i >= end ] whileTrue: [ | 				[ i >= end ] whileTrue: [ | ||||||
| 					aBlock value: i. | 					block value: i. | ||||||
| 					i := i - step. | 					i := i - step. | ||||||
| 				]. | 				]. | ||||||
| 			]. | 			]. | ||||||
| 	} | 		*) | ||||||
|  | 		if (step > 0) | ||||||
| 	method to: end do: aBlock |  | ||||||
| 		{ | 		{ | ||||||
| 		^self to: end by: 1 do: aBlock. | 			while (i <= end) | ||||||
|  | 			{ | ||||||
|  | 				block value: i. | ||||||
|  | 				i := i + step. | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			while ( i => end) | ||||||
|  | 			{ | ||||||
|  | 				block value: i. | ||||||
|  | 				i := i - step. | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method priorTo: end by: step do: aBlock | 	method to: end do: block | ||||||
|  | 	{ | ||||||
|  | 		^self to: end by: 1 do: block. | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	method priorTo: end by: step do: block | ||||||
| 	{ | 	{ | ||||||
| 		| i | | 		| i | | ||||||
| 		i := self. | 		i := self. | ||||||
|  | 		(* | ||||||
| 		(step > 0)  | 		(step > 0)  | ||||||
| 			ifTrue: [ | 			ifTrue: [ | ||||||
| 				[ i < end ] whileTrue: [  | 				[ i < end ] whileTrue: [  | ||||||
| 					aBlock value: i. | 					block value: i. | ||||||
| 					i := i + step. | 					i := i + step. | ||||||
| 				]. | 				]. | ||||||
| 			] | 			] | ||||||
| 			ifFalse: [ | 			ifFalse: [ | ||||||
| 				[ i > end ] whileTrue: [ | 				[ i > end ] whileTrue: [ | ||||||
| 					aBlock value: i. | 					block value: i. | ||||||
| 					i := i - step. | 					i := i - step. | ||||||
| 				]. | 				]. | ||||||
| 			]. | 			]. | ||||||
|  | 		*) | ||||||
|  | 		if (step > 0) | ||||||
|  | 		{ | ||||||
|  | 			while (i < end) | ||||||
|  | 			{ | ||||||
|  | 				block value: i. | ||||||
|  | 				i := i + step. | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			while ( i > end) | ||||||
|  | 			{ | ||||||
|  | 				block value: i. | ||||||
|  | 				i := i - step. | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	method priorTo: end do: aBlock | 	method priorTo: end do: block | ||||||
| 	{ | 	{ | ||||||
| 		^self priorTo: end by: 1 do: aBlock. | 		^self priorTo: end by: 1 do: block. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method abs | 	method abs | ||||||
| 	{ | 	{ | ||||||
| 		self < 0 ifTrue: [^self negated]. | 		(*self < 0 ifTrue: [^self negated]. | ||||||
| 		^self. | 		^self.*) | ||||||
|  | 		^if (self < 0) { self negated } else { self } | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method sign | 	method sign | ||||||
| 	{ | 	{ | ||||||
| 		self < 0 ifTrue: [^-1]. | 		(* self < 0 ifTrue: [^-1]. | ||||||
| 		self > 0 ifTrue: [^1]. | 		self > 0 ifTrue: [^1]. | ||||||
| 		^0. | 		^0.*) | ||||||
|  | 		^if (self < 0) { -1 } | ||||||
|  | 		 elsif (self > 0) { 1 } | ||||||
|  | 		 else { 0 } | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -281,26 +321,12 @@ class(#liword) LargeInteger(Integer) | |||||||
|  |  | ||||||
| class(#liword) LargePositiveInteger(LargeInteger) | class(#liword) LargePositiveInteger(LargeInteger) | ||||||
| { | { | ||||||
| 	method abs | 	method abs { ^self } | ||||||
| 	{ | 	method sign { ^1 } | ||||||
| 		^self. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method sign |  | ||||||
| 	{ |  | ||||||
| 		^1. |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class(#liword) LargeNegativeInteger(LargeInteger) | class(#liword) LargeNegativeInteger(LargeInteger) | ||||||
| { | { | ||||||
| 	method abs | 	method abs { ^self negated } | ||||||
| 	{ | 	method sign { ^-1 } | ||||||
| 		^self negated. |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	method sign |  | ||||||
| 	{ |  | ||||||
| 		^-1. |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3162,12 +3162,10 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) | |||||||
|  |  | ||||||
| 				if (moo->sem_io_wait_count > 0) | 				if (moo->sem_io_wait_count > 0) | ||||||
| 				{ | 				{ | ||||||
| MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT()\n"); |  | ||||||
| 					vm_vm_muxwait (moo, &ft); | 					vm_vm_muxwait (moo, &ft); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n"); |  | ||||||
| 					vm_sleep (moo, &ft); | 					vm_sleep (moo, &ft); | ||||||
| 				} | 				} | ||||||
| 				vm_gettime (moo, &now); | 				vm_gettime (moo, &now); | ||||||
| @ -3183,7 +3181,6 @@ MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n"); | |||||||
|  |  | ||||||
| 	if (moo->sem_io_wait_count > 0)  | 	if (moo->sem_io_wait_count > 0)  | ||||||
| 	{ | 	{ | ||||||
| MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT 222()\n"); |  | ||||||
| 		vm_vm_muxwait (moo, MOO_NULL); | 		vm_vm_muxwait (moo, MOO_NULL); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -134,6 +134,7 @@ struct xtn_t | |||||||
| #if defined(USE_THREAD) | #if defined(USE_THREAD) | ||||||
| 	int p[2]; /* pipe for signaling */ | 	int p[2]; /* pipe for signaling */ | ||||||
| 	pthread_t iothr; | 	pthread_t iothr; | ||||||
|  | 	int iothr_up; | ||||||
| 	int iothr_abort; | 	int iothr_abort; | ||||||
| 	struct | 	struct | ||||||
| 	{ | 	{ | ||||||
| @ -800,7 +801,8 @@ static int vm_startup (moo_t* moo) | |||||||
| 	pthread_cond_init (&xtn->ev.cnd2, MOO_NULL); | 	pthread_cond_init (&xtn->ev.cnd2, MOO_NULL); | ||||||
|  |  | ||||||
| 	xtn->iothr_abort = 0; | 	xtn->iothr_abort = 0; | ||||||
| 	pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo); | 	xtn->iothr_up = 0; | ||||||
|  | 	/*pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo);*/ | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| @ -837,9 +839,13 @@ static void vm_cleanup (moo_t* moo) | |||||||
| 	xtn_t* xtn = (xtn_t*)moo_getxtn(moo); | 	xtn_t* xtn = (xtn_t*)moo_getxtn(moo); | ||||||
|  |  | ||||||
| #if defined(USE_THREAD) | #if defined(USE_THREAD) | ||||||
|  | 	if (xtn->iothr_up) | ||||||
|  | 	{ | ||||||
| 		write (xtn->p[1], "Q", 1); | 		write (xtn->p[1], "Q", 1); | ||||||
| 		pthread_cond_signal (&xtn->ev.cnd); | 		pthread_cond_signal (&xtn->ev.cnd); | ||||||
| 		pthread_join (xtn->iothr, MOO_NULL); | 		pthread_join (xtn->iothr, MOO_NULL); | ||||||
|  | 		xtn->iothr_up = 0; | ||||||
|  | 	} | ||||||
| 	pthread_cond_destroy (&xtn->ev.cnd); | 	pthread_cond_destroy (&xtn->ev.cnd); | ||||||
| 	pthread_cond_destroy (&xtn->ev.cnd2); | 	pthread_cond_destroy (&xtn->ev.cnd2); | ||||||
| 	pthread_mutex_destroy (&xtn->ev.mtx); | 	pthread_mutex_destroy (&xtn->ev.mtx); | ||||||
| @ -973,6 +979,18 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c | |||||||
| #if defined(USE_THREAD) | #if defined(USE_THREAD) | ||||||
| 	int n; | 	int n; | ||||||
|  |  | ||||||
|  | 	/* create a thread if mux wait is started at least once. */ | ||||||
|  | 	if (!xtn->iothr_up)  | ||||||
|  | 	{ | ||||||
|  | 		xtn->iothr_up = 1; | ||||||
|  | 		if (pthread_create (&xtn->iothr, MOO_NULL, iothr_main, moo) != 0) | ||||||
|  | 		{ | ||||||
|  | 			MOO_LOG2 (moo, MOO_LOG_WARN, "Warning: pthread_create failure - %d, %hs\n", errno, strerror(errno)); | ||||||
|  | 			xtn->iothr_up = 0; | ||||||
|  | /* TODO: switch to the non-threaded mode? */ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (xtn->ev.len <= 0)  | 	if (xtn->ev.len <= 0)  | ||||||
| 	{ | 	{ | ||||||
| 		struct timespec ts; | 		struct timespec ts; | ||||||
| @ -1016,6 +1034,7 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c | |||||||
| 			else if (muxwcb) | 			else if (muxwcb) | ||||||
| 			{ | 			{ | ||||||
| 				int mask = 0; | 				int mask = 0; | ||||||
|  |  | ||||||
| 				if (xtn->ev.buf[n].events & EPOLLIN) mask |= MOO_SEMAPHORE_IO_MASK_INPUT; | 				if (xtn->ev.buf[n].events & EPOLLIN) mask |= MOO_SEMAPHORE_IO_MASK_INPUT; | ||||||
| 				if (xtn->ev.buf[n].events & EPOLLOUT) mask |= MOO_SEMAPHORE_IO_MASK_OUTPUT; | 				if (xtn->ev.buf[n].events & EPOLLOUT) mask |= MOO_SEMAPHORE_IO_MASK_OUTPUT; | ||||||
| 				if (xtn->ev.buf[n].events & EPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; | 				if (xtn->ev.buf[n].events & EPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; | ||||||
| @ -1049,6 +1068,9 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c | |||||||
| 		xtn->ev.len = n; | 		xtn->ev.len = n; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	/* the muxwcb must be valid all the time in a non-threaded mode */ | ||||||
|  | 	MOO_ASSERT (moo, muxwcb != MOO_NULL); | ||||||
|  |  | ||||||
| 	while (n > 0) | 	while (n > 0) | ||||||
| 	{ | 	{ | ||||||
| 		int mask; | 		int mask; | ||||||
| @ -1124,7 +1146,8 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur) | |||||||
|  |  | ||||||
| 	#if defined(USE_THREAD) | 	#if defined(USE_THREAD) | ||||||
| 	/* the sleep callback is called only if there is no IO semaphore  | 	/* the sleep callback is called only if there is no IO semaphore  | ||||||
| 	 * waiting. so i can safely use vm_muxwait when USE_THREAD is true */ | 	 * waiting. so i can safely call vm_muxwait() wihtout a muxwait callback | ||||||
|  | 	 * when USE_THREAD is true */ | ||||||
| 	vm_muxwait (moo, dur, MOO_NULL); | 	vm_muxwait (moo, dur, MOO_NULL); | ||||||
| 	#else | 	#else | ||||||
| 	struct timespec ts; | 	struct timespec ts; | ||||||
|  | |||||||
| @ -225,7 +225,7 @@ static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_class_t _class, moo_oow_t | |||||||
|  |  | ||||||
| 		if (vlen > 0) | 		if (vlen > 0) | ||||||
| 		{ | 		{ | ||||||
| 			MOO_DEBUG2 (moo, "Unamed instance variables for a fixed class %O - %zu\n", _class, vlen);  | 			MOO_DEBUG2 (moo, "Unnamed instance variables for a fixed class %O - %zu\n", _class, vlen);  | ||||||
| 			return -1; | 			return -1; | ||||||
| 		} | 		} | ||||||
| 		/*vlen = 0;*/ /* vlen is not used */ | 		/*vlen = 0;*/ /* vlen is not used */ | ||||||
|  | |||||||
| @ -39,14 +39,14 @@ typedef struct x11_t x11_t; | |||||||
| struct x11_t | struct x11_t | ||||||
| { | { | ||||||
| 	xcb_connection_t* c; | 	xcb_connection_t* c; | ||||||
| 	xcb_window_t w; | 	xcb_screen_t* screen; | ||||||
| 	xcb_intern_atom_reply_t* dwcr; /* TODO: move this to each window */ |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| typedef struct x11_win_t x11_win_t; | typedef struct x11_win_t x11_win_t; | ||||||
| struct x11_win_t | struct x11_win_t | ||||||
| { | { | ||||||
| 	xcb_window_t w; | 	xcb_window_t id; | ||||||
|  | 	xcb_intern_atom_reply_t* dwcr; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | ||||||
| @ -89,7 +89,9 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) | |||||||
| 		goto softfail; | 		goto softfail; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	x11->screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data; | ||||||
| 	x11->c = c; | 	x11->c = c; | ||||||
|  |  | ||||||
| 	MOO_STACK_SETRETTORCV (moo, nargs); | 	MOO_STACK_SETRETTORCV (moo, nargs); | ||||||
| 	return MOO_PF_SUCCESS; | 	return MOO_PF_SUCCESS; | ||||||
|  |  | ||||||
| @ -158,12 +160,17 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) | |||||||
| 	{ | 	{ | ||||||
| 		uint8_t evttype = evt->response_type & ~0x80; | 		uint8_t evttype = evt->response_type & ~0x80; | ||||||
|  |  | ||||||
| 		if (evttype == XCB_CLIENT_MESSAGE &&  | 		if (evttype == XCB_CLIENT_MESSAGE) | ||||||
|  | #if 0 | ||||||
|  | &&  | ||||||
| 		    ((xcb_client_message_event_t*)evt)->data.data32[0] == x11->dwcr->atom) | 		    ((xcb_client_message_event_t*)evt)->data.data32[0] == x11->dwcr->atom) | ||||||
|  | #endif | ||||||
| 		{ | 		{ | ||||||
|  | #if 0 | ||||||
| 			xcb_unmap_window (x11->c, x11->w); | 			xcb_unmap_window (x11->c, x11->w); | ||||||
| 			xcb_destroy_window (x11->c, x11->w); | 			xcb_destroy_window (x11->c, x11->w); | ||||||
| 			xcb_flush (x11->c); | 			xcb_flush (x11->c); | ||||||
|  | #endif | ||||||
| 			MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */ | 			MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(9999)); /* TODO: translate evt to the event object */ | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| @ -174,30 +181,33 @@ static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| MOO_DEBUG0(moo, "BBBBBBBBBBBBbb GOT NO EVENT...\n"); |  | ||||||
| 		MOO_STACK_SETRET (moo, nargs, moo->_nil); | 		MOO_STACK_SETRET (moo, nargs, moo->_nil); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return MOO_PF_SUCCESS; | 	return MOO_PF_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| static moo_pfrc_t pf_makewin (moo_t* moo, moo_ooi_t nargs) | /* ------------------------------------------------------------------------ */ | ||||||
|  |  | ||||||
|  | static moo_pfrc_t pf_win_make_on (moo_t* moo, moo_ooi_t nargs) | ||||||
| { | { | ||||||
| 	x11_t* x11; | 	x11_t* x11; | ||||||
| 	xcb_screen_t* screen; | 	x11_win_t* win; | ||||||
|  |  | ||||||
| 	uint32_t mask; | 	uint32_t mask; | ||||||
| 	uint32_t values[2]; | 	uint32_t values[2]; | ||||||
| 	xcb_intern_atom_cookie_t cookie; | 	xcb_intern_atom_cookie_t cookie; | ||||||
| 	xcb_intern_atom_reply_t* reply; | 	xcb_intern_atom_reply_t* reply; | ||||||
|  |  | ||||||
| 	x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); | MOO_DEBUG0 (moo, "<x11.win._makeon:> %p\n"); | ||||||
| 	MOO_DEBUG1 (moo, "<x11.__makewin> %p\n", x11->c); |  | ||||||
|  |  | ||||||
| 	screen = xcb_setup_roots_iterator(xcb_get_setup(x11->c)).data; | 	x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL); | ||||||
| 	x11->w = xcb_generate_id (x11->c); | 	win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); | ||||||
|  |  | ||||||
|  | 	win->id = xcb_generate_id (x11->c); | ||||||
|  |  | ||||||
| 	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; | 	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; | ||||||
| 	values[0] = screen->white_pixel; | 	values[0] = x11->screen->white_pixel; | ||||||
| 	values[1] = XCB_EVENT_MASK_KEY_RELEASE | | 	values[1] = XCB_EVENT_MASK_KEY_RELEASE | | ||||||
| 	            XCB_EVENT_MASK_BUTTON_PRESS | | 	            XCB_EVENT_MASK_BUTTON_PRESS | | ||||||
| 	            XCB_EVENT_MASK_EXPOSURE | | 	            XCB_EVENT_MASK_EXPOSURE | | ||||||
| @ -208,43 +218,50 @@ static moo_pfrc_t pf_makewin (moo_t* moo, moo_ooi_t nargs) | |||||||
| 	xcb_create_window ( | 	xcb_create_window ( | ||||||
| 		x11->c,  | 		x11->c,  | ||||||
| 		XCB_COPY_FROM_PARENT, | 		XCB_COPY_FROM_PARENT, | ||||||
| 		x11->w, | 		win->id, | ||||||
| 		screen->root, | 		x11->screen->root, | ||||||
| 		0, 0, 300, 300, 10, | 		0, 0, 300, 300, 10, | ||||||
| 		XCB_WINDOW_CLASS_INPUT_OUTPUT, | 		XCB_WINDOW_CLASS_INPUT_OUTPUT, | ||||||
| 		screen->root_visual, | 		x11->screen->root_visual, | ||||||
| 		mask, values); | 		mask, values); | ||||||
|  |  | ||||||
| 	cookie = xcb_intern_atom(x11->c, 1, 12, "WM_PROTOCOLS"); | 	cookie = xcb_intern_atom(x11->c, 1, 12, "WM_PROTOCOLS"); | ||||||
| 	reply = xcb_intern_atom_reply(x11->c, cookie, 0); | 	reply = xcb_intern_atom_reply(x11->c, cookie, 0); | ||||||
|  |  | ||||||
| 	cookie = xcb_intern_atom(x11->c, 0, 16, "WM_DELETE_WINDOW"); | 	cookie = xcb_intern_atom(x11->c, 0, 16, "WM_DELETE_WINDOW"); | ||||||
| 	x11->dwcr = xcb_intern_atom_reply(x11->c, cookie, 0); | 	win->dwcr = xcb_intern_atom_reply(x11->c, cookie, 0); | ||||||
|  |  | ||||||
| 	xcb_change_property(x11->c, XCB_PROP_MODE_REPLACE, x11->w, reply->atom, 4, 32, 1, &x11->dwcr->atom); | 	xcb_change_property(x11->c, XCB_PROP_MODE_REPLACE, win->id, reply->atom, 4, 32, 1, &win->dwcr->atom); | ||||||
|  |  | ||||||
| /*TODO: use xcb_request_check() for error handling. you need to call create_x11->wdwo_checked(). xxx_checked()... */ | /*TODO: use xcb_request_check() for error handling. you need to call create_x11->wdwo_checked(). xxx_checked()... */ | ||||||
| 	xcb_map_window (x11->c, x11->w); | 	xcb_map_window (x11->c, win->id); | ||||||
| 	xcb_flush (x11->c); | 	xcb_flush (x11->c); | ||||||
|  |  | ||||||
| 	MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(x11->w)); /* TODO: write this function to return a window handle... */ | 	MOO_STACK_SETRETTORCV (moo, nargs);  | ||||||
| 	return MOO_PF_SUCCESS; | 	return MOO_PF_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static moo_pfrc_t pf_win_kill_on (moo_t* moo, moo_ooi_t nargs) | ||||||
| /* ------------------------------------------------------------------------ */ |  | ||||||
|  |  | ||||||
| static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs) |  | ||||||
| { | { | ||||||
| 	MOO_STACK_SETRET (moo, nargs, moo->_nil);  | 	x11_t* x11; | ||||||
| MOO_DEBUG0 (moo, "x11.window.create....\n"); | 	x11_win_t* win; | ||||||
|  |  | ||||||
|  | 	x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETARG(moo, nargs, 0), MOO_NULL); | ||||||
|  | 	win = (x11_win_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); | ||||||
|  |  | ||||||
|  | 	if (!x11->c) | ||||||
|  | 	{ | ||||||
|  | 		MOO_STACK_SETRETTOERROR (moo, nargs); /* More specific error code*/ | ||||||
| 		return MOO_PF_SUCCESS; | 		return MOO_PF_SUCCESS; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| static moo_pfrc_t pf_win_destroy (moo_t* moo, moo_ooi_t nargs) | /* TODO: check on windows id */ | ||||||
| { |  | ||||||
| 	MOO_STACK_SETRET (moo, nargs, moo->_nil);  | 	xcb_unmap_window (x11->c, win->id); /* TODO: check error code */ | ||||||
| MOO_DEBUG0 (moo, "x11.window.destroy....\n"); | 	xcb_destroy_window (x11->c, win->id); | ||||||
|  | 	xcb_flush (x11->c); | ||||||
|  |  | ||||||
|  | 	MOO_STACK_SETRETTORCV (moo, nargs);  | ||||||
| 	return MOO_PF_SUCCESS; | 	return MOO_PF_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -253,8 +270,7 @@ MOO_DEBUG0 (moo, "x11.window.destroy....\n"); | |||||||
|  |  | ||||||
| static moo_pfinfo_t x11_pfinfo[] = | static moo_pfinfo_t x11_pfinfo[] = | ||||||
| { | { | ||||||
| 	{ I, { '_','_','g','e','t','e','v','e','n','t','\0'},                  0, pf_getevent      }, | 	{ I, { '_','g','e','t','e','v','e','n','t','\0'},                  0, pf_getevent      }, | ||||||
| 	{ I, { '_','_','m','a','k','e','w','i','n','\0'},                      0, pf_makewin       }, |  | ||||||
| 	{ I, { 'c','o','n','n','e','c','t','\0' },                         0, pf_connect       }, | 	{ I, { 'c','o','n','n','e','c','t','\0' },                         0, pf_connect       }, | ||||||
| 	{ I, { 'd','i','s','c','o','n','n','e','c','t','\0' },             0, pf_disconnect    }, | 	{ I, { 'd','i','s','c','o','n','n','e','c','t','\0' },             0, pf_disconnect    }, | ||||||
| 	{ I, { 'g','e','t','f','d','\0' },                                 0, pf_getfd         } | 	{ I, { 'g','e','t','f','d','\0' },                                 0, pf_getfd         } | ||||||
| @ -291,14 +307,15 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) | |||||||
|  |  | ||||||
| static moo_pfinfo_t x11_win_pfinfo[] = | static moo_pfinfo_t x11_win_pfinfo[] = | ||||||
| { | { | ||||||
| 	{ I, { 'c','r','e','a','t','e','\0' },                                 0, pf_win_create        }, | 	{ I, { '_','m','a','k','e','_','o','n',':','\0' },        0, pf_win_make_on       }, | ||||||
| 	{ I, { 'd','i','s','t','r','o','y','\0' },                             0, pf_win_destroy       } | 	{ I, { '_','k','i','l','l','_','o','n',':','\0' },        0, pf_win_kill_on       } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) | static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) | ||||||
| { | { | ||||||
| 	if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; | 	if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; | ||||||
| 	return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo)); | 	/*return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo));*/ | ||||||
|  | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| static moo_pfimpl_t x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) | static moo_pfimpl_t x11_win_query (moo_t* moo, moo_mod_t* mod, const moo_ooch_t* name) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user