//----------------------------------------------------------------------------- // BugDlg_CompressScreenshot // // Compress .BMP to .JPG, Delete .BMP //----------------------------------------------------------------------------- bool BugDlg_CompressScreenshot() { if ( !g_bug_szScreenshot[0] ) { return false; } bool bSuccess = false; HBITMAP hBitmap = NULL; HDC hDC = NULL; char *pBMPBits = NULL; CUtlBuffer buf( 0, 0 ); hBitmap = (HBITMAP)LoadImage( NULL, g_bug_szScreenshot, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE ); if ( !hBitmap ) goto cleanUp; hDC = CreateCompatibleDC( NULL ); if ( !hDC ) goto cleanUp; BITMAPINFO bitmapInfo; ZeroMemory( &bitmapInfo, sizeof( BITMAPINFO ) ); bitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); // populate the bmp info if ( !GetDIBits( hDC, hBitmap, 0, 0, NULL, &bitmapInfo, DIB_RGB_COLORS ) ) goto cleanUp; pBMPBits = (char *)Sys_Alloc( bitmapInfo.bmiHeader.biSizeImage ); if ( !pBMPBits ) goto cleanUp; // could be bottom-up or top-down int nHeight = abs( bitmapInfo.bmiHeader.biHeight ); if ( bitmapInfo.bmiHeader.biBitCount != 32 ) { // unexpected format goto cleanUp; } if ( bitmapInfo.bmiHeader.biCompression != BI_RGB && bitmapInfo.bmiHeader.biCompression != BI_BITFIELDS ) { // unexpected format goto cleanUp; } // don't want color masks bitmapInfo.bmiHeader.biCompression = BI_RGB; // get the raw bits if ( !GetDIBits( hDC, hBitmap, 0, nHeight, pBMPBits, &bitmapInfo, DIB_RGB_COLORS ) ) goto cleanUp; JSAMPROW row_pointer[1]; // compression data structure struct jpeg_compress_struct cinfo; ZeroMemory( &cinfo, sizeof( jpeg_compress_struct ) ); // point at stderr struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error( &jerr ); // create compressor jpeg_create_compress( &cinfo ); // Hook CUtlBuffer to compression jpeg_UtlBuffer_dest( &cinfo, &buf ); // image width and height, in pixels cinfo.image_width = bitmapInfo.bmiHeader.biWidth; cinfo.image_height = nHeight; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; // Apply settings jpeg_set_defaults( &cinfo ); jpeg_set_quality( &cinfo, 50, TRUE ); // Start compressor jpeg_start_compress( &cinfo, TRUE); char *pRowBuffer = (char*)_alloca( bitmapInfo.bmiHeader.biWidth * 3 ); row_pointer[0] = (JSAMPROW)pRowBuffer; // Write scanlines while ( cinfo.next_scanline < cinfo.image_height ) { char *pSrc; if ( bitmapInfo.bmiHeader.biHeight < 0 ) { // top down pSrc = &pBMPBits[cinfo.next_scanline * bitmapInfo.bmiHeader.biWidth * 4]; } else { // bottom up pSrc = &pBMPBits[(nHeight-1 - cinfo.next_scanline) * bitmapInfo.bmiHeader.biWidth * 4]; } // convert to BGR to RGB char *pDst = pRowBuffer; for ( int i=0; i<bitmapInfo.bmiHeader.biWidth; i++ ) { pDst[0] = pSrc[2]; pDst[1] = pSrc[1]; pDst[2] = pSrc[0]; pSrc += 4; pDst += 3; } jpeg_write_scanlines( &cinfo, row_pointer, 1 ); } // Finalize image jpeg_finish_compress( &cinfo ); char jpgFilename[MAX_PATH]; Sys_StripExtension( g_bug_szScreenshot, jpgFilename, sizeof( jpgFilename ) ); Sys_AddExtension( ".jpg", jpgFilename, sizeof( jpgFilename ) ); if ( !Sys_SaveFile( jpgFilename, buf.Base(), buf.TellMaxPut() ) ) goto cleanUp; // remove the uncompressed version unlink( g_bug_szScreenshot ); strcpy( g_bug_szScreenshot, jpgFilename ); bSuccess = true; cleanUp: if ( hBitmap ) DeleteObject( hBitmap ); if ( hDC ) DeleteDC( hDC ); if ( pBMPBits ) Sys_Free( pBMPBits ); return bSuccess; }
/** * * This function blocks the current process while waiting for an event that sends data which meet the condition. * * @param[in] eventID Identifier of the event that need to occur * @param[in] function Pointer to the function that represents the condition function (return true if condition is met and continues the process). If function = 0 .. condition is always met. * @return sys_event_data * Pointer to the event data struct that contains the values carried by the event */ sys_event_data *Sys_Wait_For_Condition(uint eventID, pConditionFunction function){ Sys_Block_Process(sys_running_process->pcb.process_ID, eventID, function); //This is only executed if process continued //now get return value (tansmited event data) Sys_Start_AtomicSection(); sys_process_event_handler *event = sys_running_process->pcb.event_register; sys_process_event_handler *prev_event = event; while(event != 0){ if(event->eventID == eventID && event->condition == function){ void *data = event->buffered_data; if(prev_event == event){ sys_running_process->pcb.event_register = event->next; }else{ prev_event->next = event->next; } event->next = 0; Sys_Free(event);//deletes event handler but leaves the data (return value) Sys_End_AtomicSection(); return data; } prev_event = event; event = event->next; } Sys_End_AtomicSection(); return 0; }
//----------------------------------------------------------------------------- // BugDlg_UploadFile // //----------------------------------------------------------------------------- bool BugDlg_UploadFile( char const *pLocalName, char const *pRemoteName, bool bDeleteLocal ) { FILE *fp; int len; void *pLocalData; ConsoleWindowPrintf( BUG_COLOR, "Uploading %s to %s\n", pLocalName, pRemoteName ); len = Sys_LoadFile( pLocalName, &pLocalData ); if ( !pLocalData || !len ) { ConsoleWindowPrintf( XBX_CLR_RED, "UploadFile: Unable to open local path '%s'\n", pLocalName ); return false; } Sys_CreatePath( pRemoteName ); fp = fopen( pRemoteName, "wb" ); if ( !fp ) { ConsoleWindowPrintf( XBX_CLR_RED, "UploadFile: Unable to open remote path '%s'\n", pRemoteName ); Sys_Free( pLocalData ); return false; } fwrite( pLocalData, len, 1, fp ); fclose( fp ); Sys_Free( pLocalData ); if ( bDeleteLocal ) { unlink( pLocalName ); } return true; }
/** * * This function executes all event handlers and processes stored event data. First it checks the list of occurred events and then it executes all event handlers of these events * */ inline void Sys_Execute_All_EventHandler(){ sys_occurred_event *o_event; Sys_Start_AtomicSection(); o_event = sys_occurred_events; sys_occurred_events = 0; while(o_event != 0){//assuming there are less processes then events Sys_Execute_Events_in_ProcessList(o_event->eventID, sys_ready_processes); Sys_Execute_Events_in_ProcessList(o_event->eventID, sys_blocked_processes); sys_occurred_event *occured_event = o_event; o_event = o_event->next; occured_event->next = 0; Sys_Free(occured_event); } Sys_End_AtomicSection(); }
/** * * This function adds the event-data to the local list of the process (pid). * * @param[in] pid process identifier * @param[in] eventID event identifier * @param[in] data memory that contains the value of the occurred event * @param[in] length length of the data (bytes) */ void Sys_Add_Event_to_Process(uint pid, uint eventID, void *data, uint length){ sys_pcb_list_element *element; Sys_Start_AtomicSection(); element = Sys_Find_Process(pid); if(element == 0){//no process with pid Sys_End_AtomicSection(); return; } bool add_event = true; sys_occurred_event **o_event = &sys_occurred_events; while(*o_event != 0){//check if the event (eventID) already occurred if((*o_event)->eventID == eventID){//it already occurred add_event = false; break; } o_event = &((*o_event)->next); } if(add_event){//if it hasn't occurred //add eventID to the list of occurred events (*o_event) = Sys_Malloc(sizeof(sys_occurred_event)); if((*o_event) == 0){ Sys_End_AtomicSection(); return; //no memory left } (*o_event)->eventID = eventID; (*o_event)->next = 0; } //NOW add the data sys_process_event_handler *event = element->pcb.event_register; while( (event = Sys_Next_EventHandler(event, eventID)) != 0 ){ //check if the condition was met to add the event data bool is_condition_met = false; if(event->condition != 0){ is_condition_met = event->condition(data); }else{//no condition is always met is_condition_met = true; } if( is_condition_met ){ sys_event_data *e_data = (sys_event_data*) Sys_Malloc(sizeof(sys_event_data)); if(e_data == 0){//if malloc fails .. exit Sys_End_AtomicSection(); return; } //create the struct that holds the data if(length != 0){//if there is data e_data->value = Sys_Malloc(length); if(e_data->value == 0){//if malloc fails .. exit Sys_Free(e_data); Sys_End_AtomicSection(); return; } Sys_Memcpy(data, e_data->value, length); }else{ e_data->value = 0; } e_data->size = length; e_data->next = 0; //add the struct to the end of the buffered_data if(event->buffered_data == 0){ event->buffered_data = e_data; }else{ sys_event_data *set_data = event->buffered_data; while(set_data->next != 0){ set_data = set_data->next; } set_data->next = e_data; } event = event->next; } } Sys_End_AtomicSection(); }