Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

mousecursor_generic.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: mousecursor_generic.cpp,v 1.1 2001/03/06 15:09:17 mbn Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 */
00014 
00015 #include "Core/precomp.h"
00016 
00017 #ifdef BORLAND
00018 #pragma hdrstop
00019 #endif
00020 
00021 #include "mousecursor_generic.h"
00022 #include "API/Display/Display/display.h"
00023 #include "API/Core/System/system.h"
00024 #include "API/Display/Input/mouse.h"
00025 #include "surface_generic.h"
00026 
00027 /**************************************
00028       class CL_MouseCursor_Generic
00029 **************************************/
00030 
00031 void CL_MouseCursor::set_cursor(
00032         CL_MouseCursorProvider *provider,
00033         int frame)
00034 {
00035         CL_MouseCursor_Generic::m_instance.set_cursor(provider, frame);
00036 }
00037 
00038 void CL_MouseCursor::show(bool show_async)
00039 {
00040         CL_MouseCursor_Generic::m_instance.show(show_async);
00041 }
00042 
00043 void CL_MouseCursor::hide()
00044 {
00045         CL_MouseCursor_Generic::m_instance.hide();
00046 }
00047 
00048 /**************************************
00049       class CL_MouseCursor_Generic
00050 **************************************/
00051 CL_MouseCursor_Generic CL_MouseCursor_Generic::m_instance;
00052 
00053 CL_MouseCursor_Generic::CL_MouseCursor_Generic() : m_rect(0,0,0,0)
00054 {
00055         m_buffer = NULL;
00056         m_provider = NULL;
00057         m_cursor = NULL;
00058         m_cur_frame = 0;
00059         m_frame_timer = 0;
00060         m_mux = CL_Mutex::create();
00061         m_thread = NULL;
00062         m_callback_added = false;
00063         m_last_x = m_last_y = -1;
00064 }
00065 
00066 CL_MouseCursor_Generic::~CL_MouseCursor_Generic()
00067 {
00068         delete[] m_buffer;
00069         delete m_mux;
00070         delete m_thread;
00071 }
00072 
00073 void CL_MouseCursor_Generic::run()
00074 {
00075         while (true)
00076         {
00077                 m_mux->enter();
00078 
00079                 if (m_provider != NULL)
00080                 {
00081                         CL_Target *target = ((CL_DisplayCard_Generic *) CL_Display::get_current_card())->get_frontbuffer();
00082                         show_cursor(target, true);
00083                 }
00084                 m_mux->leave();
00085 
00086                 CL_System::sleep(20);
00087         }
00088 }
00089 
00090 void CL_MouseCursor_Generic::pre_flip()
00091 {
00092         m_mux->enter();
00093 
00094         if (m_visible && m_provider != NULL)
00095         {
00096                 show_cursor(((CL_DisplayCard_Generic *) CL_Display::get_current_card())->get_target(), false);
00097         }
00098         else
00099         {
00100                 invalidate_region();
00101         }
00102 
00103         // Do not leave mutex, as this will happen in post_flip
00104 }
00105 
00106 void CL_MouseCursor_Generic::post_flip()
00107 {
00108         m_mux->leave();
00109 }
00110 
00111 void CL_MouseCursor_Generic::show_cursor(CL_Target *dest, bool load_saved)
00112 {
00113         if (!load_saved)
00114         {
00115                 invalidate_region();
00116         }
00117         int mouse_x = CL_Mouse::get_x();
00118         int mouse_y = CL_Mouse::get_y();
00119 
00120         int x1 = mouse_x+m_provider->get_surface_provider()->get_translate_x();
00121         int y1 = mouse_y+m_provider->get_surface_provider()->get_translate_y();
00122         if (load_saved && (x1 != m_last_x || y1 != m_last_y))
00123         {
00124                 load_region(dest);
00125         }
00126         m_last_x = x1;
00127         m_last_y = y1;
00128 
00129         if (m_provider->is_animated() && CL_System::get_time() >= m_frame_timer)
00130         {
00131                 m_cur_frame = (m_cur_frame+1) % m_provider->get_surface_provider()->get_num_frames();
00132                 int next_frame = m_provider->get_frame_delay(m_cur_frame);
00133                 if (next_frame == -1) next_frame = 100;
00134                 m_frame_timer = CL_System::get_time() + next_frame;
00135         }
00136 
00137         CL_ClipRect r(
00138                 x1,
00139                 y1,
00140                 x1+m_provider->get_surface_provider()->get_width(),
00141                 y1+m_provider->get_surface_provider()->get_height());
00142         CL_ClipRect scr_r = r.clip(CL_Display::get_current_card()->get_clip_rect());
00143         if (scr_r.m_x1 < scr_r.m_x2 && scr_r.m_y1 < scr_r.m_y2)
00144         {
00145                 save_region(dest, scr_r);
00146                 m_cursor->impl->get_cardsurface(
00147                         CL_Display::get_current_card())->put_screen(
00148                                 x1, y1, m_cur_frame, dest);
00149         }
00150         else
00151         {
00152                 invalidate_region();
00153         }
00154 }
00155 
00156 void CL_MouseCursor_Generic::set_cursor(
00157         CL_MouseCursorProvider *provider,
00158         int frame)
00159 {
00160         m_mux->enter();
00161         if (m_provider != NULL) 
00162         {
00163                 m_provider->get_surface_provider()->unlock();
00164                 delete m_cursor;
00165         }
00166         if (m_cursor != NULL)
00167         {
00168                 //delete m_cursor;
00169                 m_cursor = NULL;
00170         }
00171 
00172         m_provider = provider;
00173         if (m_provider != NULL)
00174         {
00175                 m_provider->get_surface_provider()->lock();
00176                 m_cursor = CL_Surface::create(m_provider->get_surface_provider(), false);
00177                 m_cur_frame = frame;
00178                //       if (m_cur_frame < 0) m_cur_frame = 0; m_cur_frame is unsigned
00179                 if (m_cur_frame >= provider->get_surface_provider()->get_num_frames())
00180                 {
00181                         m_cur_frame = provider->get_surface_provider()->get_num_frames()-1;
00182                 }
00183                 if (!m_callback_added)
00184                 {
00185                         ((CL_DisplayCard_Generic *) CL_Display::get_current_card())->add_callback(this);
00186                         m_callback_added = true;
00187                 }
00188                 show(true);
00189         }
00190         m_mux->leave();
00191         
00192         if (m_provider == NULL && m_visible) // make system cursor visible if no custom cursor was set.
00193         {
00194                 CL_DisplayCard_Generic *card = (CL_DisplayCard_Generic *) CL_Display::get_current_card();
00195                 card->show_system_cursor();
00196         }
00197         else if (m_provider != NULL && m_visible)
00198         {
00199                 CL_DisplayCard_Generic *card = (CL_DisplayCard_Generic *) CL_Display::get_current_card();
00200                 card->hide_system_cursor();
00201         }
00202 }
00203 
00204 void CL_MouseCursor_Generic::show(bool show_async)
00205 {
00206         m_async = show_async;
00207         m_visible = true;
00208 
00209         if (m_cursor == NULL) // if we have no custom cursor, use system cursor.
00210         {
00211                 CL_DisplayCard_Generic *card = (CL_DisplayCard_Generic *) CL_Display::get_current_card();
00212                 card->show_system_cursor();
00213                 return;
00214         }
00215 
00216         if (m_thread == NULL)
00217         {
00218                 m_thread = CL_Thread::create(this);
00219                 m_thread->start();
00220         }
00221 }
00222 
00223 void CL_MouseCursor_Generic::hide()
00224 {
00225         CL_DisplayCard_Generic *card = (CL_DisplayCard_Generic *) CL_Display::get_current_card();
00226         card->hide_system_cursor();
00227 
00228         m_mux->enter();
00229         m_visible = false;
00230         delete m_thread;
00231         m_thread = NULL;
00232         invalidate_region();
00233         m_mux->leave();
00234 }
00235 
00236 void CL_MouseCursor_Generic::invalidate_region()
00237 {
00238         delete[] m_buffer;
00239         m_buffer = NULL;
00240         m_rect = CL_ClipRect(0,0,0,0);
00241 }
00242 
00243 void CL_MouseCursor_Generic::save_region(CL_Target *source, const CL_ClipRect &r)
00244 {
00245         if (source == NULL) return;
00246 
00247         source->lock();
00248 
00249         if ((m_rect.m_x2-m_rect.m_x1) != (r.m_x2-r.m_x1) ||
00250                 (m_rect.m_y2-m_rect.m_y1) != (r.m_y2-r.m_y1))
00251         {
00252                 delete[] m_buffer;
00253                 m_buffer = new unsigned char[
00254                         (r.m_x2-r.m_x1)*
00255                         (r.m_y2-r.m_y1)*
00256                         source->get_bytes_per_pixel()];
00257         }
00258 
00259         int dest_pitch = (r.m_x2-r.m_x1)*source->get_bytes_per_pixel();
00260         unsigned char *dest_ptr = m_buffer;
00261         unsigned char *src_ptr = &((unsigned char *) source->get_data())[
00262                 r.m_y1*source->get_pitch()+
00263                 r.m_x1*source->get_bytes_per_pixel()];
00264         for (int y=r.m_y1;y<r.m_y2;y++)
00265         {
00266                 memcpy(
00267                         dest_ptr,
00268                         src_ptr,
00269                         dest_pitch);
00270                 dest_ptr += dest_pitch;
00271                 src_ptr += source->get_pitch();
00272         }
00273 
00274         m_rect = r;
00275 
00276         source->unlock();
00277 }
00278 
00279 void CL_MouseCursor_Generic::load_region(CL_Target *dest)
00280 {
00281         if (dest == NULL || m_buffer == NULL) return;
00282 
00283         dest->lock();
00284 
00285         int src_pitch = (m_rect.m_x2-m_rect.m_x1)*dest->get_bytes_per_pixel();
00286         unsigned char *src_ptr = m_buffer;
00287         unsigned char *dest_ptr = &((unsigned char *) dest->get_data())[
00288                 m_rect.m_y1*dest->get_pitch()+
00289                 m_rect.m_x1*dest->get_bytes_per_pixel()];
00290         for (int y=m_rect.m_y1;y<m_rect.m_y2;y++)
00291         {
00292                 memcpy(
00293                         dest_ptr,
00294                         src_ptr,
00295                         src_pitch);
00296                 src_ptr += src_pitch;
00297                 dest_ptr += dest->get_pitch();
00298         }
00299 
00300         dest->unlock();
00301 }

Generated at Wed Apr 4 19:54:02 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001