LibSoup

홈페이지: http://live.gnome.org/LibSoup

gnome 환경을 위한 http 클라이언트/서버 라이브러리.

libsoup is an HTTP client/server library for GNOME. It uses GObjects and the glib main loop, to integrate well with GNOME applications, and also has a synchronous API, for use in threaded applications.

다운로드: 2.28.1
참고: http://crew.emstone.com/~keedi/timetolog/

Libcroco

홈페이지: http://www.freespiders.org/projects/libcroco

libxml이 xml을 해석하듯 css를 해석해주는 라이브러리. cssom까지 제공한다.

Libcroco is a general CSS parsing and manipulation library written in C for the GNOME project. It provides a CSS2 parser (SAC and CSSOM API), and a CSS2 selection engine. It uses Libxml2 as underlying XML platform and the GLib as a portability layer.

다운로드: 0.6.2

ClutterCairo

홈페이지: http://www.clutter-project.org/sources/clutter-cairo/

An experimental clutter cairo ‘drawable’ actor. Sucks a bit as renders
cairo via an image surface and thus no real cairo rendering
acceleration. Experiments with glitz and sharing GL contexts for such
acceleration proved problematic. Needs more investigation.

bubbles

다운로드: 0.8.2

Clutter

홈페이지: http://clutter-project.org/

c언어로 구현한 2D 그래픽 사용자 인터페이스 라이브러리.
2D임에도 불구하고 OpenGL 또는 OpenGL ES를 렌더링에 사용하며, GLib의 GObject 기반으로 API가 구성되어 있다.

Clutter is an open source software library for creating fast, visually rich, portable and animated graphical user interfaces.

Clutter uses OpenGL (and optionally OpenGL|ES for use on Mobile and embedded platforms) for rendering but with an API which hides the underlying GL complexity from the developer. The Clutter API is intended to be easy to use, efficient and flexible.

다운로드: 0.8.8, 1.0.0
데모 다운로드: clutter-test-mingw.7z

아래는 테스트 해본 화면..
clone-test1
cline-test2
image-viewer
Clutter로 제작된 Moblin UI

Mesa3D

홈페이지: http://mesa3d.sourceforge.net/

OpenGL API와 호환성을 갖는 라이브러리이다.

대부분의 상용 운영체제에서는 SGI에서 라이선스받은 정식 OpenGL 라이브러리가 지원되지만 리눅스는 그렇지 못하다. 사실 리눅스에서 사용하는 OpenGL은 정식 OpenGL이 아니라 Mesa3D(www.mesa3d.org)라는 이름의 OpenGLAPI를 그대로 구현한 공개 라이브러리다

Mesa is an open-source implementation of the OpenGL specification – a system for rendering interactive 3D graphics.

A variety of device drivers allows Mesa to be used in many different environments ranging from software emulation to complete hardware acceleration for modern GPUs.

Mesa ties into several other open-source projects: the Direct Rendering Infrastructure and X.org to provide OpenGL support to users of X on Linux, FreeBSD and other operating systems.

컴파일시 같은 디렉토리내에 MesaLib-7.4.4.tar.gz, MesaGLUT-7.4.4.tar.gz, MesaDemos-7.4.4.tar.gz 이 파일들을 풀고, make -f Makefile.mgw 를 수행한다.

다운로드: 7.4.4
샘플 다운로드: mesa3d-test-mingw.7z

librsvg

홈페이지: http://librsvg.sourceforge.net/

벡터 그래픽 포맷 SVG를 취급하는 라이브러리.

In simple terms, librsvg is a component used within software applications to enable support for SVG-format scalable graphics. In contrast to raster formats, scalable vector graphics provide users and artists a way to create, view, and provide imagery that is not limited to the pixel or dot density that an output device is capable of.
Many software developers use the librsvg library to render SVG graphics. It is lightweight and portable, requiring only libxml and libart at a minimum, while providing extra features when used with libcroco, libgsf, and mozilla. It is included as part of the GNOME Desktop, and is licensed under the LGPL license.

다운로드: 2.26.0

cairo & cairomm example

아래의 코드들은 wxWidgets와의 조합이며, wxEVT_PAINT 이벤트내에서 작성하면 될것이다. MinGW로 테스트 되었다.

아래의 코드는 cairo의 경우이다.

wxPaintDC dc(this);

wxRect rect = GetClientRect();

if(rect.width == 0 || rect.height == 0) return;

// RENDER_NATIVE
HWND hWnd = (HWND)this->GetHandle();
HDC hDC = ::GetDC(hWnd);

HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.width, rect.height);
SelectObject(hMemDC, hBitmap); 

cairo_surface_t* surface = cairo_win32_surface_create(hMemDC);
cairo_t* image = cairo_create(surface);

cairo_pattern_t *pat;

pat = cairo_pattern_create_linear (0.0, 0.0,  0.0, 256.0);
cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_rectangle (image, 0, 0, rect.width, rect.height);
cairo_set_source (image, pat);
cairo_fill (image);
cairo_pattern_destroy (pat);

pat = cairo_pattern_create_radial (115.2, 102.4, 25.6,
							   102.4,  102.4, 128.0);
cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
cairo_set_source (image, pat);
cairo_arc (image, 128.0, 128.0, 76.8, 0, 2 * M_PI);
cairo_fill (image);
cairo_pattern_destroy (pat);

BitBlt(hDC, 0, 0, rect.width, rect.height, hMemDC, 0, 0, SRCCOPY);

DeleteDC(hMemDC);
DeleteObject(hBitmap);

// Because we called ::GetDC make sure we relase the handle
// back to the system or we'll have a memory leak.
::ReleaseDC(hWnd, hDC);

아래의 코드는 cairomm의 경우이다.

wxPaintDC dc(this);

wxRect rect = GetClientRect();

if(rect.width == 0 || rect.height == 0) return;

// RENDER_NATIVE
HWND hWnd = (HWND)this->GetHandle();
HDC hDC = ::GetDC(hWnd);

HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.width, rect.height);
SelectObject(hMemDC, hBitmap); 

Cairo::RefPtr<Context> context;
Cairo::RefPtr<Win32Surface> surface;

surface = Win32Surface::create(hMemDC);
context = Context::create(surface);

// draw background
Cairo::RefPtr<Cairo::LinearGradient> background_gradient_ptr = 
	Cairo::LinearGradient::create (0, 0, rect.width, rect.height);

background_gradient_ptr->add_color_stop_rgb (0, 0.7,0,0);
background_gradient_ptr->add_color_stop_rgb (1, 0.3,0,0);

// Draw a rectangle and fill with gradient
context->set_source (background_gradient_ptr);
context->rectangle (0, 0, rect.width, rect.height);
context->fill();

surface->finish();

BitBlt(hDC, 0, 0, rect.width, rect.height, hMemDC, 0, 0, SRCCOPY);

DeleteDC(hMemDC);
DeleteObject(hBitmap);

// Because we called ::GetDC make sure we relase the handle
// back to the system or we'll have a memory leak.
::ReleaseDC(hWnd, hDC);

NetClass

홈페이지: http://netclass.sourceforge.net

NetClass – a multi-platform C++ library which provides a thin wrapper for socket and thread support. This library is available under the terms of the GNU Public License. Currently, there is support for GNU/Linux and Win32 platforms. Also included in the library is the basic architecture to quickly create a simple generic server.

멀티플랫폼 소켓/ 쓰레드 랩퍼 라이브러리이다.

다운: 0.3.0

예제

#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include "netclass.h"

//#define TEST_MODE_UDP
#define TEST_MODE_TCPIP


/* globals */
const int NUMBYTES = 512;
char buf[NUMBYTES] = {0};
char str[NUMBYTES] = {0};

int processRetVal(RetCode ret)
{
   switch(ret)
   {
   case NC_FAILED:
      cout << "The operation failed." << endl;
      return 0;
   case NC_TIMEDOUT:
      cout << "The operation has timed out." << endl;
      return 0;
   case NC_MOREDATA:
      cout << "The operation has returned that more data is available." << endl;
      return 0;
   }
   return 1;
}

ncCallBackRetType printstuff(void *ptr)
{
   cout << "Function callback for client connection called." << endl;

#ifdef TEST_MODE_UDP
   udpData *udpdata = ((udpData *)ptr);
   if (udpdata)
   {
      cout << udpdata->getData() << endl;
      delete udpdata;
   }
#else
   ncSocket *client = ((ncSocket *)ptr);
   
   if (client)
   {
      memset(buf,0,NUMBYTES);
      int numActualBytes = 0;

      /* read incoming bytes, leaving a null-terminator */
      switch(client->readData(buf,NUMBYTES-1,&numActualBytes))
      {
      case NC_OK:
         cout << numActualBytes << " bytes read." << endl;
         cout << buf << endl;
         break;
      case NC_FAILED:
         cout << "printstuff readData failed." << endl;
         break;
      case NC_MOREDATA:
         cout << "NC_MOREDATA | READ ONLY RETURNED " << 
            numActualBytes << " BYTES." << endl;
         break;
      }
      cout << "Deleting client" << endl;
      delete client;
   }
#endif

   return (ncCallBackRetType)0;
}

ncCallBackRetType threadfunc1(void *ptr)
{
#ifdef TEST_MODE_UDP
   ncSocketListener ncsl(1234,SOCKTYPE_UDP);
#else
   ncSocketListener ncsl(1234,SOCKTYPE_TCPIP);
#endif

   /*
     Start the non threaded server;
     printstuff will be called with each new incoming connection.
   */
   cout << "Non-threaded Server starting" << endl;
   ncsl.startListening(printstuff,NC_NONTHREADED);

   /* OR Start the threaded server */
   //cout << "Threaded Server starting" << endl;
   //ncsl.startListening(printstuff,NC_THREADED);
   return (ncCallBackRetType)0;
}

ncCallBackRetType threadfunc2(void *ptr)
{
   static ncSocket sock;
   ncThread *thread1 = (ncThread *)ptr;
   int bytesWritten = 0;

   ncSleep(1000);
   
   /* fill (null-terminated) string with repeating upper case letters */
   for(int i = 0; i < 511; i++)
   {
      str[i] = (char)((i % 26)+65);
   }

   while(1)
   {
      bytesWritten = 0;

      /* attempt the connect */
#ifdef TEST_MODE_UDP
      if (!processRetVal(sock.connect("localhost",1234,SOCKTYPE_UDP)))
#else
      if (!processRetVal(sock.connect("localhost",1234,SOCKTYPE_TCPIP)))
#endif
      {
         cout << "Connect failed" << endl;
         goto cleanup;
      }
      else
      {
         cout << "Connected." << endl;
      }
      
      /* write the string data to the server (w/o null terminator) */
      if (!processRetVal(sock.writeData((char *)str,511,&bytesWritten)))
      {
         cout << "write data failed" << endl;
         break;
      }
      else
      {
         cout << "Bytes written = " << bytesWritten << endl;
      }

      sock.close();
      ncSleep(1000);
   }

  cleanup:
   if (thread1)
   {
      cout << "Cancelling thread 1" << endl;
      thread1->stop(1);
   }
   cout << "Thread 2 exiting" << endl;
   return (ncCallBackRetType)0;
}


int main(int argc,char **argv)
{
   netClass nc;
   ncThread thread1;
   ncThread thread2;

   /* only required under win32 (initializes winsock) */
   nc.initialize();

   if (thread1.start(threadfunc1,(void *)0) == NC_FAILED)
   {
      cout << "Thread 1 creation failed." << endl;
   }
   if (thread2.start(threadfunc2,(void *)&thread1) == NC_FAILED)
   {
      cout << "Thread 2 creation failed." << endl;
   }
   if (thread1.detach() == NC_FAILED)
   {
      cout << "Thread 1 join failed." << endl;
   }
   if (thread2.join() == NC_FAILED)
   {
      cout << "Thread 2 join failed." << endl;
   }
   return 0;
}