Exemple #1
0
static void
dump_outputs( IDirectFBScreen *screen,
              int              num )
{
     int                         i, n;
     DFBResult                   ret;
     DFBScreenOutputDescription *descs;
     DFBScreenOutputConfig       conf;

     descs = (DFBScreenOutputDescription*) D_CALLOC( num, sizeof(*descs) );
     if (!descs) {
          D_OOM();
          return;
     }

     ret = screen->GetOutputDescriptions( screen, descs );
     if (ret) {
          DirectFBError( "IDirectFBScreen::GetOutputDescriptions", ret );
          D_FREE( descs );
          return;
     }

     for (i=0; i<num; i++) {
          printf( "   Output (%d) %s\n", i, descs[i].name );


          /* Caps */
          printf( "     Caps:       " );

          for (n=0; output_caps[n].capability; n++) {
               if (descs[i].caps & output_caps[n].capability)
                    printf( "%s ", output_caps[n].name );
          }

          printf( "\n" );

          /* Connectors */
          if (descs[i].caps & DSOCAPS_CONNECTORS) {
              printf( "     Connectors: " );

              for (n=0; connectors[n].connector; n++) {
                   if (descs[i].all_connectors & connectors[n].connector)
                        printf( "%s ", connectors[n].name );
              }

              printf( "\n" );
          }

          /* Output Resolutions */
          if (descs[i].caps & DSOCAPS_RESOLUTION) {
               printf( "     Resolutions: " );

               for (n=0; resolutions[n].resolution; n++) {
                    if (descs[i].all_resolutions & resolutions[n].resolution)
                         printf( "%s ", resolutions[n].name );
               }

               printf( "\n" );
          }

          /* Signals */
          printf( "     Signals:    " );

          for (n=0; signals[n].signal; n++) {
               if (descs[i].all_signals & signals[n].signal)
                    printf( "%s ", signals[n].name );
          }

          printf( "\n" );

          ret = screen->GetOutputConfiguration( screen, i, &conf );
          if (ret) {
               DirectFBError( "IDirectFBScreen::GetOutputConfiguration", ret );
               D_FREE( descs );
               return;
          }

          if (conf.flags & DSOCONF_ENCODER)
               printf( "     Encoder:    %d (current)\n", conf.encoder );

          printf( "\n" );
     }

     printf( "\n" );

     D_FREE( descs );
}
Exemple #2
0
     /* fill device info structure */
     snprintf( info->desc.name,
               DFB_INPUT_DEVICE_DESC_NAME_LENGTH, "H3600 Touchscreen" );

     snprintf( info->desc.vendor,
               DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, "Unknown" );

     info->prefered_id     = DIDID_MOUSE;

     info->desc.type       = DIDTF_MOUSE;
     info->desc.caps       = DICAPS_AXES | DICAPS_BUTTONS;
     info->desc.max_axis   = DIAI_Y;
     info->desc.max_button = DIBI_LEFT;

     /* allocate and fill private data */
     data = D_CALLOC( 1, sizeof(H3600TSData) );

     data->fd     = fd;
     data->device = device;

     /* start input thread */
     data->thread = direct_thread_create( DTT_INPUT, h3600tsEventThread, data, "H3600 TS Input" );

     /* set private data pointer */
     *driver_data = data;

     return DFB_OK;
}

/*
 * Fetch one entry from the device's keymap if supported.
Exemple #3
0
static void
dump_mixers( IDirectFBScreen *screen,
             int              num )
{
     int                        i, n;
     DFBResult                  ret;
     DFBScreenMixerDescription *descs;

     descs = (DFBScreenMixerDescription*) D_CALLOC( num, sizeof(*descs) );
     if (!descs) {
          D_OOM();
          return;
     }

     ret = screen->GetMixerDescriptions( screen, descs );
     if (ret) {
          DirectFBError( "IDirectFBScreen::GetMixerDescriptions", ret );
          D_FREE( descs );
          return;
     }

     for (i=0; i<num; i++) {
          printf( "   Mixer (%d) %s\n", i, descs[i].name );

          /* Caps */
          printf( "     Caps:                    " );

          for (n=0; mixer_caps[n].capability; n++) {
               if (descs[i].caps & mixer_caps[n].capability)
                    printf( "%s ", mixer_caps[n].name );
          }

          printf( "\n" );


          /* Full mode layers */
          if (descs[i].caps & DSMCAPS_FULL) {
               printf( "     Layers (full mode):      " );

               for (n=0; n<DFB_DISPLAYLAYER_IDS_MAX; n++) {
                    if (DFB_DISPLAYLAYER_IDS_HAVE( descs[i].layers, n ))
                         printf( "(%02x) ", n );
               }

               printf( "\n" );
          }


          /* Sub mode layers */
          if (descs[i].caps & DSMCAPS_SUB_LAYERS) {
               printf( "     Layers (sub mode): %2d of ", descs[i].sub_num );

               for (n=0; n<DFB_DISPLAYLAYER_IDS_MAX; n++) {
                    if (DFB_DISPLAYLAYER_IDS_HAVE( descs[i].sub_layers, n ))
                         printf( "(%02x) ", n );
               }

               printf( "\n" );
          }

          printf( "\n" );
     }

     printf( "\n" );

     D_FREE( descs );
}
Exemple #4
0
static void
dump_encoders( IDirectFBScreen *screen,
               int              num )
{
     int                          i, n;
     DFBResult                    ret;
     DFBScreenEncoderDescription *descs;
     DFBScreenEncoderConfig       conf;

     descs = (DFBScreenEncoderDescription*) D_CALLOC( num, sizeof(*descs) );
     if (!descs) {
          D_OOM();
          return;
     }

     ret = screen->GetEncoderDescriptions( screen, descs );
     if (ret) {
          DirectFBError( "IDirectFBScreen::GetEncoderDescriptions", ret );
          D_FREE( descs );
          return;
     }

     for (i=0; i<num; i++) {
          printf( "   Encoder (%d) %s\n", i, descs[i].name );

          /* Type */
          printf( "     Type:           " );

          for (n=0; encoder_type[n].type; n++) {
               if (descs[i].type & encoder_type[n].type)
                    printf( "%s ", encoder_type[n].name );
          }

          printf( "\n" );


          /* Caps */
          printf( "     Caps:           " );

          for (n=0; encoder_caps[n].capability; n++) {
               if (descs[i].caps & encoder_caps[n].capability)
                    printf( "%s ", encoder_caps[n].name );
          }

          printf( "\n" );


          /* TV Norms */
          if (descs[i].caps & DSECAPS_TV_STANDARDS) {
               printf( "     TV Standards:   " );

               for (n=0; tv_standards[n].standard; n++) {
                    if (descs[i].tv_standards & tv_standards[n].standard)
                         printf( "%s ", tv_standards[n].name );
               }

               printf( "\n" );
          }


          /* Output signals */
          if (descs[i].caps & DSECAPS_OUT_SIGNALS) {
               printf( "     Output Signals: " );

               for (n=0; signals[n].signal; n++) {
                    if (descs[i].out_signals & signals[n].signal)
                         printf( "%s ", signals[n].name );
               }

               printf( "\n" );
          }
          
          /* Output Resolutions */
          if (descs[i].caps & DSECAPS_RESOLUTION) {
               printf( "     Output Resolutions: " );

               for (n=0; resolutions[n].resolution; n++) {
                    if (descs[i].all_resolutions & resolutions[n].resolution)
                         printf( "%s ", resolutions[n].name );
               }

               printf( "\n" );
          }

          /* Output connectors */
          if (descs[i].caps & DSECAPS_CONNECTORS) {
               printf( "     Output Connectors: " );

               for (n=0; connectors[n].connector; n++) {
                    if (descs[i].all_connectors & connectors[n].connector)
                         printf( "%s ", connectors[n].name );
               }

               printf( "\n" );
          }

          /* Picture Framing */
          if (descs[i].caps & DSECAPS_FRAMING) {
               printf( "     Framing:        " );

               for (n=0; framings[n].framing; n++) {
                    if (descs[i].all_framing & framings[n].framing)
                         printf( "%s ", framings[n].name );
               }

               printf( "\n" );
          }

          ret = screen->GetEncoderConfiguration( screen, i, &conf );
          if (ret) {
               DirectFBError( "IDirectFBScreen::GetEncoderConfiguration", ret );
               D_FREE( descs );
               return;
          }

          if (conf.flags & DSECONF_MIXER)
               printf( "     Mixer:          %d (current)\n", conf.mixer );

          printf( "\n" );
     }

     printf( "\n" );

     D_FREE( descs );
}
Exemple #5
0
DirectResult
voodoo_link_init_local( VoodooLink *link,
                        const char *path,
                        bool        raw )
{
     DirectResult        ret;
     int                 err;
     struct sockaddr_un  addr;
     Link               *l;

     D_ASSERT( link != NULL );
     D_ASSERT( path != NULL );

     l = D_CALLOC( 1, sizeof(Link) );
     if (!l)
          return D_OOM();

     /* Create the client socket. */
     l->fd[0] = socket( AF_LOCAL, SOCK_STREAM, 0 );
     if (l->fd[0] < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
          D_FREE( l );
          return ret;
     }
     l->fd[1] = l->fd[0];

#if !VOODOO_BUILD_NO_SETSOCKOPT
     if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );

     if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
#endif

     D_INFO( "Voodoo/Link: Connecting to '%s'...\n", path );


     memset( &addr, 0, sizeof(addr) );

     /* Bind the socket to the local port. */
     addr.sun_family = AF_UNIX;

     snprintf( addr.sun_path + 1, UNIX_PATH_MAX - 1, "%s", path );

     /* Connect to the server. */
     err = connect( l->fd[0], (struct sockaddr*) &addr, strlen(addr.sun_path+1)+1 + sizeof(addr.sun_family) );
     if (err) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
          close( l->fd[0] );
          D_FREE( l );
          return ret;
     }

     D_INFO( "Voodoo/Link: Connected.\n" );

     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );

     if (!raw) {
          link->code = 0x80008676;

          if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
               D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
               close( l->fd[0] );
               D_FREE( l );
               return DR_IO;
          }
     }
     D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );

     pipe( l->wakeup_fds );


     link->priv        = l;
     link->Close       = Close;
     link->Read        = Read;
     link->Write       = Write;
     link->SendReceive = SendReceive;
     link->WakeUp      = WakeUp;
     link->WaitForData = WaitForData;

     return DR_OK;
}
Exemple #6
0
static DFBEnumerationResult
display_layer_callback( DFBDisplayLayerID           id,
                        DFBDisplayLayerDescription  desc,
                        void                       *arg )
{
     int i;

     /* Name */
     printf( "     Layer (%02x) %-30s", id, desc.name );

     switch (id) {
          case DLID_PRIMARY:
               printf( "  (primary layer)" );
               break;
          default:
               break;
     }

     printf( "\n" );


     /* Type */
     printf( "        Type:    " );

     for (i=0; layer_types[i].type; i++) {
          if (desc.type & layer_types[i].type)
               printf( "%s ", layer_types[i].name );
     }

     printf( "\n" );


     /* Caps */
     printf( "        Caps:    " );

     for (i=0; layer_caps[i].capability; i++) {
          if (desc.caps & layer_caps[i].capability)
               printf( "%s ", layer_caps[i].name );
     }

     printf( "\n" );


     /* Sources */
     if (desc.caps & DLCAPS_SOURCES) {
          DFBResult              ret;
          IDirectFBDisplayLayer *layer;

          ret = dfb->GetDisplayLayer( dfb, id, &layer );
          if (ret) {
               DirectFBError( "DirectFB::GetDisplayLayer() failed", ret );
          }
          else {
               DFBDisplayLayerSourceDescription *descs;

               descs = (DFBDisplayLayerSourceDescription*) D_CALLOC( desc.sources, sizeof(*descs) );
               if (descs) {
                    ret = layer->GetSourceDescriptions( layer, descs );
                    if (ret) {
                         DirectFBError( "DirectFBDisplayLayer::GetSourceDescriptions() failed", ret );
                    }
                    else {
                         printf( "        Sources: " );

                         for (i=0; i<desc.sources; i++) {
                              if (i > 0)
                                   printf( ", %s", descs[i].name );
                              else
                                   printf( "%s", descs[i].name );
                         }

                         printf( "\n" );
                    }

                    D_FREE( descs );
               }
               else
                    D_OOM();

               layer->Release( layer );
          }
     }


     printf( "\n" );

     return DFENUM_OK;
}
Exemple #7
0
DFBResult
dfb_vt_initialize( void )
{
     DFBResult ret;
     struct vt_stat vs;

     D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ );

     dfb_vt = D_CALLOC( 1, sizeof(VirtualTerminal) );
     if (!dfb_vt)
          return D_OOM();

     setsid();
     dfb_vt->fd0 = open( "/dev/tty0", O_RDONLY | O_NOCTTY );
     if (dfb_vt->fd0 < 0) {
          if (errno == ENOENT) {
               dfb_vt->fd0 = open( "/dev/vc/0", O_RDONLY | O_NOCTTY );
               if (dfb_vt->fd0 < 0) {
                    if (errno == ENOENT) {
                         D_PERROR( "DirectFB/core/vt: Couldn't open "
                                    "neither `/dev/tty0' nor `/dev/vc/0'!\n" );
                    }
                    else {
                         D_PERROR( "DirectFB/core/vt: "
                                    "Error opening `/dev/vc/0'!\n" );
                    }

                    D_FREE( dfb_vt );
                    dfb_vt = NULL;

                    return DFB_INIT;
               }
          }
          else {
               D_PERROR( "DirectFB/core/vt: Error opening `/dev/tty0'!\n");

               D_FREE( dfb_vt );
               dfb_vt = NULL;

               return DFB_INIT;
          }
     }

     if (ioctl( dfb_vt->fd0, VT_GETSTATE, &vs ) < 0) {
          D_PERROR( "DirectFB/core/vt: VT_GETSTATE failed!\n" );
          close( dfb_vt->fd0 );
          D_FREE( dfb_vt );
          dfb_vt = NULL;
          return DFB_INIT;
     }

     dfb_vt->prev = vs.v_active;


     if (!dfb_config->vt_switch) {
          if (dfb_config->vt_num != -1)
               dfb_vt->num = dfb_config->vt_num;
          else
               dfb_vt->num = dfb_vt->prev;

          /* move vt to framebuffer */
          dfb_vt->old_fb = vt_get_fb( dfb_vt->num );
          vt_set_fb( dfb_vt->num, -1 );
     }
     else {
          if (dfb_config->vt_num == -1) {
               int n;

               n = ioctl( dfb_vt->fd0, VT_OPENQRY, &dfb_vt->num );
               if (n < 0 || dfb_vt->num == -1) {
                    D_PERROR( "DirectFB/core/vt: Cannot allocate VT!\n" );
                    close( dfb_vt->fd0 );
                    D_FREE( dfb_vt );
                    dfb_vt = NULL;
                    return DFB_INIT;
               }
          }
          else {
               dfb_vt->num = dfb_config->vt_num;
          }

          /* move vt to framebuffer */
          dfb_vt->old_fb = vt_get_fb( dfb_vt->num );
          vt_set_fb( dfb_vt->num, -1 );

          /* switch to vt */
          while (ioctl( dfb_vt->fd0, VT_ACTIVATE, dfb_vt->num ) < 0) {
               if (errno == EINTR)
                    continue;
               D_PERROR( "DirectFB/core/vt: VT_ACTIVATE failed!\n" );
               close( dfb_vt->fd0 );
               D_FREE( dfb_vt );
               dfb_vt = NULL;
               return DFB_INIT;
          }

          while (ioctl( dfb_vt->fd0, VT_WAITACTIVE, dfb_vt->num ) < 0) {
               if (errno == EINTR)
                    continue;
               D_PERROR( "DirectFB/core/vt: VT_WAITACTIVE failed!\n" );
               close( dfb_vt->fd0 );
               D_FREE( dfb_vt );
               dfb_vt = NULL;
               return DFB_INIT;
          }

          usleep( 40000 );
     }

     ret = vt_init_switching();
     if (ret) {
          if (dfb_config->vt_switch) {
               D_DEBUG_AT( VT, "  -> switching back...\n" );
               ioctl( dfb_vt->fd0, VT_ACTIVATE, dfb_vt->prev );
               ioctl( dfb_vt->fd0, VT_WAITACTIVE, dfb_vt->prev );
               D_DEBUG_AT( VT, "  -> ...switched back\n" );
               ioctl( dfb_vt->fd0, VT_DISALLOCATE, dfb_vt->num );
          }

          close( dfb_vt->fd0 );
          D_FREE( dfb_vt );
          dfb_vt = NULL;
          return ret;
     }

     vt_start_flushing();

     dfb_fbdev->vt = dfb_vt;

     return DFB_OK;
}
Exemple #8
0
static int
do_face( const Face *face )
{
     int              i, ret;
     int              align        = DFB_PIXELFORMAT_ALIGNMENT( m_format );
     int              num_glyphs   = 0;
     int              num_rows     = 1;
     int              row_index    = 0;
     int              row_offset   = 0;
     int              next_face    = sizeof(DGIFFFaceHeader);
     int              total_height = 0;

     Entity::vector   glyph_vector;
     unsigned int     glyph_count = 0;

     DGIFFFaceHeader  header;
     DGIFFGlyphInfo  *glyphs;
     DGIFFGlyphRow   *rows;
     void           **row_data;

     DFBSurfaceDescription *descs;

     D_DEBUG_AT( mkdgiff, "%s( %p )\n", __FUNCTION__, face );

     get_entities( face->buf, face->length, glyph_vector );

     glyph_count = glyph_vector.size();


     /* Clear to not leak any data into file. */
     memset( &header, 0, sizeof(header) );


     /* Allocate glyph info array. */
     glyphs   = (DGIFFGlyphInfo*)        D_CALLOC( glyph_count, sizeof(DGIFFGlyphInfo) );
     rows     = (DGIFFGlyphRow*)         D_CALLOC( glyph_count, sizeof(DGIFFGlyphRow) );            /* WORST case :) */
     row_data = (void**)                 D_CALLOC( glyph_count, sizeof(void*) );                    /* WORST case :) */
     descs    = (DFBSurfaceDescription*) D_CALLOC( glyph_count, sizeof(DFBSurfaceDescription) );    /* WORST case :) */

     for (Entity::vector::const_iterator iter = glyph_vector.begin(); iter != glyph_vector.end(); iter++) {
          const Glyph *glyph = dynamic_cast<const Glyph*>( *iter );

          glyph->Dump();


          DGIFFGlyphInfo *info = &glyphs[num_glyphs];
          DGIFFGlyphRow  *row  = &rows[num_rows - 1];

          D_DEBUG_AT( mkdgiff, "  -> code %3u\n", glyph->unicode );

          ret = load_image( glyph->file.c_str(), &descs[num_glyphs] );
          if (ret)
               continue;

          info->unicode = glyph->unicode;

          info->width   = descs[num_glyphs].width;
          info->height  = descs[num_glyphs].height;

          info->left    = glyph->left;
          info->top     = glyph->top;
          info->advance = glyph->advance;

          num_glyphs++;

          if (row->width > 0 && row->width + info->width > MAX_ROW_WIDTH) {
               num_rows++;
               row++;
          }

          row->width += (info->width + align) & ~align;

          if (row->height < info->height)
               row->height = info->height;
     }

     for (i=0; i<num_rows; i++) {
          DGIFFGlyphRow *row = &rows[i];

          D_DEBUG_AT( mkdgiff, "  ->   row %d, width %d, height %d\n", i, row->width, row->height );

          total_height += row->height;

          row->pitch = (DFB_BYTES_PER_LINE( m_format, row->width ) + 7) & ~7;

          row_data[i] = D_CALLOC( row->height, row->pitch );

          next_face += row->height * row->pitch;
     }

     D_DEBUG_AT( mkdgiff, "  -> %d glyphs, %d rows, total height %d\n", num_glyphs, num_rows, total_height );

     next_face += num_glyphs * sizeof(DGIFFGlyphInfo);
     next_face += num_rows * sizeof(DGIFFGlyphRow);

     for (i=0; i<num_glyphs; i++) {
          DGIFFGlyphInfo *glyph = &glyphs[i];

          D_DEBUG_AT( mkdgiff, "  -> writing character 0x%x (%d)\n", glyph->unicode, i );

          if (row_offset > 0 && row_offset + glyph->width > MAX_ROW_WIDTH) {
               row_index++;
               row_offset = 0;
          }


          D_DEBUG_AT( mkdgiff, "  -> row offset %d\n", row_offset );

          write_glyph( glyph, descs[i],
                       (char*) row_data[row_index] + DFB_BYTES_PER_LINE( m_format, row_offset ),
                       rows[row_index].pitch );

          glyph->row    = row_index;
          glyph->offset = row_offset;

          row_offset += (glyph->width + align) & ~align;
     }

     D_ASSERT( row_index == num_rows - 1 );

     header.next_face   = next_face;
     header.size        = face->size;

     header.ascender    = face->ascender;
     header.descender   = face->descender;
     header.height      = face->height;

     header.max_advance = face->maxadvance;

     header.pixelformat = m_format;

     header.num_glyphs  = num_glyphs;
     header.num_rows    = num_rows;

     header.blittingflags = face->blittingflags;

     D_DEBUG_AT( mkdgiff, "  -> ascender %d, descender %d\n", header.ascender, header.descender );
     D_DEBUG_AT( mkdgiff, "  -> height %d, max advance %d\n", header.height, header.max_advance );

     fwrite( &header, sizeof(header), 1, stdout );

     fwrite( glyphs, sizeof(*glyphs), num_glyphs, stdout );

     for (i=0; i<num_rows; i++) {
          DGIFFGlyphRow *row = &rows[i];

          fwrite( row, sizeof(*row), 1, stdout );

          fwrite( row_data[i], row->pitch, row->height, stdout );
     }

     for (i=0; i<num_rows; i++) {
          if (row_data[i])
               D_FREE( row_data[i] );
     }

     D_FREE( row_data );
     D_FREE( rows );
     D_FREE( glyphs );

     return 0;
}
Exemple #9
0
DFBResult
dfb_font_get_glyph_data( CoreFont        *font,
                         unichar          glyph,
                         CoreGlyphData  **ret_data )
{
     DFBResult      ret;
     CoreGlyphData *data;

     D_MAGIC_ASSERT( font, CoreFont );

     D_ASSERT( ret_data != NULL );

     if ((data = direct_tree_lookup (font->glyph_infos, (void *)glyph)) != NULL) {
          *ret_data = data;
          return DFB_OK;
     }

     data = (CoreGlyphData *) D_CALLOC(1, sizeof (CoreGlyphData));
     if (!data)
          return DFB_NOSYSTEMMEMORY;

     if (font->GetGlyphInfo &&
         font->GetGlyphInfo (font, glyph, data) == DFB_OK &&
         data->width > 0 && data->height > 0)
     {
          if (font->next_x + data->width > font->row_width) {
               CoreSurface *surface;

               if (font->row_width == 0) {
                    int width = 8192 / font->height;

                    if (width > 2048)
                         width = 2048;

                    if (width < font->maxadvance)
                         width = font->maxadvance;

                    font->row_width = (width + 7) & ~7;
               }

               ret = dfb_surface_create( font->core,
                                         font->row_width,
                                         MAX( font->height + 1, 8 ),
                                         font->pixel_format,
                                         CSP_VIDEOLOW, DSCAPS_NONE, NULL,
                                         &surface );
               if (ret) {
                    D_ERROR( "DirectFB/core/fonts: "
                              "Could not create glyph surface! (%s)\n",
                              DirectFBErrorString( ret ) );

                    D_FREE( data );
                    return ret;
               }

               font->next_x = 0;
               font->rows++;

               font->surfaces = D_REALLOC( font->surfaces, sizeof(void *) * font->rows );

               font->surfaces[font->rows - 1] = surface;
          }

          if (font->RenderGlyph(font, glyph, data,
                                font->surfaces[font->rows - 1]) == DFB_OK)
          {
               int align = DFB_PIXELFORMAT_ALIGNMENT(font->pixel_format);

               data->surface = font->surfaces[font->rows - 1];
               data->start   = font->next_x;
               font->next_x += (data->width + align) & ~align;

               dfb_gfxcard_flush_texture_cache();
          }
          else {
               data->start = data->width = data->height = 0;
          }
     }
     else {
          data->start = data->width = data->height = 0;
     }

     direct_tree_insert (font->glyph_infos, (void *) glyph, data);

     *ret_data = data;

     return DFB_OK;
}
Exemple #10
0
DirectTree *
direct_tree_new()
{
     return D_CALLOC( 1, sizeof (DirectTree) );
}
Exemple #11
0
DirectResult
voodoo_manager_create( int             fd,
                       VoodooClient   *client,
                       VoodooServer   *server,
                       VoodooManager **ret_manager )
{
     DirectResult     ret;
     VoodooManager   *manager;
     int              val;
     unsigned int     len;
     static const int tos = IPTOS_LOWDELAY;

     D_ASSERT( fd >= 0 );
     D_ASSERT( (client != NULL) ^ (server != NULL) );
     D_ASSERT( ret_manager != NULL );

     /* Allocate manager structure. */
     manager = D_CALLOC( 1, sizeof(VoodooManager) );
     if (!manager) {
          D_WARN( "out of memory" );
          return DR_NOLOCALMEMORY;
     }

     D_DEBUG( "Voodoo/Manager: Creating manager at %p.\n", manager );

     if (setsockopt( fd, SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );

     if (setsockopt( fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );

     DUMP_SOCKET_OPTION( SO_SNDLOWAT );
     DUMP_SOCKET_OPTION( SO_RCVLOWAT );
     DUMP_SOCKET_OPTION( SO_SNDBUF );
     DUMP_SOCKET_OPTION( SO_RCVBUF );

     /* Create the hash table for dispatcher instances. */
     ret = direct_hash_create( 251, &manager->instances.local );
     if (ret) {
          D_FREE( manager );
          return ret;
     }

     /* Create the hash table for requestor instances. */
     ret = direct_hash_create( 251, &manager->instances.remote );
     if (ret) {
          direct_hash_destroy( manager->instances.local );
          D_FREE( manager );
          return ret;
     }

     /* Store file descriptor. */
     manager->fd = fd;

     /* Store client or server. */
     manager->client = client;
     manager->server = server;

     /* Initialize all locks. */
     direct_util_recursive_pthread_mutex_init( &manager->instances.lock );
     direct_util_recursive_pthread_mutex_init( &manager->response.lock );
     direct_util_recursive_pthread_mutex_init( &manager->input.lock );
     direct_util_recursive_pthread_mutex_init( &manager->output.lock );

     /* Initialize all wait conditions. */
     pthread_cond_init( &manager->response.wait, NULL );
     pthread_cond_init( &manager->input.wait, NULL );
     pthread_cond_init( &manager->output.wait, NULL );

     /* Set default buffer limit. */
     manager->input.max = IN_BUF_MAX;

     D_MAGIC_SET( manager, VoodooManager );

     /* Create all threads. */
     manager->dispatcher    = direct_thread_create( DTT_MESSAGING, manager_dispatch_loop,
                                                    manager, "Voodoo Dispatch" );

     manager->input.thread  = direct_thread_create( DTT_INPUT, manager_input_loop,
                                                    manager, "Voodoo Input" );

     manager->output.thread = direct_thread_create( DTT_OUTPUT, manager_output_loop,
                                                    manager, "Voodoo Output" );

     /* Return the new manager. */
     *ret_manager = manager;

     return DR_OK;
}
Exemple #12
0
static DFBResult
system_initialize( CoreDFB *core, void **data )
{
     DFBResult     ret;
     DFBX11       *x11;
     DFBX11Shared *shared;

     D_DEBUG_AT( X11_Core, "%s()\n", __FUNCTION__ );

     x11 = D_CALLOC( 1, sizeof(DFBX11) );
     if (!x11)
          return D_OOM();

     shared = SHCALLOC( dfb_core_shmpool( core ), 1, sizeof(DFBX11Shared) );
     if (!shared) {
          D_FREE( x11 );
          return D_OOSHM();
     }

     shared->outputs = direct_config_get_int_value_with_default( "x11-outputs", 1 );
     shared->layers  = direct_config_get_int_value_with_default( "x11-layers", 5 );

     /* we need the error handler to signal the error to us, so
        use a global static */
     shared_for_error_handler = shared;
     XSetErrorHandler( error_handler );

     /*
      * Local init (master and slave)
      */
     ret = InitLocal( x11, shared, core );
     if (ret) {
          SHFREE( dfb_core_shmpool( core ), shared );
          D_FREE( x11 );
          return ret;
     }


     /*
      * Shared init (master only)
      */
     shared->data_shmpool = dfb_core_shmpool_data( core );

     shared->screen_size.w = x11->screenptr->width;
     shared->screen_size.h = x11->screenptr->height;

     fusion_call_init( &shared->call, call_handler, x11, dfb_core_world(core) );


     /*
      * Must be set before initializing the pools!
      */
     *data = x11;


     /*
      * Master init
      */
     dfb_surface_pool_initialize( core, &x11SurfacePoolFuncs, &shared->x11image_pool );
     dfb_surface_pool_initialize( core, &x11WindowPoolFuncs, &shared->x11window_pool );

#ifdef USE_GLX
     dfb_surface_pool_initialize( core, &glxSurfacePoolFuncs, &shared->glx_pool );
#endif

     if (dfb_config->video_length) {
          shared->vpsmem_length = dfb_config->video_length;

          dfb_surface_pool_initialize( core, &vpsmemSurfacePoolFuncs, &shared->vpsmem_pool );
     }

#ifdef USE_GLX
     dfb_surface_pool_bridge_initialize( core, &x11SurfacePoolBridgeFuncs, x11, &shared->x11_pool_bridge );
#endif

     core_arena_add_shared_field( core, "x11", shared );

     return DFB_OK;
}
Exemple #13
0
DirectThread *
direct_thread_create( DirectThreadType      thread_type,
                      DirectThreadMainFunc  thread_main,
                      void                 *arg,
                      const char           *name )
{
     DirectThread       *thread;
     pthread_attr_t      attr;
     struct sched_param  param;
     int                 policy;
     int                 priority;
     size_t              stack_size;

     D_ASSERT( thread_main != NULL );
     D_ASSERT( name != NULL );

     D_DEBUG_AT( Direct_Thread, "%s( %s, %p(%p), '%s' )\n", __FUNCTION__,
                 direct_thread_type_name(thread_type), thread_main, arg, name );

     /* Create the key for the TSD (thread specific data). */
     pthread_mutex_lock( &key_lock );

     if (thread_key == -1)
          pthread_key_create( &thread_key, NULL );

     pthread_mutex_unlock( &key_lock );

     /* Allocate thread structure. */
     thread = D_CALLOC( 1, sizeof(DirectThread) );
     if (!thread) {
          D_OOM();
          return NULL;
     }

     /* Write thread information to structure. */
     thread->name = D_STRDUP( name );
     thread->type = thread_type;
     thread->main = thread_main;
     thread->arg  = arg;

     /* Initialize to -1 for synchronization. */
     thread->thread = (pthread_t) -1;
     thread->tid    = (pid_t) -1;

     /* Initialize mutex and condition. */
     direct_util_recursive_pthread_mutex_init( &thread->lock );
     pthread_cond_init( &thread->cond, NULL );

     D_MAGIC_SET( thread, DirectThread );

     /* Initialize scheduling and other parameters. */
     pthread_attr_init( &attr );

     pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );

     /* Select scheduler. */
     switch (direct_config->thread_scheduler) {
          case DCTS_FIFO:
               policy = SCHED_FIFO;
               break;

          case DCTS_RR:
               policy = SCHED_RR;
               break;

          default:
               policy = SCHED_OTHER;
               break;
     }

     if (pthread_attr_setschedpolicy( &attr, policy ))
          D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) );

     /* Read (back) value. */
     pthread_attr_getschedpolicy( &attr, &policy );

     /* Select priority. */
     switch (thread->type) {
          case DTT_CLEANUP:
          case DTT_INPUT:
          case DTT_OUTPUT:
          case DTT_MESSAGING:
          case DTT_CRITICAL:
               priority = thread->type * direct_config->thread_priority_scale / 100;
               break;

          default:
               priority = direct_config->thread_priority;
               break;
     }

     D_DEBUG_AT( Direct_ThreadInit, "  -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority,
                 sched_get_priority_min( policy ), sched_get_priority_max( policy ) );

     if (priority < sched_get_priority_min( policy ))
          priority = sched_get_priority_min( policy );

     if (priority > sched_get_priority_max( policy ))
          priority = sched_get_priority_max( policy );

     param.sched_priority = priority;

     if (pthread_attr_setschedparam( &attr, &param ))
          D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority );

     /* Select stack size? */
     if (direct_config->thread_stack_size > 0) {
          if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size ))
               D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size );
     }

     /* Read (back) value. */
     pthread_attr_getstacksize( &attr, &stack_size );

     /* Lock the thread mutex. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> locking...\n" );
     pthread_mutex_lock( &thread->lock );

     /* Create and run the thread. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> creating...\n" );
     pthread_create( &thread->thread, &attr, direct_thread_main, thread );

     pthread_attr_destroy( &attr );

     pthread_getschedparam( thread->thread, &policy, &param );

     D_INFO( "Direct/Thread: Started '%s' (%d) [%s %s/%s %d/%d] <%zu>...\n",
             name, thread->tid, direct_thread_type_name(thread_type),
             direct_thread_policy_name(policy), direct_thread_scheduler_name(direct_config->thread_scheduler),
             param.sched_priority, priority, stack_size );

#ifdef DIRECT_THREAD_WAIT_INIT
     /* Wait for completion of the thread's initialization. */
     while (!thread->init) {
          D_DEBUG_AT( Direct_ThreadInit, "  -> waiting...\n" );
          pthread_cond_wait( &thread->cond, &thread->lock );
     }

     D_DEBUG_AT( Direct_ThreadInit, "  -> ...thread is running.\n" );
#endif

     /* Unlock the thread mutex. */
     D_DEBUG_AT( Direct_ThreadInit, "  -> unlocking...\n" );
     pthread_mutex_unlock( &thread->lock );

     D_DEBUG_AT( Direct_ThreadInit, "  -> returning %p\n", thread );

     return thread;
}
Exemple #14
0
DirectResult
voodoo_client_create( const char     *host,
                      int             port,
                      VoodooClient  **ret_client )
{
     DirectResult    ret;
     VoodooPlayInfo  info;
     VoodooClient   *client;
     VoodooPlayer   *player;
     char            buf[100] = { 0 };
     const char     *hostname = host;
     bool            raw = true;

     D_ASSERT( ret_client != NULL );

     if (!host)
          host = "";

     if (!port)
          port = 2323;

     D_DEBUG_AT( Voodoo_Client, "%s( '%s', %d )\n", __FUNCTION__, host, port );

     if (port != 2323) {
          D_DEBUG_AT( Voodoo_Client, "  -> port != 2323, using PACKET mode right away\n" );

          raw = false;
     }

     direct_list_foreach (client, m_clients) {
          if (!strcmp( client->host, host ) && client->port == port) {
               D_INFO( "Voodoo/Client: Reconnecting to '%s', increasing ref count of existing connection!\n", host );

               client->refs++;

               *ret_client = client;

               return DR_OK;
          }
     }

     /*
      * Get the player singleton
      */
     ret = voodoo_player_create( NULL, &player );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Could not create the player!\n" );
          return ret;
     }

     /*
      * If we got a hostname or address try to lookup the player info
      */
     // FIXME: resolve first, not late in voodoo_link_init_connect
     if (hostname && hostname[0]) {
          ret = voodoo_player_lookup_by_address( player, hostname, &info );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;
          }
     }
     else {
          /*
           * Start discovery and use first host visible
           */
          ret = discover_host( player, NULL, &info, buf, sizeof(buf) );
          if (ret == DR_OK) {
               if (info.flags & VPIF_PACKET)
                    raw = false;

               hostname = buf;
          }
     }

     if (!hostname || !hostname[0]) {
          D_ERROR( "Voodoo/Client: Did not find any other player!\n" );
          return DR_ITEMNOTFOUND;
     }


     /* Allocate client structure. */
     client = D_CALLOC( 1, sizeof(VoodooClient) );
     if (!client)
          return D_OOM();


     raw = !voodoo_config->link_packet && (voodoo_config->link_raw || raw);

     /* Create a link to the other player. */
     ret = voodoo_link_init_connect( &client->vl, hostname, port, raw );
     if (ret) {
          D_DERROR( ret, "Voodoo/Client: Failed to initialize Voodoo Link!\n" );
          D_FREE( client );
          return ret;
     }

     D_INFO( "Voodoo/Client: Fetching player information...\n" );

     if (raw) {     // FIXME: send_discover_and_receive_info() only does RAW, but we don't need it for packet connection, yet
          VoodooPlayVersion version;
          VoodooPlayInfo    info;

          ret = send_discover_and_receive_info( &client->vl, &version, &info );
          if (ret) {
               D_DEBUG_AT( Voodoo_Client, "  -> Failed to receive player info via TCP!\n" );

               D_INFO( "Voodoo/Client: No player information from '%s', trying to discover via UDP!\n", host );

               /*
                * Fallback to UDP discovery
                */
               ret = discover_host( player, hostname, &info, buf, sizeof(buf) );
               if (ret == DR_OK) {
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }
          else {
               D_INFO( "Voodoo/Client: Connected to '%s' (%-15s) %s "
                       "=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x= "
                       "(vendor: %s, model: %s)\n",
                       info.name, host,
                       (info.flags & VPIF_LEVEL2) ? "*" : " ",
                       info.uuid[0], info.uuid[1], info.uuid[2], info.uuid[3], info.uuid[4],
                       info.uuid[5], info.uuid[6], info.uuid[7], info.uuid[8], info.uuid[9],
                       info.uuid[10], info.uuid[11], info.uuid[12], info.uuid[13], info.uuid[14],
                       info.uuid[15],
                       info.vendor, info.model );

               if (raw && !voodoo_config->link_raw) {
                    /*
                     * Switch to packet mode?
                     */
                    if (info.flags & VPIF_PACKET)
                         raw = false;
               }
          }

          /*
           * Switch to packet mode?
           */
          if (!raw) {
               D_INFO( "Voodoo/Client: Switching to packet mode!\n" );

               client->vl.Close( &client->vl );

               /* Create another link to the other player. */
               ret = voodoo_link_init_connect( &client->vl, hostname, port, false );
               if (ret) {
                    D_DERROR( ret, "Voodoo/Client: Failed to initialize second Voodoo Link!\n" );
                    D_FREE( client );
                    return ret;
               }
          }
     }


     /* Create the manager. */
     ret = voodoo_manager_create( &client->vl, client, NULL, &client->manager );
     if (ret) {
          client->vl.Close( &client->vl );
          D_FREE( client );
          return ret;
     }

     client->refs = 1;
     client->host = D_STRDUP( host );
     client->port = port;

     direct_list_prepend( &m_clients, &client->link );

     /* Return the new client. */
     *ret_client = client;

     D_DEBUG_AT( Voodoo_Client, "  => client %p\n", client );

     return DR_OK;
}
Exemple #15
0
DirectResult
voodoo_link_init_connect( VoodooLink *link,
                          const char *hostname,
                          int         port,
                          bool        raw )
{
     DirectResult     ret;
     int              err;
     struct addrinfo  hints;
     struct addrinfo *addr;
     char             portstr[10];
     Link            *l;


     memset( &hints, 0, sizeof(hints) );
     hints.ai_flags    = AI_CANONNAME;
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_family   = PF_UNSPEC;

     D_INFO( "Voodoo/Link: Looking up host '%s'...\n", hostname );

     snprintf( portstr, sizeof(portstr), "%d", port );

     err = getaddrinfo( hostname, portstr, &hints, &addr );
     if (err) {
          switch (err) {
               case EAI_FAMILY:
                    D_ERROR( "Direct/Log: Unsupported address family!\n" );
                    return DR_UNSUPPORTED;

               case EAI_SOCKTYPE:
                    D_ERROR( "Direct/Log: Unsupported socket type!\n" );
                    return DR_UNSUPPORTED;

               case EAI_NONAME:
                    D_ERROR( "Direct/Log: Host not found!\n" );
                    return DR_FAILURE;

               case EAI_SERVICE:
                    D_ERROR( "Direct/Log: Service is unreachable!\n" );
                    return DR_FAILURE;

#ifdef EAI_ADDRFAMILY
               case EAI_ADDRFAMILY:
#endif
               case EAI_NODATA:
                    D_ERROR( "Direct/Log: Host found, but has no address!\n" );
                    return DR_FAILURE;

               case EAI_MEMORY:
                    return D_OOM();

               case EAI_FAIL:
                    D_ERROR( "Direct/Log: A non-recoverable name server error occurred!\n" );
                    return DR_FAILURE;

               case EAI_AGAIN:
                    D_ERROR( "Direct/Log: Temporary error, try again!\n" );
                    return DR_TEMPUNAVAIL;

               default:
                    D_ERROR( "Direct/Log: Unknown error occured!?\n" );
                    return DR_FAILURE;
          }
     }


     l = D_CALLOC( 1, sizeof(Link) );
     if (!l)
          return D_OOM();

     /* Create the client socket. */
     l->fd[0] = socket( addr->ai_family, SOCK_STREAM, 0 );
     if (l->fd[0] < 0) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket creation failed!\n" );
          freeaddrinfo( addr );
          D_FREE( l );
          return ret;
     }
     l->fd[1] = l->fd[0];

#if !VOODOO_BUILD_NO_SETSOCKOPT
     if (setsockopt( l->fd[0], SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" );

     if (setsockopt( l->fd[0], SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0)
          D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" );
#endif

     D_INFO( "Voodoo/Link: Connecting to '%s:%d'...\n", addr->ai_canonname, port );

     /* Connect to the server. */
     err = connect( l->fd[0], addr->ai_addr, addr->ai_addrlen );
     freeaddrinfo( addr );

     if (err) {
          ret = errno2result( errno );
          D_PERROR( "Voodoo/Link: Socket connect failed!\n" );
          close( l->fd[0] );
          D_FREE( l );
          return ret;
     }

     D_INFO( "Voodoo/Link: Connected.\n" );

     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVLOWAT );
     DUMP_SOCKET_OPTION( l->fd[0], SO_SNDBUF );
     DUMP_SOCKET_OPTION( l->fd[0], SO_RCVBUF );

     if (!raw) {
          link->code = 0x80008676;

          if (write( l->fd[1], &link->code, sizeof(link->code) ) != 4) {
               D_ERROR( "Voodoo/Link: Coult not write initial four bytes!\n" );
               close( l->fd[0] );
               D_FREE( l );
               return DR_IO;
          }
     }
     D_INFO( "Voodoo/Link: Sent link code (%s).\n", raw ? "raw" : "packet" );

     pipe( l->wakeup_fds );


     link->priv        = l;
     link->Close       = Close;
     link->Read        = Read;
     link->Write       = Write;
     link->SendReceive = SendReceive;
     link->WakeUp      = WakeUp;
     link->WaitForData = WaitForData;

     return DR_OK;
}
Exemple #16
0
DFBResult
dfb_core_create( CoreDFB **ret_core )
{
     int      ret;
#if FUSION_BUILD_MULTI
     char     buf[16];
#endif
     CoreDFB       *core   = NULL;
     CoreDFBShared *shared = NULL;

     D_ASSERT( ret_core != NULL );
     D_ASSERT( dfb_config != NULL );

     D_DEBUG_AT( DirectFB_Core, "%s...\n", __FUNCTION__ );

     pthread_mutex_lock( &core_dfb_lock );

     D_ASSERT( core_dfb == NULL || core_dfb->refs > 0 );

     if (core_dfb) {
          D_MAGIC_ASSERT( core_dfb, CoreDFB );

          core_dfb->refs++;

          *ret_core = core_dfb;

          pthread_mutex_unlock( &core_dfb_lock );

          return DFB_OK;
     }

     direct_initialize();


     D_INFO( "DirectFB/Core: %s Application Core. ("BUILDTIME") %s%s\n",
             FUSION_BUILD_MULTI ? "Multi" : "Single",
             DIRECT_BUILD_DEBUG ? "[ DEBUG ]" : "",
             DIRECT_BUILD_TRACE ? "[ TRACE ]" : "" );


#if defined(DFB_DYNAMIC_LINKING) && defined(SOPATH)
     if (!dfb_lib_handle)
#ifdef RTLD_GLOBAL
          dfb_lib_handle = dlopen(SOPATH, RTLD_GLOBAL|RTLD_LAZY);
#else
          /* RTLD_GLOBAL is not defined on OpenBSD */
          dfb_lib_handle = dlopen(SOPATH, RTLD_LAZY);
#endif
#endif

     ret = dfb_system_lookup();
     if (ret)
          goto error;


     /* Allocate local core structure. */
     core = D_CALLOC( 1, sizeof(CoreDFB) );
     if (!core) {
          ret = D_OOM();
          goto error;
     }

     core->refs = 1;

     core->init_handler = direct_thread_add_init_handler( dfb_core_thread_init_handler, core );

#if FUSION_BUILD_MULTI
     dfb_system_thread_init();
#endif

     direct_find_best_memcpy();

     D_MAGIC_SET( core, CoreDFB );

     core_dfb = core;

     ret = fusion_enter( dfb_config->session, DIRECTFB_CORE_ABI, FER_ANY, &core->world );
     if (ret)
          goto error;

     core->fusion_id = fusion_id( core->world );

#if FUSION_BUILD_MULTI
     D_DEBUG_AT( DirectFB_Core, "world %d, fusion id %d\n", fusion_world_index(core->world), core->fusion_id );

     snprintf( buf, sizeof(buf), "%d", fusion_world_index(core->world) );

     setenv( "DIRECTFB_SESSION", buf, true );
#endif

     if (dfb_config->sync) {
          D_INFO( "DirectFB/Core: calling sync()...\n" );
          sync();
     }

     direct_signal_handler_add( DIRECT_SIGNAL_ANY, dfb_core_signal_handler, core, &core->signal_handler );

     if (fusion_arena_enter( core->world, "DirectFB/Core",
                             dfb_core_arena_initialize, dfb_core_arena_join,
                             core, &core->arena, &ret ) || ret)
     {
          ret = ret ? ret : DFB_FUSION;
          goto error;
     }

     shared = core->shared;
     D_MAGIC_ASSERT( shared, CoreDFBShared );

     if (dfb_config->block_all_signals)
          direct_signals_block_all();

     if (dfb_config->deinit_check)
          direct_cleanup_handler_add( dfb_core_deinit_check, NULL, &core->cleanup_handler );


     fusion_skirmish_prevail( &shared->lock );

     if (!core->master) {
          while (!shared->active)
               fusion_skirmish_wait( &shared->lock, 0 );
     }

     fusion_skirmish_dismiss( &shared->lock );


     *ret_core = core;

     pthread_mutex_unlock( &core_dfb_lock );

     D_DEBUG_AT( DirectFB_Core, "Core successfully created.\n" );

     return DFB_OK;


error:
     if (core) {
          if (core->world)
               fusion_exit( core->world, false );

          if (core->init_handler)
               direct_thread_remove_init_handler( core->init_handler );

          if (core->signal_handler)
               direct_signal_handler_remove( core->signal_handler );

          D_MAGIC_CLEAR( core );

          D_FREE( core );
          core_dfb = NULL;
     }

     pthread_mutex_unlock( &core_dfb_lock );

     direct_shutdown();

     return ret;
}
Exemple #17
0
DirectResult
voodoo_play_get_broadcast( VoodooPlayAddress **ret_addr,
                           size_t             *ret_num )
{
    size_t             num = 0;
    size_t             i   = 0;
    VoodooPlayAddress *addr;

    int            ret;
    int            fd;
    char          *ptr, lastname[IFNAMSIZ];
    struct ifreq   req[16];
    struct ifconf  conf;

    D_ASSERT( ret_addr != NULL );
    D_ASSERT( ret_num != NULL );

    conf.ifc_buf = (char*) req;
    conf.ifc_len = sizeof(req);

    fd = socket( AF_INET, SOCK_DGRAM, 0 );
    if (fd < 0) {
        D_PERROR( "Voodoo/Unix: socket( AF_INET, SOCK_DGRAM, 0 ) failed!\n" );
        return DR_FAILURE;
    }

    ret = ioctl( fd, SIOCGIFCONF, &conf );
    if (ret) {
        D_PERROR( "Voodoo/Player: ioctl( SIOCGIFCONF ) failed!\n" );
        close( fd );
        return DR_FAILURE;
    }

    lastname[0] = 0;

    for (ptr = conf.ifc_buf; ptr < conf.ifc_buf + conf.ifc_len; ) {
        struct ifreq         ifrcopy, *ifr  = (struct ifreq *)ptr;
        struct sockaddr_in  *saddr = (struct sockaddr_in*) &ifr->ifr_broadaddr;

#ifdef MACOS
        ptr += sizeof(ifr->ifr_name) + MAX(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); // for next one in buffer
#else
        ptr += sizeof(req[0]);
#endif

        if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
            continue; /* already processed this interface */
        }

        memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

        ifrcopy = *ifr;
        ioctl( fd, SIOCGIFFLAGS, &ifrcopy);
        if ((ifrcopy.ifr_flags & IFF_UP) == 0)
            continue;   // ignore if interface not up

        ret = ioctl( fd, SIOCGIFBRDADDR, ifr );
        if (ret)
            continue;

        if (!saddr->sin_addr.s_addr) {
            ret = ioctl( fd, SIOCGIFDSTADDR, ifr );
            if (ret)
                continue;
        }

        num++;
    }


    addr = D_CALLOC( num, sizeof(VoodooPlayAddress) );
    if (!addr) {
        close( fd );
        return D_OOM();
    }


    for (ptr = conf.ifc_buf; ptr < conf.ifc_buf + conf.ifc_len; ) {
        char                 buf[100];
        struct ifreq         ifrcopy, *ifr  = (struct ifreq *)ptr;
        struct sockaddr_in  *saddr = (struct sockaddr_in*) &ifr->ifr_broadaddr;

#ifdef MACOS
        ptr += sizeof(ifr->ifr_name) + MAX(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); // for next one in buffer
#else
        ptr += sizeof(req[0]);
#endif

        if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
            continue; /* already processed this interface */
        }

        memcpy(lastname, ifr->ifr_name, IFNAMSIZ);

        ifrcopy = *ifr;
        ioctl( fd, SIOCGIFFLAGS, &ifrcopy);
        if ((ifrcopy.ifr_flags & IFF_UP) == 0) {
            D_INFO( "Voodoo/Player:   %-16s is not up.\n", ifrcopy.ifr_name );
            continue;   // ignore if interface not up
        }

        ret = ioctl( fd, SIOCGIFBRDADDR, ifr );
        if (ret) {
            D_PERROR( "Voodoo/Player: ioctl( SIOCGIFBRDADDR ) %-16s failed!\n", ifr->ifr_name );
            continue;
        }

        if (saddr->sin_addr.s_addr) {
            inet_ntop( AF_INET, &saddr->sin_addr, buf, sizeof(buf) );

            D_INFO( "Voodoo/Player:   %-16s (%s)\n", ifr->ifr_name, buf );
        }
        else {
            ret = ioctl( fd, SIOCGIFDSTADDR, ifr );
            if (ret) {
                D_PERROR( "Voodoo/Player: ioctl( SIOCGIFDSTADDR ) failed!\n" );
                continue;
            }

            inet_ntop( AF_INET, &saddr->sin_addr, buf, sizeof(buf) );

            D_INFO( "Voodoo/Player:   %-16s (%s) (P-t-P)\n", ifr->ifr_name, buf );
        }

        voodoo_play_from_inet_addr( &addr[i++], saddr->sin_addr.s_addr );
    }

    close( fd );

    *ret_addr = addr;
    *ret_num  = num;

    return DR_OK;
}