コード例 #1
0
FILEMONITOR_PROC( void, EndMonitor )( PMONITOR monitor )
{
	if( !monitor )
		return;
	if( monitor->flags.bDispatched || monitor->flags.bScanning )
	{
		monitor->flags.bEnd = 1;
		return;
	}
	if( monitor->flags.bClosing )
	{
		if( l.flags.bLog ) Log( WIDE("Monitor already closing...") );
		return;
	}
	EnterCriticalSec( &monitor->cs );
	monitor->flags.bClosing = 1;
	monitor->flags.bRemoveFromEvents = 1;

	if( !monitor->flags.bRemovedFromEvents )
	{
		SetEvent( l.hMonitorThreadControlEvent );
		while( !monitor->flags.bRemovedFromEvents )
			Relinquish();
	}
	//Log1( WIDE("Closing the monitor on %s and killing thread...")
	//    , monitor->directory );
	if( monitor->hChange != INVALID_HANDLE_VALUE )
	{
		lprintf( WIDE( "close ntoification (wakes thread?" ) );
		FindCloseChangeNotification( monitor->hChange );
		lprintf( WIDE( "and then we wait..." ) );
	}
	monitor->hChange = INVALID_HANDLE_VALUE;
	{
		uint32_t tick = timeGetTime();
		while( monitor->pThread && ( ( tick+50 ) > timeGetTime() ) )
			Relinquish();
	}
	if( monitor->pThread )
	{
		EndThread( monitor->pThread );
	}
	//else
	//	Log( WIDE("Thread already left...") );
	CloseFileMonitors( monitor );
	RemoveTimer( monitor->timer );
	UnlinkThing( monitor );
	LeaveCriticalSec( &monitor->cs );
	Release( monitor );
}
コード例 #2
0
int main( int argc, char **argv )
{
   int i;
	SetSystemLog( SYSLOG_FILE, stdout );
	g.pdi = GetDisplayInterface();
	g.pii = GetImageInterface();
	g.x = 10;
	g.y = 10;
   for( i = 1; i < argc; i++ )
	{
      AddImage( argv[i] );
	}

	while( !g.flags.exit )
		Relinquish(); // hmm what do we have to do here?
	{
		PIMAGE_DISPLAY pdi;
		pdi = g.images;
		while( pdi )
		{
			CloseDisplay( pdi->display );
			UnmakeImageFile( pdi->Loaded );
         pdi = pdi->next;
		}
	}
   return 0;
}
コード例 #3
0
				/*
				 * this code would ideally check to see if
				 * the cpu rdtsc instruction worked....
				 * someday we should consider using the rdtscp instruction
				 * but that will require fetching CPU characteristics
             * - SEE mmx.asm in src/imglib/
             */
void TestCPUTick( void )
{
	uint64_t tick, _tick;
	int n;
	bCPUTickWorks = 1;
	_tick = tick = GetCPUTick();
	for( n = 0; n < 10000000; n++ )
	{
#ifdef GCC
      //asm( "cpuid\n" );
#endif
		tick = GetCPUTick();
		if( tick > _tick )
		{
			//lprintf( "%020Ld %020Ld", _tick, tick );
			_tick = tick;
		}
		else
		{
         lprintf( "CPU TICK FAILED!" );
			bCPUTickWorks = 0;
         break;
		}
		Relinquish();
	}
}
コード例 #4
0
uintptr_t CPROC ProcessDisplayMessages( PTHREAD thread )
{
	XEvent event;
	struct display_camera *camera;
	INDEX idx;
	struct display_camera *did_one;
	LoadOptions(); // loads camera config, and logging options...
	SACK_Vidlib_OpenCameras();  // create logical camera structures
	l.bThreadRunning = 1;
	while( !l.bExitThread )
	{
		did_one = NULL;
		LIST_FORALL( l.cameras, idx, struct display_camera *, camera )
		{
		//lprintf( "Checking Thread %Lx", GetThreadID( MakeThread() ) );
			if( !camera->hVidCore )
            continue;
			GLWindow *x11_gl_window = camera->hVidCore->x11_gl_window;
			if( !x11_gl_window && ( l.bottom ) )
			{
				x11_gl_window = createGLWindow( camera );  // opens the physical device
			}
			//lprintf( "is it %Lx?", GetThreadID( thread ) );
			if( x11_gl_window && x11_gl_window->dpy )
			{
				did_one = camera;
				while( XPending( x11_gl_window->dpy ) > 0 )
				{
					XNextEvent(x11_gl_window->dpy, &event);
					//if( l.flags.bLogMessageDispatch )
					//	lprintf( WIDE("(E)Got message:%d"), event.type );
					HandleMessage( camera->hVidCore, x11_gl_window, &event );
					//if( l.flags.bLogMessageDispatch )
					//	lprintf( WIDE("(X)Got message:%d"), event.type );
				}
				//lprintf( "Draw GL..." );
				//drawGLScene( camera, x11_gl_window );

				//  calls Update; moves the camera if it has a motion...
				// does a global tick then draws all cameras
				// returns if draw should be done; might step and draw one message
				// loop for each camera instead
				ProcessGLDraw( TRUE );
			}
			
			
		}
		if( !did_one )
			WakeableSleep( 1000 );
      else
			Relinquish();
	}
	return 1;
}
コード例 #5
0
uintptr_t CPROC Thread1( PTHREAD thread )
{
   while( 1 )
	if( !pc )
	{
      EnterCriticalSec( &cs );
		pc = CreateFrame( "test frame", 0, 0, 256, 256, 0, NULL );
      DisplayFrame( pc );
      LeaveCriticalSec( &cs );
	}
	else
      Relinquish();
   return 0;
}
コード例 #6
0
uintptr_t CPROC Thread2( PTHREAD thread )
{
   while( 1 )
	if( pc )
	{
      EnterCriticalSec( &cs );
		DestroyFrame( &pc );
      LeaveCriticalSec( &cs );

	}
	else
      Relinquish();
   return 0;
}
コード例 #7
0
void TCPTest1000Byte( void )
{
	int n;
   uint32_t sec = time(NULL);
	while( (sec+5) > time(NULL) )
	//for( n = 0; n < 10000; n++ )
	{
		l.waiting = 1;

		SetTick( l.start );
		SendTCP( l.pClient, l.data, 1000 );
	// have to wait here until the responce is received.
		while( l.waiting )
         Relinquish();
	}
   DumpStats();
}
コード例 #8
0
int main( int argc, char** argv )
{
	SOCKADDR *sa;
   int n;
	if( argc < 2 )
	{
		printf( "usage: %s <Telnet IP[:port]>\n", argv[0] );
		return 0;
	}
	SystemLog( "Starting the network" );
	NetworkStart();
	SystemLog( "Started the network" );
   sa = CreateSockAddress( argv[1], 23 );
	//if( argc >= 3 ) port = atoi( argv[2] ); else port = 23;
	pc_user = OpenTCPClientAddrExx( sa, ReadComplete, Closed, NULL, Connected );

	if( !pc_user )
	{
		SystemLog( "Failed to open some port as telnet" );
		printf( "failed to open %s%s\n", argv[1], strchr(argv[1],':')?"":":telnet[23]" );
		return 0;
	}
	for( n = 0; n < 1000; n++ )
	{
		if( (rand() & 3) != 0 )
		{
         WakeableSleep( rand() %1000 );
		}
      lprintf( "..." );
		RemoveClient( pc_user );
		pc_user = OpenTCPClientAddrExx( sa, ReadComplete, Closed, NULL, Connected );
		lprintf( "..." );
		if( (rand() &3) < 3 )
		{
         fflush( stdout );
			while( !connected )
				Relinquish();
		}
		if( connected )
		{
         lprintf( "send." );
			SendTCP( pc_user, "test", 4 );
		}
	}
	return -1;
}
コード例 #9
0
static uintptr_t CPROC HandleTaskOutput(PTHREAD thread )
{
	PTASK_INFO task = (PTASK_INFO)GetThreadParam( thread );
	{
		task->pOutputThread = thread;
		// read input from task, montiro close and dispatch TaskEnd Notification also.
		{
			PHANDLEINFO phi = &task->hStdOut;
			PTEXT pInput = SegCreate( 4096 );
			int done, lastloop;
			Hold( task );
			done = lastloop = FALSE;
			do
			{
				uint32_t dwRead, dwAvail;
				if( done )
					lastloop = TRUE;
#ifdef _WIN32
				//while(  )
				{

#else
					while( CanRead( phi->handle ) )
#endif
					{
						if( task->flags.log_input )
							lprintf( WIDE( "Go to read task's stdout." ) );
#ifdef _WIN32
						if( !task->flags.process_ended &&
							 ReadFile( phi->handle
										, GetText( pInput ), (DWORD)(GetTextSize( pInput ) - 1)
										, (LPDWORD)&dwRead, NULL ) )  //read the  pipe
						{
#else
							dwRead = read( phi->handle
											 , GetText( pInput )
											 , GetTextSize( pInput ) - 1 );
							if( !dwRead )
							{
#ifdef _DEBUG
												//lprintf( WIDE( "Ending system thread because of broke pipe! %d" ), errno );
#endif
#ifdef WIN32
								continue;
#else
												//lprintf( WIDE( "0 read = pipe failure." ) );
								break;
#endif
							}
#endif
							if( task->flags.log_input )
								lprintf( WIDE( "got read on task's stdout: %d" ), dwRead );
							if( task->flags.bSentIoTerminator )
							{
								if( dwRead > 1 )
									dwRead--;
								else
								{
									if( task->flags.log_input )
										lprintf( WIDE( "Finished, no more data, task has ended; no need for once more around" ) );
									lastloop = 1;
									break; // we're done; task ended, and we got an io terminator on XP
								}
							}
							//lprintf( WIDE( "result %d" ), dwRead );
							GetText( pInput )[dwRead] = 0;
							pInput->data.size = dwRead;
							//LogBinary( GetText( pInput ), GetTextSize( pInput ) );
							if( task->OutputEvent )
							{
								task->OutputEvent( task->psvEnd, task, GetText( pInput ), GetTextSize( pInput ) );
							}
							pInput->data.size = 4096;
#ifdef _WIN32
						}
						else
						{
							DWORD dwError = GetLastError();
							if( ( dwError == ERROR_OPERATION_ABORTED ) && task->flags.process_ended )
							{
								if( PeekNamedPipe( phi->handle, NULL, 0, NULL, (LPDWORD)&dwAvail, NULL ) )
								{
									if( dwAvail > 0 )
									{
										lprintf( WIDE( "caught data" ) );
										// there is still data in the pipe, just that the process closed
										// and we got the sync even before getting the data.
									}
									else
										break;
								}
							}
						}
#endif
					}
#ifdef _WIN32
				}
#endif
				//allow a minor time for output to be gathered before sending
				// partial gathers...
				if( task->flags.process_ended )
#ifdef _WIN32
				{
					// Ending system thread because of process exit!
					done = TRUE;
				}
#else
				//if( !dwRead )
				//	break;
				if( task->pid == waitpid( task->pid, NULL, WNOHANG ) )
				{
					Log( WIDE( "Setting done event on system reader." ) );
					done = TRUE; // do one pass to make sure we completed read
				}
				else
				{
					//lprintf( WIDE( "process active..." ) );
					Relinquish();
				}
#endif
			}
			while( !lastloop );
#ifdef _DEBUG
			if( lastloop )
			{
				//DECLTEXT( msg, WIDE( "Ending system thread because of process exit!" ) );
				//EnqueLink( phi->pdp->&ps->Command->Output, &msg );
			}
			else
			{
				//DECLTEXT( msg, WIDE( "Guess we exited from broken pipe" ) );
				//EnqueLink( phi->pdp->&ps->Command->Output, &msg );
			}
#endif
			LineRelease( pInput );
#ifdef _WIN32
			CloseHandle( task->hReadIn );
			CloseHandle( task->hReadOut );
			CloseHandle( task->hWriteIn );
			CloseHandle( task->hWriteOut );
			//lprintf( WIDE( "Closing process handle %p" ), task->pi.hProcess );
			phi->hThread = 0;
#else
			//close( phi->handle );
			close( task->hStdIn.pair[1] );
			close( task->hStdOut.pair[0] );
         //close( task->hStdErr.pair[0] );
#define INVALID_HANDLE_VALUE -1
#endif
			if( phi->handle == task->hStdIn.handle )
				task->hStdIn.handle = INVALID_HANDLE_VALUE;
			phi->handle = INVALID_HANDLE_VALUE;
			task->pOutputThread = NULL;

			Release( task );
			//WakeAThread( phi->pdp->common.Owner );
			return 0xdead;
		}
	}
}
コード例 #10
0
 void  BlotScaledImageSizedEx ( ImageFile *pifDest, ImageFile *pifSrc
                                    , int32_t xd, int32_t yd
                                    , uint32_t wd, uint32_t hd
                                    , int32_t xs, int32_t ys
                                    , uint32_t ws, uint32_t hs
                                    , uint32_t nTransparent
                                    , uint32_t method, ... )
     // integer scalar... 0x10000 = 1
{
	CDATA *po, *pi;
	static uint32_t lock;
	uint32_t  oo;
	uint32_t srcwidth;
	int errx, erry;
	uint32_t dhd, dwd, dhs, dws;
	va_list colors;
	va_start( colors, method );
	//lprintf( WIDE("Blot enter (%d,%d)"), _wd, _hd );
	if( nTransparent > ALPHA_TRANSPARENT_MAX )
	{
		return;
	}
	if( !pifSrc ||  !pifDest
	   || !pifSrc->image //|| !pifDest->image
	   || !wd || !hd || !ws || !hs )
	{
		return;
	}

	if( ( xd > ( pifDest->x + pifDest->width ) )
	  || ( yd > ( pifDest->y + pifDest->height ) )
	  || ( ( xd + (signed)wd ) < pifDest->x )
		|| ( ( yd + (signed)hd ) < pifDest->y ) )
	{
		return;
	}
	dhd = hd;
	dhs = hs;
	dwd = wd;
	dws = ws;

	// ok - how to figure out how to do this
	// need to update the position and width to be within the 
	// the bounds of pifDest....
	//lprintf(" begin scaled output..." );
	errx = -(signed)dwd;
	erry = -(signed)dhd;

	if( xd < pifDest->x )
	{
		while( xd < pifDest->x )
		{
			errx += (signed)dws;
			while( errx >= 0 )
			{
	            errx -= (signed)dwd;
				ws--;
				xs++;
			}
			wd--;
			xd++;
		}
	}
	//Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), 
	//       xs, ys, ws, hs, xd, yd, wd, hd );
	if( yd < pifDest->y )
	{
		while( yd < pifDest->y )
		{
			erry += (signed)dhs;
			while( erry >= 0 )
			{
				erry -= (signed)dhd;
				hs--;
				ys++;
			}
			hd--;
			yd++;
		}
	}
	//Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), 
	//       xs, ys, ws, hs, xd, yd, wd, hd );
	if( ( xd + (signed)wd ) > ( pifDest->x + pifDest->width) )
	{
		//int newwd = TOFIXED(pifDest->width);
		//ws -= ((int64_t)( (int)wd - newwd)* (int64_t)ws )/(int)wd;
		wd = ( pifDest->x + pifDest->width ) - xd;
	}
	//Log8( WIDE("Blot scaled params: %d %d %d %d / %d %d %d %d "), 
	//       xs, ys, ws, hs, xd, yd, wd, hd );
	if( ( yd + (signed)hd ) > (pifDest->y + pifDest->height) )
	{
		//int newhd = TOFIXED(pifDest->height);
		//hs -= ((int64_t)( hd - newhd)* hs )/hd;
		hd = (pifDest->y + pifDest->height) - yd;
	}
	if( (int32_t)wd <= 0 ||
       (int32_t)hd <= 0 ||
       (int32_t)ws <= 0 ||
		 (int32_t)hs <= 0 )
	{
		return;
	}
   
	//Log9( WIDE("Image locations: %d(%d %d) %d(%d) %d(%d) %d(%d)")
	//          , xs, FROMFIXED(xs), FIXEDPART(xs)
	//          , ys, FROMFIXED(ys)
	//          , xd, FROMFIXED(xd)
	//          , yd, FROMFIXED(yd) );
#ifdef _INVERT_IMAGE
	// set pointer in to the starting x pixel
	// on the last line of the image to be copied 
	pi = IMG_ADDRESS( pifSrc, (xs), (ys) );
	po = IMG_ADDRESS( pifDest, (xd), (yd) );
	oo = 4*(-((signed)wd) - (pifDest->pwidth) ); // w is how much we can copy...
	// adding in multiple of 4 because it's C...
	srcwidth = -(4* pifSrc->pwidth);
#else
	// set pointer in to the starting x pixel
	// on the first line of the image to be copied...
	pi = IMG_ADDRESS( pifSrc, (xs), (ys) );
	po = IMG_ADDRESS( pifDest, (xd), (yd) );
	oo = 4*(pifDest->pwidth - (wd)); // w is how much we can copy...
	// adding in multiple of 4 because it's C...
	srcwidth = 4* pifSrc->pwidth;
#endif
	while( LockedExchange( &lock, 1 ) )
		Relinquish();
   //Log8( WIDE("Do blot work...%d(%d),%d(%d) %d(%d) %d(%d)")
   //    , ws, FROMFIXED(ws), hs, FROMFIXED(hs) 
	//    , wd, FROMFIXED(wd), hd, FROMFIXED(hd) );

	if( ( pifDest->flags & IF_FLAG_FINAL_RENDER )
		&& !( pifDest->flags & IF_FLAG_IN_MEMORY ) )
	{
		int updated = 0;
		Image topmost_parent;

		// closed loop to get the top imgae size.
		for( topmost_parent = pifSrc; topmost_parent->pParent; topmost_parent = topmost_parent->pParent );

		ReloadOpenGlTexture( pifSrc, 0 );
		if( !pifSrc->glActiveSurface )
		{
			lprintf( WIDE( "gl texture hasn't downloaded or went away?" ) );
			lock = 0;
			return;
		}
		//lprintf( WIDE( "use regular texture %p (%d,%d)" ), pifSrc, pifSrc->width, pifSrc->height );

		{
			int glDepth = 1;
			VECTOR v1[2], v3[2], v4[2], v2[2];
			int v = 0;
			double x_size, x_size2, y_size, y_size2;
			/*
			 * only a portion of the image is actually used, the rest is filled with blank space
			 *
			 */
			TranslateCoord( pifDest, &xd, &yd );
			TranslateCoord( pifSrc, &xs, &ys );

			v1[v][0] = xd;
			v1[v][1] = yd;
			v1[v][2] = 0.0;

			v2[v][0] = xd;
			v2[v][1] = yd+hd;
			v2[v][2] = 0.0;

			v3[v][0] = xd+wd;
			v3[v][1] = yd+hd;
			v3[v][2] = 0.0;

			v4[v][0] = xd+wd;
			v4[v][1] = yd;
			v4[v][2] = 0.0;

			x_size = (double) xs/ (double)topmost_parent->width;
			x_size2 = (double) (xs+ws)/ (double)topmost_parent->width;
			y_size = (double) ys/ (double)topmost_parent->height;
			y_size2 = (double) (ys+hs)/ (double)topmost_parent->height;

			while( pifDest && pifDest->pParent )
			{
				glDepth = 0;
				if( pifDest->transform )
				{
					Apply( pifDest->transform, v1[1-v], v1[v] );
					Apply( pifDest->transform, v2[1-v], v2[v] );
					Apply( pifDest->transform, v3[1-v], v3[v] );
					Apply( pifDest->transform, v4[1-v], v4[v] );
					v = 1-v;
				}
				pifDest = pifDest->pParent;
			}
			if( pifDest->transform )
			{
				Apply( pifDest->transform, v1[1-v], v1[v] );
				Apply( pifDest->transform, v2[1-v], v2[v] );
				Apply( pifDest->transform, v3[1-v], v3[v] );
				Apply( pifDest->transform, v4[1-v], v4[v] );
				v = 1-v;
			}
#if 0
			if( glDepth )
			{
				//lprintf( WIDE( "enqable depth..." ) );
				glEnable( GL_DEPTH_TEST );
			}
			else
			{
				//lprintf( WIDE( "disable depth..." ) );
				glDisable( GL_DEPTH_TEST );
			}
#endif
			glBindTexture(GL_TEXTURE_2D, pifSrc->glActiveSurface);				// Select Our Texture
			if( method == BLOT_COPY )
				glColor4ub( 255,255,255,255 );
			else if( method == BLOT_SHADED )
			{
				CDATA tmp = va_arg( colors, CDATA );
				glColor4ubv( (GLubyte*)&tmp );
			}
			else if( method == BLOT_MULTISHADE )
			{
#if !defined( __ANDROID__ )
				InitShader();
				if( glUseProgram && l.glActiveSurface->shader.multi_shader )
				{
					int err;
					CDATA r = va_arg( colors, CDATA );
					CDATA g = va_arg( colors, CDATA );
					CDATA b = va_arg( colors, CDATA );
		 			glEnable(GL_FRAGMENT_PROGRAM_ARB);
					glUseProgram( l.glActiveSurface->shader.multi_shader );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 0, (float)GetRedValue( r )/255.0f, (float)GetGreenValue( r )/255.0f, (float)GetBlueValue( r )/255.0f, (float)GetAlphaValue( r )/255.0f );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 1, (float)GetRedValue( g )/255.0f, (float)GetGreenValue( g )/255.0f, (float)GetBlueValue( g )/255.0f, (float)GetAlphaValue( g )/255.0f );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, (float)GetRedValue( b )/255.0f, (float)GetGreenValue( b )/255.0f, (float)GetBlueValue( b )/255.0f, (float)GetAlphaValue( b )/255.0f );					
					err = glGetError();
				}
				else
#endif
				{
					Image output_image;
					CDATA r = va_arg( colors, CDATA );
					CDATA g = va_arg( colors, CDATA );
					CDATA b = va_arg( colors, CDATA );
					output_image = GetShadedImage( pifSrc, r, g, b );
					glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface );
					glColor4ub( 255,255,255,255 );
				}
			}
			else if( method == BLOT_INVERTED )
			{
#if !defined( __ANDROID__ )
				InitShader();
				if( l.glActiveSurface->shader.inverse_shader )
				{
					int err;
					//lprintf( WIDE( "HAVE SHADER %d" ), l.glActiveSurface->shader.inverse_shader );
					glEnable(GL_FRAGMENT_PROGRAM_ARB);
					glUseProgram( l.glActiveSurface->shader.inverse_shader );
					err = glGetError();
				}
				else
#endif
				{
					Image output_image;
					//lprintf( WIDE( "DID NOT HAVE SHADER" ) );
					output_image = GetInvertedImage( pifSrc );
					glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface );
					glColor4ub( 255,255,255,255 );
				}
			}

			glBegin(GL_TRIANGLE_STRIP);
			//glBegin(GL_QUADS);
			// Front Face
			//glColor4ub( 255,120,32,192 );
			scale( v1[v], v1[v], l.scale );
			scale( v2[v], v2[v], l.scale );
			scale( v3[v], v3[v], l.scale );
			scale( v4[v], v4[v], l.scale );
			glTexCoord2f(x_size, y_size); glVertex3fv(v1[v]);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(x_size, y_size2); glVertex3fv(v2[v]);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(x_size2, y_size); glVertex3fv(v4[v]);	// Top Left Of The Texture and Quad
			glTexCoord2f(x_size2, y_size2); glVertex3fv(v3[v]);	// Top Right Of The Texture and Quad
			// Back Face
			glEnd();
#if !defined( __ANDROID__ )
			if( method == BLOT_MULTISHADE )
			{
				if( l.glActiveSurface->shader.multi_shader )
				{
 					glDisable(GL_FRAGMENT_PROGRAM_ARB);
				}
			}
			else if( method == BLOT_INVERTED )
			{
				if( l.glActiveSurface->shader.inverse_shader )
				{
 					glDisable(GL_FRAGMENT_PROGRAM_ARB);
				}
			}
#endif
			glBindTexture(GL_TEXTURE_2D, 0);				// Select Our Texture
		}
	}

	else switch( method )
	{
	case BLOT_COPY:
		if( !nTransparent )
			cBlotScaledT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth );       
		else if( nTransparent == 1 )
			cBlotScaledT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth );       
		else if( nTransparent & ALPHA_TRANSPARENT )
			cBlotScaledTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF );
		else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
			cBlotScaledTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF );        
		else
			cBlotScaledTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent );        
		break;
	case BLOT_SHADED:
		if( !nTransparent )
			cBlotScaledShadedT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, va_arg( colors, CDATA ) );
		else if( nTransparent == 1 )
			cBlotScaledShadedT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, va_arg( colors, CDATA ) );
		else if( nTransparent & ALPHA_TRANSPARENT )
			cBlotScaledShadedTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF, va_arg( colors, CDATA ) );
		else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
			cBlotScaledShadedTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent&0xFF, va_arg( colors, CDATA ) );
		else
			cBlotScaledShadedTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth, nTransparent, va_arg( colors, CDATA ) );
		break;
	case BLOT_MULTISHADE:
		{
			CDATA r,g,b;
			r = va_arg( colors, CDATA );
			g = va_arg( colors, CDATA );
			b = va_arg( colors, CDATA );
			if( !nTransparent )
				cBlotScaledMultiT0( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth
									  , r, g, b );
			else if( nTransparent == 1 )
				cBlotScaledMultiT1( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth
									  , r, g, b );
			else if( nTransparent & ALPHA_TRANSPARENT )
				cBlotScaledMultiTImgA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth
										  , nTransparent & 0xFF
										  , r, g, b );
			else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
				cBlotScaledMultiTImgAI( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth
											, nTransparent & 0xFF
											, r, g, b );
			else
				cBlotScaledMultiTA( po, pi, errx, erry, wd, hd, dwd, dhd, dws, dhs, oo, srcwidth
									  , nTransparent
									  , r, g, b );
		}
		break;
	}
	lock = 0;
//   Log( WIDE("Blot done") );
}
コード例 #11
0
ファイル: Port.cpp プロジェクト: robotology-legacy/yarp1
///
/// this commands the port to terminate gracefully.
int Port::SaySelfEnd(void)
{
	int result = YARP_FAIL;
	if (self_id == NULL && name.c_str()[0] != '\0')
	{
		if (protocol_type == YARP_MCAST)
		{
			self_id = YARPNameService::LocateName(name.c_str(), network_name.c_str(), YARP_UDP);
			self_id->setServiceType (YARP_TCP);

			YARPEndpointManager::CreateOutputEndpoint (*self_id);
			YARPEndpointManager::ConnectEndpoints (*self_id, name);
		}
		else
		{
			self_id = YARPNameService::LocateName(name.c_str(), network_name.c_str(), protocol_type);
			if (self_id->getServiceType() != YARP_QNET)
				self_id->setServiceType (YARP_TCP);

			YARPEndpointManager::CreateOutputEndpoint (*self_id);
			YARPEndpointManager::ConnectEndpoints (*self_id, name);
		}
	}
	else
	/// silly but to guarantee self_id is !NULL.
	if (self_id != NULL && !self_id->isValid() && name.c_str()[0] != '\0')
	{
		if (protocol_type == YARP_MCAST)
		{
			self_id = YARPNameService::LocateName(name.c_str(), network_name.c_str(), YARP_UDP);
			self_id->setServiceType (YARP_TCP);

			YARPEndpointManager::CreateOutputEndpoint (*self_id);
			YARPEndpointManager::ConnectEndpoints (*self_id, name);
		}
		else
		{
			self_id = YARPNameService::LocateName(name.c_str(), network_name.c_str(), protocol_type);
			if (self_id->getServiceType() != YARP_QNET)
				self_id->setServiceType (YARP_TCP);

			YARPEndpointManager::CreateOutputEndpoint (*self_id);
			YARPEndpointManager::ConnectEndpoints (*self_id, name);
		}
	}

	if (self_id != NULL)
	{
		if (self_id->isValid())
		{
			// need to make sure the detach message will be read,
			// even if other messages are arriving

			Relinquish();
			out_mutex.Wait();
			ignore_data = 1;
			out_mutex.Post();
			Relinquish();

			result = SendHelper (*self_id, NULL, 0, MSG_ID_DETACH_ALL);
		}

		Relinquish();
		/// wait for message to be received.
		complete_msg_thread.Wait();

		/// deletes the endpoint.
		YARPEndpointManager::Close (*self_id);

		YARPNameService::DeleteName (self_id);
		self_id = NULL;

		///YARPScheduler::yield();

		/// tell the main thread to complete the termination function.
		complete_terminate.Signal();

		YARPThread::Join ();
	}

	return result;
}
コード例 #12
0
ファイル: hgstream.cpp プロジェクト: alistairmcmillan/frhed
void HGlobalStream::Reset()
{
	if (HGLOBAL hGlobal = Relinquish())
		GlobalFree(hGlobal);
}
コード例 #13
0
CLIENTMSG_PROC( void, UnloadService )( CTEXTSTR name )
{
	PEVENTHANDLER pHandler;
	pHandler = g.pHandlers;
	while( pHandler )
	{
		if( StrCaseCmp( pHandler->servicename, name ) == 0 )
			break;
		pHandler = pHandler->next;
	}
	if( pHandler )
	{
		MSGIDTYPE Responce;
		//lprintf( WIDE("Unload service: %s"), pHandler->servicename );
		if( pHandler->flags.local_service )
		{
			//lprintf( WIDE("Local service... resulting quick success...") );
			Responce = (MSG_ServiceUnload)|SERVER_SUCCESS;
		}
		else
		{
			//lprintf( WIDE("Requesting message %d from %d "), MSG_ServiceUnload , pHandler->MsgBase );
			Responce = ((MSG_ServiceUnload)|SERVER_SUCCESS);
			if( !TransactServerMessage( &pHandler->RouteID
											  , MSG_ServiceUnload, NULL, 0
											  , &Responce/*NULL*/, NULL, 0 ) )
			{
				lprintf( WIDE("Transaction to ServiceUnload failed...") );
			}
			else if( Responce != ((MSG_ServiceUnload)|SERVER_SUCCESS) )
			{
				lprintf( WIDE("Server reports it failed to unload the service %08") _MsgID_f WIDE(" %08") _MsgID_f WIDE("")
						 , Responce, (MSGIDTYPE)((MSG_ServiceUnload)|SERVER_SUCCESS) );
			// no matter what the result, this must still release this
			// resource....
			//return;
			}
			while( pHandler->flags.dispatched )
			{
				Relinquish();
			}
		}

		UnlinkThing( pHandler );

		//lprintf( WIDE("Release? wow release hangs forever?") );
		//Release( pHandler );
		if( 0 && !g.pHandlers )
		{
			Log( WIDE("No more services loaded - killing threads, disconnecting") );
			if( g.pLocalEventThread )
			{
				EndThread( g.pLocalEventThread );
				// wake up the thread...
			}
			if( g.pEventThread )
				EndThread( g.pEventThread );
			if( g.pThread )
				EndThread( g.pThread );

			CloseMessageQueues();
			g.flags.events_ready = 0;
			g.flags.local_events_ready = 0;
			g.flags.failed = 0;
			g.flags.message_handler_ready = 0;
			g.flags.message_responce_handler_ready = 0;
		}
		//Log( WIDE("Done unloading services...") );
		return;
	}
	Log( WIDE("Service was already Unloaded!?!?!?!?!?") );
}
コード例 #14
0
//---------------------------------------------------------------------------
// x, y is position
// xs, ys is starting position on source bitmap (x, y is upper left) + xs, ys )
// w, h is height and width of the image to use.
// default behavior is to omit copying 0 pixels for transparency
// overlays....
 void  BlotImageSizedEx ( ImageFile *pifDest, ImageFile *pifSrc
                              , int32_t xd, int32_t yd
                              , int32_t xs, int32_t ys
                              , uint32_t ws, uint32_t hs
                              , uint32_t nTransparent
                              , uint32_t method
                              , ... )
{
#define BROKEN_CODE
	PCDATA po, pi;
	//int  hd, wd;
	uint32_t oo, oi; // treated as an adder... it is unsigned by math, but still results correct offset?
	static uint32_t lock;
	va_list colors;
	va_start( colors, method );
	if( nTransparent > ALPHA_TRANSPARENT_MAX )
		return;

	if(  !pifSrc
		|| !pifSrc->image
		|| !pifDest
		//|| !pifDest->image

	  )
	{
		// this will happen when mixing modes...
		lprintf( WIDE( "sanity check failed %p %p %p" ), pifSrc, pifDest, pifSrc?pifSrc->image:NULL );
		return;
	}
	//lprintf( WIDE( "BlotImageSized %d,%d to %d,%d by %d,%d" ), xs, ys, xd, yd, ws, hs );

	{
		IMAGE_RECTANGLE r1;
		IMAGE_RECTANGLE r2;
		IMAGE_RECTANGLE rs;
		IMAGE_RECTANGLE rd;
		int tmp;
		//IMAGE_RECTANGLE r3;
		r1.x = xd;
		r1.y = yd;
		r1.width = ws;
		r1.height = hs;
		r2.x = pifDest->eff_x;
		r2.y = pifDest->eff_y;
		tmp = (pifDest->eff_maxx - pifDest->eff_x) + 1;
		if( tmp < 0 )
			r2.width = 0;
		else
			r2.width = (IMAGE_SIZE_COORDINATE)tmp;
		tmp = (pifDest->eff_maxy - pifDest->eff_y) + 1;
		if( tmp < 0 )
			r2.height = 0;
		else
			r2.height = (IMAGE_SIZE_COORDINATE)tmp;
		if( !IntersectRectangle( &rd, &r1, &r2 ) )
		{
			//lprintf( WIDE( "Images do not overlap. %d,%d %d,%d vs %d,%d %d,%d" ), r1.x,r1.y,r1.width,r1.height
			//		 , r2.x,r2.y,r2.width,r2.height);
			return;
		}

		//lprintf( WIDE( "Correcting coordinates by %d,%d" )
		//		 , rd.x - xd
		//		 , rd.y - yd
		//		 );

		xs += rd.x - xd;
		ys += rd.y - yd;
		tmp = rd.x - xd;
		if( tmp > 0 && (unsigned)tmp > ws )
			ws = 0;
		else
		{
			if( tmp < 0 )
				ws += (unsigned)-tmp;
			else
				ws -= (unsigned)tmp;
		}
		tmp = rd.y - yd;
		if( tmp > 0 && (unsigned)tmp > hs )
			hs = 0;
		else
		{
			if( tmp < 0 )
				hs += (unsigned)-tmp;
			else
				hs -= (unsigned)tmp;
		}
		//lprintf( WIDE( "Resulting dest is %d,%d %d,%d" ), rd.x,rd.y,rd.width,rd.height );
		xd = rd.x;
		yd = rd.y;
		r1.x = xs;
		r1.y = ys;
		r1.width = ws;
		r1.height = hs;
		r2.x = pifSrc->eff_x;
		r2.y = pifSrc->eff_y;
		tmp = (pifSrc->eff_maxx - pifSrc->eff_x) + 1;
		if( tmp < 0 )
			r2.width = 0;
		else
			r2.width = (IMAGE_SIZE_COORDINATE)tmp;
		tmp = (pifSrc->eff_maxy - pifSrc->eff_y) + 1;
		if( tmp < 0 )
			r2.height = 0;
		else
			r2.height = (IMAGE_SIZE_COORDINATE)tmp;
		if( !IntersectRectangle( &rs, &r1, &r2 ) )
		{
			lprintf( WIDE( "Desired Output does not overlap..." ) );
			return;
		}
		//lprintf( WIDE( "Resulting dest is %d,%d %d,%d" ), rs.x,rs.y,rs.width,rs.height );
		ws = rs.width<rd.width?rs.width:rd.width;
		hs = rs.height<rd.height?rs.height:rd.height;
		xs = rs.x;
		ys = rs.y;
		//lprintf( WIDE( "Resulting rect is %d,%d to %d,%d dim: %d,%d" ), rs.x, rs.y, rd.x, rd.y, rs.width, rs.height );
		//lprintf( WIDE( "Resulting rect is %d,%d to %d,%d dim: %d,%d" ), xs, ys, xd, yd, ws, hs );
	}
		//lprintf( WIDE(WIDE( "Doing image (%d,%d)-(%d,%d) (%d,%d)-(%d,%d)" )), xs, ys, ws, hs, xd, yd, wd, hd );
	if( (int32_t)ws <= 0 ||
        (int32_t)hs <= 0 /*||
        (int32_t)wd <= 0 ||
		(int32_t)hd <= 0 */ )
	{
		lprintf( WIDE( "out of bounds" ) );
		return;
	}
#ifdef _INVERT_IMAGE
	// set pointer in to the starting x pixel
	// on the last line of the image to be copied
	//pi = IMG_ADDRESS( pifSrc, xs, ys );
	//po = IMG_ADDRESS( pifDest, xd, yd );
	pi = IMG_ADDRESS( pifSrc, xs, ys );
	po = IMG_ADDRESS( pifDest, xd, yd );
//cpg 19 Jan 2007 2>c:\work\sack\src\imglib\blotdirect.c(492) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
//cpg 19 Jan 2007 2>c:\work\sack\src\imglib\blotdirect.c(493) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
	oo = 4*-(int)(ws+pifDest->pwidth);     // w is how much we can copy...
	oi = 4*-(int)(ws+pifSrc->pwidth); // adding remaining width...
#else
	// set pointer in to the starting x pixel
	// on the first line of the image to be copied...
	pi = IMG_ADDRESS( pifSrc, xs, ys );
	po = IMG_ADDRESS( pifDest, xd, yd );
	oo = 4*(pifDest->pwidth - ws);     // w is how much we can copy...
	oi = 4*(pifSrc->pwidth - ws); // adding remaining width...
#endif
	//lprintf( WIDE("Doing image (%d,%d)-(%d,%d) (%d,%d)-(%d,%d)"), xs, ys, ws, hs, xd, yd, wd, hd );
	//oo = 4*(pifDest->pwidth - ws);     // w is how much we can copy...
	//oi = 4*(pifSrc->pwidth - ws); // adding remaining width...
	while( LockedExchange( &lock, 1 ) )
		Relinquish();

	if( ( pifDest->flags & IF_FLAG_FINAL_RENDER )
		&& !( pifDest->flags & IF_FLAG_IN_MEMORY ) )
	{
		Image topmost_parent;

		ReloadOpenGlTexture( pifSrc, 0 );
		if( !pifSrc->glActiveSurface )
		{
	        //lprintf( WIDE( "gl texture hasn't updated or went away?" ) );
		    lock = 0;
			return;
		}
		//lprintf( WIDE( "use regular texture %p (%d,%d)" ), pifSrc, pifSrc->width, pifSrc->height );
      //DebugBreak();        g

		// closed loop to get the top imgae size.
		for( topmost_parent = pifSrc; topmost_parent->pParent; topmost_parent = topmost_parent->pParent );

		/*
		 * only a portion of the image is actually used, the rest is filled with blank space
		 *
		 */
		TranslateCoord( pifDest, &xd, &yd );
		TranslateCoord( pifSrc, &xs, &ys );
		{
			int glDepth = 1;
			double x_size, x_size2, y_size, y_size2;
			VECTOR v1[2], v3[2],v4[2],v2[2];
			int v = 0;

			v1[v][0] = xd;
			v1[v][1] = yd;
			v1[v][2] = 0.0;

			v2[v][0] = xd;
			v2[v][1] = yd+hs;
			v2[v][2] = 0.0;

			v3[v][0] = xd+ws;
			v3[v][1] = yd+hs;
			v3[v][2] = 0.0;

			v4[v][0] = xd+ws;
			v4[v][1] = yd;
			v4[v][2] = 0.0;

			x_size = (double) xs/ (double)topmost_parent->width;
			x_size2 = (double) (xs+ws)/ (double)topmost_parent->width;
			y_size = (double) ys/ (double)topmost_parent->height;
			y_size2 = (double) (ys+hs)/ (double)topmost_parent->height;
			// Front Face
			//glColor4ub( 255,120,32,192 );
			//lprintf( WIDE( "Texture size is %g,%g to %g,%g" ), x_size, y_size, x_size2, y_size2 );
			while( pifDest && pifDest->pParent )
			{
				glDepth = 0;
				if( pifDest->transform )
				{
					Apply( pifDest->transform, v1[1-v], v1[v] );
					Apply( pifDest->transform, v2[1-v], v2[v] );
					Apply( pifDest->transform, v3[1-v], v3[v] );
					Apply( pifDest->transform, v4[1-v], v4[v] );
					v = 1-v;
				}
				pifDest = pifDest->pParent;
			}
			if( pifDest->transform )
			{
				Apply( pifDest->transform, v1[1-v], v1[v] );
				Apply( pifDest->transform, v2[1-v], v2[v] );
				Apply( pifDest->transform, v3[1-v], v3[v] );
				Apply( pifDest->transform, v4[1-v], v4[v] );
				v = 1-v;
			}
#if 0
			if( glDepth )
			{
				//lprintf( WIDE( "enqable depth..." ) );
				glEnable( GL_DEPTH_TEST );
			}
			else
			{
				//lprintf( WIDE( "disable depth..." ) );
				glDisable( GL_DEPTH_TEST );
			}
#endif
			glBindTexture(GL_TEXTURE_2D, pifSrc->glActiveSurface);				// Select Our Texture
			if( method == BLOT_COPY )
				glColor4ub( 255,255,255,255 );
			else if( method == BLOT_SHADED )
			{
				CDATA tmp = va_arg( colors, CDATA );
				glColor4ubv( (GLubyte*)&tmp );
			}
			else if( method == BLOT_MULTISHADE )
			{
#if !defined( __ANDROID__ )
				InitShader();
				if( glUseProgram && l.glActiveSurface->shader.multi_shader )
				{
					int err;
					CDATA r = va_arg( colors, CDATA );
					CDATA g = va_arg( colors, CDATA );
					CDATA b = va_arg( colors, CDATA );
		 			glEnable(GL_FRAGMENT_PROGRAM_ARB);
					glUseProgram( l.glActiveSurface->shader.multi_shader );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 0, (float)GetRedValue( r )/255.0f, (float)GetGreenValue( r )/255.0f, (float)GetBlueValue( r )/255.0f, (float)GetAlphaValue( r )/255.0f );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 1, (float)GetRedValue( g )/255.0f, (float)GetGreenValue( g )/255.0f, (float)GetBlueValue( g )/255.0f, (float)GetAlphaValue( g )/255.0f );
					err = glGetError();
					glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, 2, (float)GetRedValue( b )/255.0f, (float)GetGreenValue( b )/255.0f, (float)GetBlueValue( b )/255.0f, (float)GetAlphaValue( b )/255.0f );					
					err = glGetError();
				}
				else
#endif
				{
					Image output_image;
					CDATA r = va_arg( colors, CDATA );
					CDATA g = va_arg( colors, CDATA );
					CDATA b = va_arg( colors, CDATA );
					output_image = GetShadedImage( pifSrc, r, g, b );
					glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface );
					glColor4ub( 255,255,255,255 );
				}
			}
			else if( method == BLOT_INVERTED )
			{
#if !defined( __ANDROID__ )
				InitShader();
				if( l.glActiveSurface->shader.inverse_shader )
				{
					int err;
		 			glEnable(GL_FRAGMENT_PROGRAM_ARB);
					glUseProgram( l.glActiveSurface->shader.inverse_shader );
					err = glGetError();
				}
				else
#endif
				{
					Image output_image;
					output_image = GetInvertedImage( pifSrc );
					glBindTexture( GL_TEXTURE_2D, output_image->glActiveSurface );
					glColor4ub( 255,255,255,255 );
				}
			}
			glBegin(GL_TRIANGLE_STRIP);
			//glBegin(GL_QUADS);
			scale( v1[v], v1[v], l.scale );
			scale( v2[v], v2[v], l.scale );
			scale( v3[v], v3[v], l.scale );
			scale( v4[v], v4[v], l.scale );
			glTexCoord2f(x_size, y_size); glVertex3fv(v1[v]);	// Bottom Left Of The Texture and Quad
			glTexCoord2f(x_size, y_size2); glVertex3fv(v2[v]);	// Top Left Of The Texture and Quad
			glTexCoord2f(x_size2, y_size); glVertex3fv(v4[v]);	// Bottom Right Of The Texture and Quad
			glTexCoord2f(x_size2, y_size2); glVertex3fv(v3[v]);	// Top Right Of The Texture and Quad
			// Back Face
			glEnd();
#if !defined( __ANDROID__ )
			if( method == BLOT_MULTISHADE )
			{
				if( l.glActiveSurface->shader.multi_shader )
				{
 					glDisable(GL_FRAGMENT_PROGRAM_ARB);
				}
			}
			else if( method == BLOT_INVERTED )
			{
				if( l.glActiveSurface->shader.inverse_shader )
				{
 					glDisable(GL_FRAGMENT_PROGRAM_ARB);
				}
			}
#endif
			glBindTexture(GL_TEXTURE_2D, 0);				// Select Our Texture
		}
	}
	else
	{
		switch( method )
		{
		case BLOT_COPY:
			if( !nTransparent )
				CopyPixelsT0( po, pi, oo, oi, ws, hs );
			else if( nTransparent == 1 )
				CopyPixelsT1( po, pi, oo, oi, ws, hs );
			else if( nTransparent & ALPHA_TRANSPARENT )
				CopyPixelsTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF);
			else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
				CopyPixelsTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF );
			else
				CopyPixelsTA( po, pi, oo, oi, ws, hs, nTransparent );
			break;
		case BLOT_SHADED:
			if( !nTransparent )
				CopyPixelsShadedT0( po, pi, oo, oi, ws, hs
                           , va_arg( colors, CDATA ) );
			else if( nTransparent == 1 )
				CopyPixelsShadedT1( po, pi, oo, oi, ws, hs
                           , va_arg( colors, CDATA ) );
			else if( nTransparent & ALPHA_TRANSPARENT )
				CopyPixelsShadedTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF
                           , va_arg( colors, CDATA ) );
			else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
				CopyPixelsShadedTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF
                           , va_arg( colors, CDATA ) );
			else
				CopyPixelsShadedTA( po, pi, oo, oi, ws, hs, nTransparent
                           , va_arg( colors, CDATA ) );
			break;
		case BLOT_MULTISHADE:
			{
				CDATA r,g,b;
				r = va_arg( colors, CDATA );
				g = va_arg( colors, CDATA );
				b = va_arg( colors, CDATA );
				//lprintf( WIDE( "r g b %08x %08x %08x" ), r,g, b );
				if( !nTransparent )
					CopyPixelsMultiT0( po, pi, oo, oi, ws, hs
										  , r, g, b );
				else if( nTransparent == 1 )
					CopyPixelsMultiT1( po, pi, oo, oi, ws, hs
										  , r, g, b );
				else if( nTransparent & ALPHA_TRANSPARENT )
					CopyPixelsMultiTImgA( po, pi, oo, oi, ws, hs, nTransparent & 0xFF
											  , r, g, b );
				else if( nTransparent & ALPHA_TRANSPARENT_INVERT )
					CopyPixelsMultiTImgAI( po, pi, oo, oi, ws, hs, nTransparent & 0xFF
												, r, g, b );
				else
					CopyPixelsMultiTA( po, pi, oo, oi, ws, hs, nTransparent
										  , r, g, b );
			}
			break;
		}
		MarkImageUpdated( pifDest );
	}
	lock = 0;
	//lprintf( WIDE( "Image done.." ) );
}