resolve some compiler warnings with intel c/c++ compiler
[blender-staging.git] / source / blender / src / space.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  *
30  * - here initialize and free and handling SPACE data
31  */
32
33 #include <string.h>
34 #include <stdio.h>
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include "MEM_guardedalloc.h"
41 #include "MEM_CacheLimiterC-Api.h"
42
43 #ifdef INTERNATIONAL
44 #include "BIF_language.h"
45 #endif
46
47 #include "IMB_imbuf_types.h"
48 #include "IMB_imbuf.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_gsqueue.h"
53 #include "BLI_linklist.h"
54
55 #include "DNA_action_types.h"
56 #include "DNA_armature_types.h"
57 #include "DNA_curve_types.h"
58 #include "DNA_group_types.h" /* used for select_same_group */
59 #include "DNA_gpencil_types.h"
60 #include "DNA_image_types.h"
61 #include "DNA_ipo_types.h"
62 #include "DNA_mesh_types.h"
63 #include "DNA_meshdata_types.h"
64 #include "DNA_modifier_types.h" /* used for select grouped hooks */
65 #include "DNA_object_types.h"
66 #include "DNA_particle_types.h"
67 #include "DNA_property_types.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_screen_types.h"
70 #include "DNA_sequence_types.h"
71 #include "DNA_sound_types.h"
72 #include "DNA_space_types.h"
73 #include "DNA_userdef_types.h"
74 #include "DNA_view2d_types.h"
75 #include "DNA_view3d_types.h"
76
77 #include "BKE_blender.h"
78 #include "BKE_colortools.h"
79 #include "BKE_curve.h"
80 #include "BKE_depsgraph.h"
81 #include "BKE_DerivedMesh.h"
82 #include "BKE_displist.h"
83 #include "BKE_global.h"
84 #include "BKE_group.h"
85 #include "BKE_ipo.h"
86 #include "BKE_main.h"
87 #include "BKE_mesh.h"
88 #include "BKE_multires.h"
89 #include "BKE_node.h"
90 #include "BKE_pointcache.h"
91 #include "BKE_property.h"
92 #include "BKE_scene.h"
93 #include "BKE_sculpt.h"
94 #include "BKE_texture.h"
95 #include "BKE_utildefines.h"
96 #include "BKE_image.h" /* for IMA_TYPE_COMPOSITE and IMA_TYPE_R_RESULT */
97 #include "BKE_particle.h"
98 #include "BIF_spacetypes.h"  /* first, nasty dependency with typedef */
99
100 #include "BIF_butspace.h"
101 #include "BIF_drawimage.h"
102 #include "BIF_drawseq.h"
103 #include "BIF_drawtext.h"
104 #include "BIF_drawscript.h"
105 #include "BIF_editarmature.h"
106 #include "BIF_editparticle.h"
107 #include "BIF_editconstraint.h"
108 #include "BIF_editdeform.h"
109 #include "BIF_editfont.h"
110 #include "BIF_editgroup.h"
111 #include "BIF_editkey.h"
112 #include "BIF_editlattice.h"
113 #include "BIF_editmesh.h"
114 #include "BIF_editmode_undo.h"
115 #include "BIF_editnla.h"
116 #include "BIF_editoops.h"
117 #include "BIF_editseq.h"
118 #include "BIF_editsima.h"
119 #include "BIF_editsound.h"
120 #include "BIF_editview.h"
121 #include "BIF_filelist.h"
122 #include "BIF_gl.h"
123 #include "BIF_imasel.h"
124 #include "BIF_interface.h"
125 #include "BIF_interface_icons.h"
126 #include "BIF_keyframing.h"
127 #include "BIF_meshtools.h"
128 #include "BIF_mywindow.h"
129 #include "BIF_oops.h"
130 #include "BIF_poselib.h"
131 #include "BIF_poseobject.h"
132 #include "BIF_outliner.h"
133 #include "BIF_radialcontrol.h"
134 #include "BIF_resources.h"
135 #include "BIF_retopo.h"
136 #include "BIF_screen.h"
137 #include "BIF_space.h"
138 #include "BIF_toets.h"
139 #include "BIF_toolbox.h"
140 #include "BIF_usiblender.h"
141 #include "BIF_previewrender.h"
142
143 #include "BSE_edit.h"
144 #include "BSE_view.h"
145 #include "BSE_editipo.h"
146 #include "BSE_drawipo.h"
147 #include "BSE_drawview.h"
148 #include "BSE_drawnla.h"
149 #include "BSE_filesel.h"
150 #include "BSE_headerbuttons.h"
151 #include "BSE_editnla_types.h"
152 #include "BSE_time.h"
153 #include "BSE_trans_types.h"
154
155 #include "BDR_vpaint.h"
156 #include "BDR_editmball.h"
157 #include "BDR_editobject.h"
158 #include "BDR_editcurve.h"
159 #include "BDR_editface.h"
160 #include "BDR_drawmesh.h"
161 #include "BDR_drawobject.h"
162 #include "BDR_imagepaint.h"
163 #include "BDR_sculptmode.h"
164 #include "BDR_unwrapper.h"
165 #include "BDR_gpencil.h"
166
167 #include "BLO_readfile.h" /* for BLO_blendhandle_close */
168
169 #include "PIL_time.h"
170
171 #include "BPY_extern.h"
172
173 #include "butspace.h"
174 #include "mydevice.h"
175 #include "blendef.h"
176 #include "datatoc.h"
177 #include "multires.h"
178
179 #include "BIF_transform.h"
180
181 #include "BKE_depsgraph.h"
182
183 #include "BSE_trans_types.h"
184
185 #include "SYS_System.h" /* for the user def menu ... should move elsewhere. */
186
187 #include "GPU_extensions.h"
188 #include "GPU_draw.h"
189
190 #include "BLO_sys_types.h" // for intptr_t support
191
192 /* maybe we need this defined somewhere else */
193 extern void StartKetsjiShell(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);
194 extern void StartKetsjiShellSimulation(ScrArea *area, char* startscenename, struct Main* maggie, struct SpaceIpo* sipo,int always_use_expand_framing);/*rcruiz*/
195
196 /**
197  * When the mipmap setting changes, we want to redraw the view right
198  * away to reflect this setting.
199  */
200 static void space_mipmap_button_function(int event);
201
202 static void free_soundspace(SpaceSound *ssound);
203
204 /* *************************************** */
205
206 /* don't know yet how the handlers will evolve, for simplicity
207    i choose for an array with eventcodes, this saves in a file!
208    */
209 void add_blockhandler(ScrArea *sa, short eventcode, short val)
210 {
211         SpaceLink *sl= sa->spacedata.first;
212         short a;
213         
214         /* find empty spot */
215         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
216                 if( sl->blockhandler[a]==eventcode ) {
217                         sl->blockhandler[a+1]= val;
218                         break;
219                 }
220                 else if( sl->blockhandler[a]==0) {
221                         sl->blockhandler[a]= eventcode;
222                         sl->blockhandler[a+1]= val;
223                         break;
224                 }
225         }
226         if(a==SPACE_MAXHANDLER) {
227                 error("Only %i floating panels allowed", SPACE_MAXHANDLER-1);
228         }
229                 
230 }
231
232 void rem_blockhandler(ScrArea *sa, short eventcode)
233 {
234         SpaceLink *sl= sa->spacedata.first;
235         short a;
236         
237         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
238                 if( sl->blockhandler[a]==eventcode) {
239                         sl->blockhandler[a]= 0;
240                         
241                         /* specific free calls */
242                         if(eventcode==IMAGE_HANDLER_PREVIEW)
243                                 image_preview_event(0);
244                         break;
245                 }
246         }
247 }
248
249 void toggle_blockhandler(ScrArea *sa, short eventcode, short val)
250 {
251         SpaceLink *sl= sa->spacedata.first;
252         short a, addnew=1;
253         
254         /* find if it exists */
255         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
256                 if( sl->blockhandler[a]==eventcode ) {
257                         sl->blockhandler[a]= 0;
258                         
259                         /* specific free calls */
260                         if(eventcode==VIEW3D_HANDLER_PREVIEW)
261                                 BIF_view3d_previewrender_free(sa->spacedata.first);
262                         else if(eventcode==IMAGE_HANDLER_PREVIEW)
263                                 image_preview_event(0);
264                         
265                         addnew= 0;
266                 }
267         }
268         if(addnew) {
269                 add_blockhandler(sa, eventcode, val);
270                 
271                 /* specific add new calls */
272                 if(eventcode==IMAGE_HANDLER_PREVIEW)
273                         image_preview_event(1);
274         }
275 }
276
277
278
279 /* ************* SPACE: VIEW3D  ************* */
280
281 /*  extern void drawview3dspace(ScrArea *sa, void *spacedata); BSE_drawview.h */
282
283
284 void copy_view3d_lock(short val)
285 {
286         bScreen *sc;
287         int bit;
288         
289         /* from G.scene copy to the other views */
290         sc= G.main->screen.first;
291         
292         while(sc) {
293                 if(sc->scene==G.scene) {
294                         ScrArea *sa= sc->areabase.first;
295                         while(sa) {
296                                 SpaceLink *sl= sa->spacedata.first;
297                                 while(sl) {
298                                         if(sl->spacetype==SPACE_OOPS && val==REDRAW) {
299                                                 if(sa->win) scrarea_queue_winredraw(sa);
300                                         }
301                                         else if(sl->spacetype==SPACE_VIEW3D) {
302                                                 View3D *vd= (View3D*) sl;
303                                                 if(vd->scenelock && vd->localview==0) {
304                                                         vd->lay= G.scene->lay;
305                                                         vd->camera= G.scene->camera;
306                                                         
307                                                         if(vd->camera==0 && vd->persp==V3D_CAMOB) vd->persp= V3D_PERSP;
308                                                         
309                                                         if( (vd->lay & vd->layact) == 0) {
310                                                                 bit= 0;
311                                                                 while(bit<32) {
312                                                                         if(vd->lay & (1<<bit)) {
313                                                                                 vd->layact= 1<<bit;
314                                                                                 break;
315                                                                         }
316                                                                         bit++;
317                                                                 }
318                                                         }
319                                                         
320                                                         if(val==REDRAW && vd==sa->spacedata.first) {
321                                                                 if(sa->win) scrarea_queue_redraw(sa);
322                                                         }
323                                                 }
324                                         }
325                                         sl= sl->next;
326                                 }
327                                 sa= sa->next;
328                         }
329                 }
330                 sc= sc->id.next;
331         }
332 }
333
334 void handle_view3d_around()
335 {
336         bScreen *sc;
337         
338         if ((U.uiflag & USER_LOCKAROUND)==0) return;
339         
340         /* copies from G.vd->around to other view3ds */
341         
342         sc= G.main->screen.first;
343         
344         while(sc) {
345                 if(sc->scene==G.scene) {
346                         ScrArea *sa= sc->areabase.first;
347                         while(sa) {
348                                 SpaceLink *sl= sa->spacedata.first;
349                                 while(sl) {
350                                         if(sl->spacetype==SPACE_VIEW3D) {
351                                                 View3D *vd= (View3D*) sl;
352                                                 if (vd != G.vd) {
353                                                         vd->around= G.vd->around;
354                                                         if (G.vd->flag & V3D_ALIGN)
355                                                                 vd->flag |= V3D_ALIGN;
356                                                         else
357                                                                 vd->flag &= ~V3D_ALIGN;
358                                                         scrarea_queue_headredraw(sa);
359                                                 }
360                                         }
361                                         sl= sl->next;
362                                 }
363                                 sa= sa->next;
364                         }
365                 }
366                 sc= sc->id.next;
367         }
368 }
369
370 void handle_view3d_lock()
371 {       
372         if (G.vd != NULL && curarea != NULL ) {
373                 if(G.vd->localview==0 && G.vd->scenelock && curarea->spacetype==SPACE_VIEW3D) {
374
375                         /* copy to scene */
376                         G.scene->lay= G.vd->lay;
377                         G.scene->camera= G.vd->camera;
378         
379                         copy_view3d_lock(REDRAW);
380                 }
381         }
382 }
383
384 void space_set_commmandline_options(void) {
385         SYS_SystemHandle syshandle;
386         int a;
387                 
388         if ( (syshandle = SYS_GetSystem()) ) {
389                 /* User defined settings */
390                 a= (U.gameflags & USER_DISABLE_SOUND);
391                 /* if user already disabled audio at the command-line, don't re-enable it */
392                 if (a)
393                 {
394                         SYS_WriteCommandLineInt(syshandle, "noaudio", a);
395                 }
396
397                 a= (U.gameflags & USER_DISABLE_MIPMAP);
398                 GPU_set_mipmap(!a);
399                 SYS_WriteCommandLineInt(syshandle, "nomipmap", a);
400
401                 /* File specific settings: */
402                 /* Only test the first one. These two are switched
403                  * simultaneously. */
404                 a= (G.fileflags & G_FILE_SHOW_FRAMERATE);
405                 SYS_WriteCommandLineInt(syshandle, "show_framerate", a);
406                 SYS_WriteCommandLineInt(syshandle, "show_profile", a);
407
408                 /* When in wireframe mode, always draw debug props. */
409                 if (G.vd) {
410                         a = ( (G.fileflags & G_FILE_SHOW_DEBUG_PROPS) 
411                                   || (G.vd->drawtype == OB_WIRE)          
412                                   || (G.vd->drawtype == OB_SOLID)         );
413                         SYS_WriteCommandLineInt(syshandle, "show_properties", a);
414                 }
415                 
416                 a= (G.fileflags & G_FILE_SHOW_PHYSICS);
417                 SYS_WriteCommandLineInt(syshandle, "show_physics", a);
418
419                 a= (G.fileflags & G_FILE_ENABLE_ALL_FRAMES);
420                 SYS_WriteCommandLineInt(syshandle, "fixedtime", a);
421
422                 a= (G.fileflags & G_FILE_GAME_TO_IPO);
423                 SYS_WriteCommandLineInt(syshandle, "game2ipo", a);
424
425                 a=(G.fileflags & G_FILE_GAME_MAT);
426                 SYS_WriteCommandLineInt(syshandle, "blender_material", a);
427                 a=(G.fileflags & G_FILE_GAME_MAT_GLSL);
428                 SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", a);
429                 a=(G.fileflags & G_FILE_DISPLAY_LISTS);
430                 SYS_WriteCommandLineInt(syshandle, "displaylists", a);
431
432
433         }
434 }
435
436 #if GAMEBLENDER == 1
437         /**
438          * These two routines imported from the gameengine, 
439          * I suspect a lot of the resetting stuff is cruft
440          * and can be removed, but it should be checked.
441          */
442 static void SaveState(void)
443 {
444         glPushAttrib(GL_ALL_ATTRIB_BITS);
445
446         GPU_state_init();
447
448         if(G.f & G_TEXTUREPAINT)
449                 GPU_paint_set_mipmap(1);
450
451         waitcursor(1);
452 }
453
454 static void RestoreState(void)
455 {
456         if(G.f & G_TEXTUREPAINT)
457                 GPU_paint_set_mipmap(0);
458
459         curarea->win_swap = 0;
460         curarea->head_swap=0;
461         allqueue(REDRAWVIEW3D, 1);
462         allqueue(REDRAWBUTSALL, 0);
463         reset_slowparents();
464         waitcursor(0);
465         G.qual= 0;
466         glPopAttrib();
467 }
468
469 static LinkNode *save_and_reset_all_scene_cfra(void)
470 {
471         LinkNode *storelist= NULL;
472         Scene *sc;
473         
474         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
475                 BLI_linklist_prepend(&storelist, (void*) (intptr_t) sc->r.cfra);
476
477                 /* why is this reset to 1 ?*/
478                 /* sc->r.cfra= 1;*/
479
480                 set_scene_bg(sc);
481         }
482         
483         BLI_linklist_reverse(&storelist);
484         
485         return storelist;
486 }
487
488 static void restore_all_scene_cfra(LinkNode *storelist) {
489         LinkNode *sc_store= storelist;
490         Scene *sc;
491         
492         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
493                 int stored_cfra= (intptr_t) sc_store->link;
494                 
495                 sc->r.cfra= stored_cfra;
496                 set_scene_bg(sc);
497                 
498                 sc_store= sc_store->next;
499         }
500         
501         BLI_linklist_free(storelist, NULL);
502 }
503 #endif
504
505 void start_game(void)
506 {
507 #if GAMEBLENDER == 1
508 #ifndef NO_KETSJI
509         Scene *sc, *startscene = G.scene;
510         LinkNode *scene_cfra_store;
511
512                 /* XXX, silly code -  the game engine can
513                  * access any scene through logic, so we try 
514                  * to make sure each scene has a valid camera, 
515                  * just in case the game engine tries to use it.
516                  * 
517                  * Better would be to make a better routine
518                  * in the game engine for finding the camera.
519                  *  - zr
520                  * Note: yes, this is all very badly hacked! (ton)
521                  */
522         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
523                 if (!sc->camera) {
524                         Base *base;
525         
526                         for (base= sc->base.first; base; base= base->next)
527                                 if (base->object->type==OB_CAMERA)
528                                         break;
529                         
530                         sc->camera= base?base->object:NULL;
531                 }
532         }
533
534         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
535         markdirty_all();
536         screen_swapbuffers();
537
538         /* can start from header */
539         mywinset(curarea->win);
540     
541         scene_cfra_store= save_and_reset_all_scene_cfra();
542         
543
544         /* game engine will do its own sounds. */
545         sound_stop_all_sounds();
546         sound_exit_audio();
547         
548         /* Before jumping into Ketsji, we configure some settings. */
549         space_set_commmandline_options();
550
551         SaveState();
552         StartKetsjiShell(curarea, startscene->id.name+2, G.main,G.sipo, 1);
553         RestoreState();
554
555         /* Restart BPY - unload the game engine modules. */
556
557         /* Commented out: testing before Blender 2.46 if it's ok to keep
558          * these modules around, they give access to relevant info for
559          * exporters to other engines...
560         BPY_end_python();
561         BPY_start_python(0, NULL); 
562         BPY_post_start_python();
563         */
564
565         restore_all_scene_cfra(scene_cfra_store);
566         set_scene_bg(startscene);
567         scene_update_for_newframe(G.scene, G.scene->lay);
568
569         if (G.flags & G_FILE_AUTOPLAY)
570                 exit_usiblender();
571
572                 /* groups could have changed ipo */
573         allqueue(REDRAWNLA, 0);
574         allqueue(REDRAWACTION, 0);
575         allspace(REMAKEIPO, 0);
576         allqueue(REDRAWIPO, 0);
577 #endif
578 #else
579         notice("Game engine is disabled in this release!");
580 #endif
581 }
582
583 void start_RBSimulation(void)
584 {
585 #if GAMEBLENDER == 1
586 #ifndef NO_KETSJI
587         Scene *sc, *startscene = G.scene;
588         LinkNode *scene_cfra_store;
589
590                 /* XXX, silly code -  the game engine can
591                  * access any scene through logic, so we try
592                  * to make sure each scene has a valid camera,
593                  * just in case the game engine tries to use it.
594                  *
595                  * Better would be to make a better routine
596                  * in the game engine for finding the camera.
597                  *  - zr
598                  * Note: yes, this is all very badly hacked! (ton)
599                  */
600         for (sc= G.main->scene.first; sc; sc= sc->id.next) {
601                 if (!sc->camera) {
602                         Base *base;
603
604                         for (base= sc->base.first; base; base= base->next)
605                                 if (base->object->type==OB_CAMERA)
606                                         break;
607
608                         sc->camera= base?base->object:NULL;
609                 }
610         }
611
612         /* these two lines make sure front and backbuffer are equal. for swapbuffers */
613         markdirty_all();
614         screen_swapbuffers();
615
616         /* can start from header */
617         mywinset(curarea->win);
618
619         scene_cfra_store= save_and_reset_all_scene_cfra();
620
621
622         /* game engine will do its own sounds. */
623         sound_stop_all_sounds();
624         sound_exit_audio();
625
626         /* Before jumping into Ketsji, we configure some settings. */
627         space_set_commmandline_options();
628
629         SaveState();
630         StartKetsjiShellSimulation(curarea, startscene->id.name+2, G.main,G.sipo, 1);
631         RestoreState();
632
633         /* Restart BPY - unload the game engine modules. */
634
635         /* Commented out: testing before Blender 2.46 if it's ok to keep
636          * these modules around, they give access to relevant info for
637          * exporters to other engines...
638         BPY_end_python();
639         BPY_start_python(0, NULL); 
640         BPY_post_start_python();
641         */
642
643         restore_all_scene_cfra(scene_cfra_store);
644         set_scene_bg(startscene);
645         scene_update_for_newframe(G.scene, G.scene->lay);
646
647         if (G.flags & G_FILE_AUTOPLAY)
648                 exit_usiblender();
649
650                 /* groups could have changed ipo */
651         allqueue(REDRAWNLA, 0);
652         allqueue(REDRAWACTION, 0);
653         allspace(REMAKEIPO, 0);
654         allqueue(REDRAWIPO, 0);
655 #endif
656 #else
657         notice("YOU NEED GAME ENGIEN TO RUN THE SIMULATION!");
658 #endif
659 }
660
661 static void changeview3dspace(ScrArea *sa, void *spacedata)
662 {
663         setwinmatrixview3d(sa->winx, sa->winy, NULL);   /* 0= no pick rect */
664 }
665
666         /* Callable from editmode and faceselect mode from the
667          * moment, would be nice (and is easy) to generalize
668          * to any mode.
669          */
670 static void align_view_to_selected(View3D *v3d)
671 {
672         int nr= pupmenu("Align View (Ctrl flips)%t|To Selected (top)%x3|To Selected (front)%x2|To Selected (side)%x1");
673         if (nr!=-1) {
674                 int axis= nr;
675                 
676                 /* opposite axis in case ctrl is pressed */
677                 if(G.qual==LR_CTRLKEY) axis= -axis;
678                 
679                 if ((G.obedit) && (G.obedit->type == OB_MESH)) {
680                         editmesh_align_view_to_selected(v3d, axis);
681                         addqueue(v3d->area->win, REDRAW, 1);
682                 } else if (FACESEL_PAINT_TEST) {
683                         Object *obact= OBACT;
684                         if (obact && obact->type==OB_MESH) {
685                                 Mesh *me= obact->data;
686                                 faceselect_align_view_to_selected(v3d, me, axis);
687                                 addqueue(v3d->area->win, REDRAW, 1);
688                         }
689                 }
690         }
691 }
692
693
694 static short select_children(Object *ob, int recursive)
695 {
696         short changed = 0;
697         Base *base;
698         
699         for (base= FIRSTBASE; base; base= base->next) {
700                 if (ob == base->object->parent) {
701                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT)) {
702                                 base->flag |= SELECT;
703                                 base->object->flag |= SELECT;
704                                 changed = 1;
705                         }
706                         
707                         if (recursive)
708                                 changed |= select_children(base->object, 1);
709                 }
710         }
711         return changed;
712 }
713
714 static short select_parent(void)        /* Makes parent active and de-selected OBACT */
715 {
716         short changed = 0;
717         Base *base, *startbase, *basact=NULL, *oldbasact;
718         
719         if (!(OBACT->parent)) return 0; /* we know OBACT is valid */
720         BASACT->flag &= (~SELECT);
721         BASACT->object->flag &= (~SELECT);
722         startbase=  FIRSTBASE;
723         if(BASACT && BASACT->next) startbase= BASACT->next;
724         base = startbase;
725         while(base) {
726                 if(base->object==BASACT->object->parent) { basact=base; break; }
727                 base=base->next;
728                 if(base==NULL) base= FIRSTBASE;
729                 if(base==startbase) break;
730         }
731         /* can be NULL if parent in other scene */
732         if(basact && BASE_SELECTABLE(basact)) {
733                 oldbasact = BASACT;
734                 BASACT = basact;
735                 basact->flag |= SELECT;         
736                 
737                 basact->object->flag= basact->flag;
738                 
739                 set_active_base(basact);
740                 changed = 1;
741         }
742         return changed;
743 }
744
745
746 #define GROUP_MENU_MAX  24
747 static short select_same_group(Object *ob)      /* Select objects in the same group as the active */
748 {
749         short changed = 0;
750         Base *base;
751         Group *group, *ob_groups[GROUP_MENU_MAX];
752         char str[10 + (24*GROUP_MENU_MAX)];
753         char *p = str;
754         int group_count=0, menu, i;
755         
756         for (   group=G.main->group.first;
757                         group && group_count < GROUP_MENU_MAX;
758                         group=group->id.next
759                 ) {
760                 if (object_in_group (ob, group)) {
761                         ob_groups[group_count] = group;
762                         group_count++;
763                 }
764         }
765         
766         if (!group_count)
767                 return 0;
768         
769         else if (group_count == 1) {
770                 group = ob_groups[0];
771                 for (base= FIRSTBASE; base; base= base->next) {
772                         if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && object_in_group(base->object, group)) {
773                                 base->flag |= SELECT;
774                                 base->object->flag |= SELECT;
775                                 changed = 1;
776                         }
777                 }
778                 return changed;
779         }
780         
781         /* build the menu. */
782         p += sprintf(str, "Groups%%t"); 
783         for (i=0; i<group_count; i++) {
784                 group = ob_groups[i];
785                 p += sprintf (p, "|%s%%x%i", group->id.name+2, i);
786         }
787         
788         menu = pupmenu (str);
789         if (menu == -1)
790                 return 0;
791         
792         group = ob_groups[menu];
793         for (base= FIRSTBASE; base; base= base->next) {
794                 if (!(base->flag & SELECT) && object_in_group(base->object, group)) {
795                         base->flag |= SELECT;
796                         base->object->flag |= SELECT;
797                         changed = 1;
798                 }
799         }
800         return changed;
801 }
802
803 static short select_object_hooks(Object *ob)
804 {
805         short changed = 0;
806         Base *base;
807         ModifierData *md;
808         HookModifierData *hmd;
809         
810         for (md = ob->modifiers.first; md; md=md->next) {
811                 if (md->type==eModifierType_Hook) {
812                         hmd= (HookModifierData*) md;
813                         if (hmd->object && !(hmd->object->flag & SELECT)) {
814                                 base= object_in_scene(hmd->object, G.scene);
815                                 if (base && BASE_SELECTABLE(base)) {
816                                         base->flag |= SELECT;
817                                         base->object->flag |= SELECT;
818                                         changed = 1;
819                                 }
820                         }
821                 }
822         }
823         return changed;
824 }
825
826 /* Select objects woth the same parent as the active (siblings),
827  * parent can be NULL also */
828 static short select_same_parent(Object *ob)     
829 {
830         short changed = 0;
831         Base *base;
832         
833         for (base= FIRSTBASE; base; base= base->next) {
834                 if (BASE_SELECTABLE(base) && (base->object->parent==ob->parent)  && !(base->flag & SELECT)) {
835                         base->flag |= SELECT;
836                         base->object->flag |= SELECT;
837                         changed = 1;
838                 }
839         }
840         return changed;
841 }
842
843 static short select_same_type(Object *ob)
844 {
845         short changed = 0;
846         Base *base;
847         
848         for (base= FIRSTBASE; base; base= base->next) {
849                 if (BASE_SELECTABLE(base) && (base->object->type == ob->type) && !(base->flag & SELECT)) {
850                         base->flag |= SELECT;
851                         base->object->flag |= SELECT;
852                         changed = 1;
853                 }
854         }
855         return changed;
856 }
857
858 static short select_same_layer(Object *ob)
859 {
860         char changed = 0;
861         Base *base = FIRSTBASE;
862         
863         while(base) {
864                 if (BASE_SELECTABLE(base) && (base->lay & ob->lay) && !(base->flag & SELECT)) {
865                         base->flag |= SELECT;
866                         base->object->flag |= SELECT;
867                         changed = 1;
868                 }
869                 base= base->next;
870         }
871         return changed;
872 }
873
874 static short select_same_index_object(Object *ob)
875 {
876         char changed = 0;
877         Base *base = FIRSTBASE;
878         
879         while(base) {
880                 if (BASE_SELECTABLE(base) && (base->object->index == ob->index) && !(base->flag & SELECT)) {
881                         base->flag |= SELECT;
882                         base->object->flag |= SELECT;
883                         changed = 1;
884                 }
885                 base= base->next;
886         }
887         return changed;
888 }
889
890 static short select_same_color(Object *ob)
891 {
892         char changed = 0;
893         Base *base = FIRSTBASE;
894         
895         while(base) {
896                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (FloatCompare(base->object->col, ob->col, 0.005))) {
897                         base->flag |= SELECT;
898                         base->object->flag |= SELECT;
899                         changed = 1;
900                 }
901                 base= base->next;
902         }
903         return changed;
904 }
905
906 static short objects_share_gameprop(Object *a, Object *b)
907 {
908         bProperty *prop;
909         /*make a copy of all its properties*/
910         
911         for( prop= a->prop.first; prop; prop = prop->next ) {
912                 if ( get_ob_property(b, prop->name) )
913                         return 1;
914         }
915         return 0;
916 }
917
918 static short select_same_gameprops(Object *ob)
919 {
920         char changed = 0;
921         Base *base = FIRSTBASE;
922         
923         while(base) {
924                 if (BASE_SELECTABLE(base) && !(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) {
925                         base->flag |= SELECT;
926                         base->object->flag |= SELECT;
927                         changed = 1;
928                 }
929                 base= base->next;
930         }
931         return changed;
932 }
933
934 void select_object_grouped(short nr)
935 {
936         Object *ob = OBACT;
937         short changed = 0;
938         
939         if (ob==NULL) return;
940         
941         if(nr==1)               changed = select_children(ob, 1);
942         else if(nr==2)  changed = select_children(ob, 0);
943         else if(nr==3)  changed = select_parent();
944         else if(nr==4)  changed = select_same_parent(ob);       
945         else if(nr==5)  changed = select_same_type(ob);
946         else if(nr==6)  changed = select_same_layer(ob);        
947         else if(nr==7)  changed = select_same_group(ob);
948         else if(nr==8)  changed = select_object_hooks(ob);
949         else if(nr==9)  changed = select_same_index_object(ob);
950         else if(nr==10) changed = select_same_color(ob);
951         else if(nr==11) changed = select_same_gameprops(ob);
952         
953         if (changed) {
954                 countall();
955                 allqueue(REDRAWVIEW3D, 0);
956                 allqueue(REDRAWBUTSOBJECT, 0);
957                 allspace(REMAKEIPO, 0);
958                 allqueue(REDRAWIPO, 0);
959                 BIF_undo_push("Select Grouped");
960         }
961 }
962
963 static void select_object_grouped_menu(void)
964 {
965         char *str;
966         short nr;
967
968         /* make menu string */
969         
970         str= MEM_mallocN(512, "groupmenu");
971         strcpy(str, "Select Grouped%t|Children%x1|"
972                     "Immediate Children%x2|Parent%x3|"
973                     "Siblings (Shared Parent)%x4|"
974                     "Objects of Same Type%x5|"
975                                 "Objects on Shared Layers%x6|"
976                 "Objects in Same Group%x7|"
977                 "Object Hooks%x8|"
978                                 "Object PassIndex%x9|"
979                                 "Object Color%x10|"
980                                 "Game Properties%x11");
981
982         /* here we go */
983         
984         nr= pupmenu(str);
985         MEM_freeN(str);
986         
987         select_object_grouped(nr);
988 }
989
990 void join_menu(void)
991 {
992         Object *ob= OBACT;
993         if (G.obedit) {
994                 error("This data does not support joining in editmode");
995                 return;
996         }
997         if (!ob) {
998                 error("Can't join unless there is an active object");
999                 return;
1000         }
1001         
1002         if(ob->type == OB_MESH) {
1003                 if(okee("Join selected meshes")==0) return;
1004                 join_mesh();
1005         } else if(ob->type == OB_CURVE) {
1006                 if(okee("Join selected curves")==0) return;
1007                 join_curve(OB_CURVE);
1008         } else if(ob->type == OB_SURF) {
1009                 if(okee("Join selected NURBS")==0) return;
1010                 join_curve(OB_SURF);
1011         } else if(ob->type == OB_ARMATURE) {
1012                 /*      Make sure the user wants to continue*/
1013                 if(okee("Join selected armatures")==0) return;
1014                 join_armature ();
1015         } else {
1016                 error("This object type doesn't support joining");
1017         }
1018 }
1019
1020 static unsigned short convert_for_nonumpad(unsigned short event)
1021 {
1022         if (event>=ZEROKEY && event<=NINEKEY) {
1023                 return event - ZEROKEY + PAD0;
1024         } else if (event==MINUSKEY) {
1025                 return PADMINUS;
1026         } else if (event==EQUALKEY) {
1027                 return PADPLUSKEY;
1028         } else if (event==BACKSLASHKEY) {
1029                 return PADSLASHKEY;
1030         } else {
1031                 return event;
1032         }
1033 }
1034
1035 /* *************** */
1036
1037 void BIF_undo_push(char *str)
1038 {
1039         if(G.obedit) {
1040                 if (U.undosteps == 0) return;
1041
1042                 if(G.obedit->type==OB_MESH)
1043                         undo_push_mesh(str);
1044                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1045                         undo_push_curve(str);
1046                 else if (G.obedit->type==OB_FONT)
1047                         undo_push_font(str);
1048                 else if (G.obedit->type==OB_MBALL)
1049                         undo_push_mball(str);
1050                 else if (G.obedit->type==OB_LATTICE)
1051                         undo_push_lattice(str);
1052                 else if (G.obedit->type==OB_ARMATURE)
1053                         undo_push_armature(str);
1054         }
1055         else if(G.f & G_PARTICLEEDIT) {
1056                 if (U.undosteps == 0) return;
1057
1058                 PE_undo_push(str);
1059         }
1060         else {
1061                 if(U.uiflag & USER_GLOBALUNDO) 
1062                         BKE_write_undo(str);
1063         }
1064 }
1065
1066 void BIF_undo(void)
1067 {       
1068         if(G.obedit) {
1069                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1070                         undo_editmode_step(1);
1071         }
1072         else {
1073                 if(G.f & G_TEXTUREPAINT)
1074                         undo_imagepaint_step(1);
1075                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1076                         undo_imagepaint_step(1);
1077                 else if(G.f & G_PARTICLEEDIT)
1078                         PE_undo();
1079                 else {
1080                         /* now also in faceselect mode */
1081                         if(U.uiflag & USER_GLOBALUNDO) {
1082                                 BPY_scripts_clear_pyobjects();
1083                                 BKE_undo_step(1);
1084                                 sound_initialize_sounds();
1085                         }
1086                 }
1087         }
1088 }
1089
1090 void BIF_redo(void)
1091 {
1092         if(G.obedit) {
1093                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1094                         undo_editmode_step(-1);
1095         }
1096         else {
1097                 if(G.f & G_TEXTUREPAINT)
1098                         undo_imagepaint_step(-1);
1099                 else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL))
1100                         undo_imagepaint_step(-1);
1101                 else if(G.f & G_PARTICLEEDIT)
1102                         PE_redo();
1103                 else {
1104                         /* includes faceselect now */
1105                         if(U.uiflag & USER_GLOBALUNDO) {
1106                                 BKE_undo_step(-1);
1107                                 sound_initialize_sounds();
1108                         }
1109                 }
1110         }
1111 }
1112
1113 void BIF_undo_menu(void)
1114 {
1115         if(G.obedit) {
1116                 if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
1117                         undo_editmode_menu();
1118                 allqueue(REDRAWALL, 0);
1119         }
1120         else {
1121                 if(G.f & G_PARTICLEEDIT)
1122                         PE_undo_menu();
1123                 else if(U.uiflag & USER_GLOBALUNDO) {
1124                         char *menu= BKE_undo_menu_string();
1125                         if(menu) {
1126                                 short event= pupmenu_col(menu, 20);
1127                                 MEM_freeN(menu);
1128                                 if(event>0) {
1129                                         BKE_undo_number(event);
1130                                         sound_initialize_sounds();
1131                                 }
1132                         }
1133                 }
1134         }
1135 }
1136
1137 /* *************** */
1138
1139 void handle_view_middlemouse() {
1140         /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1141         if(U.flag & USER_VIEWMOVE) {
1142                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1143                         viewmove(0);
1144                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1145                         viewmove(2);
1146                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1147                         viewmove(1);
1148         }
1149         else {
1150                 if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1151                         viewmove(1);
1152                 else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1153                         viewmove(2);
1154                 else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1155                         viewmove(0);
1156         }
1157 }
1158
1159 void handle_view_wheelup()
1160 {
1161         /* Regular:   Zoom in */
1162         /* Shift:     Scroll up */
1163         /* Ctrl:      Scroll right */
1164         /* Alt-Shift: Rotate up */
1165         /* Alt-Ctrl:  Rotate right */
1166
1167         if( G.qual & LR_SHIFTKEY ) {
1168                 if( G.qual & LR_ALTKEY ) { 
1169                         G.qual &= ~LR_SHIFTKEY;
1170                         persptoetsen(PAD2);
1171                         G.qual |= LR_SHIFTKEY;
1172                 } else {
1173                         persptoetsen(PAD2);
1174                 }
1175         } else if( G.qual & LR_CTRLKEY ) {
1176                 if( G.qual & LR_ALTKEY ) { 
1177                         G.qual &= ~LR_CTRLKEY;
1178                         persptoetsen(PAD4);
1179                         G.qual |= LR_CTRLKEY;
1180                 } else {
1181                         persptoetsen(PAD4);
1182                 }
1183         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1184                 persptoetsen(PADMINUS);
1185         else
1186                 persptoetsen(PADPLUSKEY);
1187 }
1188
1189 void handle_view_wheeldown()
1190 {
1191         /* Regular:   Zoom out */
1192         /* Shift:     Scroll down */
1193         /* Ctrl:      Scroll left */
1194         /* Alt-Shift: Rotate down */
1195         /* Alt-Ctrl:  Rotate left */
1196
1197         if( G.qual & LR_SHIFTKEY ) {
1198                 if( G.qual & LR_ALTKEY ) { 
1199                         G.qual &= ~LR_SHIFTKEY;
1200                         persptoetsen(PAD8);
1201                         G.qual |= LR_SHIFTKEY;
1202                 } else {
1203                         persptoetsen(PAD8);
1204                 }
1205         } else if( G.qual & LR_CTRLKEY ) {
1206                 if( G.qual & LR_ALTKEY ) { 
1207                         G.qual &= ~LR_CTRLKEY;
1208                         persptoetsen(PAD6);
1209                         G.qual |= LR_CTRLKEY;
1210                 } else {
1211                         persptoetsen(PAD6);
1212                 }
1213         } else if(U.uiflag & USER_WHEELZOOMDIR) 
1214                 persptoetsen(PADPLUSKEY);
1215         else
1216                 persptoetsen(PADMINUS);
1217 }
1218
1219 int mouse_in_header(ScrArea *sa)
1220 {
1221         short mouse[2];
1222         getmouseco_sc(mouse);
1223         return mouse[0] >= sa->headrct.xmin &&
1224                mouse[0] <= sa->headrct.xmax &&
1225                mouse[1] >= sa->headrct.ymin &&
1226                mouse[1] <= sa->headrct.ymax;
1227 }
1228
1229 static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
1230 {
1231         View3D *v3d= sa->spacedata.first;
1232         Object *ob= OBACT;      /* do not change! */
1233         float *curs;
1234         int doredraw= 0, pupval;
1235         unsigned short event= evt->event;
1236         short val= evt->val;
1237         char ascii= evt->ascii;
1238         
1239         if(curarea->win==0) return;     /* when it comes from sa->headqread() */
1240         
1241         if(val) {
1242
1243                 if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
1244                 
1245                 if(event==UI_BUT_EVENT) do_butspace(val); /* temporal, view3d deserves own queue? */
1246                 
1247                 /* - we consider manipulator a button, defaulting to leftmouse 
1248                  * - grease-pencil also defaults to leftmouse
1249                  */
1250                 if(event==LEFTMOUSE) {
1251                         /* run any view3d event handler script links */
1252                         if (sa->scriptlink.totscript) {
1253                                 if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1254                                         return; /* return if event was processed (swallowed) by handler(s) */
1255                         }
1256                         
1257                         if(gpencil_do_paint(sa, L_MOUSE)) return;
1258                         if(BIF_do_manipulator(sa)) return;
1259                 }
1260                 else if(event==RIGHTMOUSE) {
1261                         if(gpencil_do_paint(sa, R_MOUSE)) return;
1262                 }
1263                 
1264                 /* swap mouse buttons based on user preference */
1265                 if (U.flag & USER_LMOUSESELECT) {
1266                         /* only swap mouse button for selection, in modes where it is relevant.
1267                          * painting/sculpting stays on LEFTMOUSE */
1268                         if (   !((G.f & G_SCULPTMODE) || (G.f & G_WEIGHTPAINT) || (G.f & G_GREASEPENCIL) ||
1269                                 (G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_PARTICLEEDIT)) ||
1270                                 (G.obedit) )
1271                         {                       
1272                                 if (event==LEFTMOUSE) event = RIGHTMOUSE;
1273                                 else if (event==RIGHTMOUSE) event = LEFTMOUSE;
1274                         }
1275                 }
1276
1277                 if(!mouse_in_header(sa)) {
1278                         if(!G.obedit && (G.f & G_SCULPTMODE)) {
1279                                 SculptSession *ss= sculpt_session();
1280                                 if(ss && ss->radialcontrol) {
1281                                         radialcontrol_do_events(ss->radialcontrol, event);
1282                                         return;
1283                                 }
1284                                 else if(event!=LEFTMOUSE && event!=MIDDLEMOUSE && (event==MOUSEY || event==MOUSEX)) {
1285                                         if(!bwin_qtest(sa->win))
1286                                                 allqueue(REDRAWVIEW3D, 0);
1287                                 }
1288                         }
1289                         else if(!G.obedit && OBACT && G.f&G_PARTICLEEDIT){
1290                                 ParticleSystem *psys=PE_get_current(OBACT);
1291                                 ParticleEditSettings *pset=PE_settings();
1292                                 if(*PE_radialcontrol()) {
1293                                         radialcontrol_do_events(*PE_radialcontrol(), event);
1294                                         return;
1295                                 }
1296                                 if(psys && psys->edit){
1297                                         if(pset->brushtype>=0 &&
1298                                                 event!=LEFTMOUSE && event!=RIGHTMOUSE && event!=MIDDLEMOUSE &&
1299                                                 (event==MOUSEY || event==MOUSEX) && bwin_qtest(sa->win)==0) {
1300                                                 allqueue(REDRAWVIEW3D, 0);
1301                                         }
1302                                 }
1303                         }
1304
1305                         /* Handle retopo painting */
1306                         if(retopo_mesh_paint_check()) {
1307                                 if(!retopo_paint(event))
1308                                         return;
1309                         }
1310                 }
1311
1312                 /* run any view3d event handler script links */
1313                 if (event && sa->scriptlink.totscript)
1314                         if (BPY_do_spacehandlers(sa, event, val, SPACEHANDLER_VIEW3D_EVENT))
1315                                 return; /* return if event was processed (swallowed) by handler(s) */
1316
1317                 /* TEXTEDITING?? */
1318                 if((G.obedit) && G.obedit->type==OB_FONT) {
1319                         switch(event) {
1320                         
1321                         case LEFTMOUSE:
1322                                 mouse_cursor();
1323                                 break;
1324                         case MIDDLEMOUSE:
1325                                 /* use '&' here, because of alt+leftmouse which emulates middlemouse */
1326                                 if(U.flag & USER_VIEWMOVE) {
1327                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1328                                                 viewmove(0);
1329                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1330                                                 viewmove(2);
1331                                         else if((G.qual==0) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==LR_ALTKEY)))
1332                                                 viewmove(1);
1333                                 }
1334                                 else {
1335                                         if((G.qual==LR_SHIFTKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_SHIFTKEY))))
1336                                                 viewmove(1);
1337                                         else if((G.qual==LR_CTRLKEY) || ((U.flag & USER_TWOBUTTONMOUSE) && (G.qual==(LR_ALTKEY|LR_CTRLKEY))))
1338                                                 viewmove(2);
1339                                         else
1340                                                 viewmove(0);
1341                                 }
1342                                 break;
1343                                 
1344                         case WHEELUPMOUSE:
1345                                 /* Regular:   Zoom in */
1346                                 /* Shift:     Scroll up */
1347                                 /* Ctrl:      Scroll right */
1348                                 /* Alt-Shift: Rotate up */
1349                                 /* Alt-Ctrl:  Rotate right */
1350
1351                                 if( G.qual & LR_SHIFTKEY ) {
1352                                         if( G.qual & LR_ALTKEY ) { 
1353                                                 G.qual &= ~LR_SHIFTKEY;
1354                                                 persptoetsen(PAD2);
1355                                                 G.qual |= LR_SHIFTKEY;
1356                                         } else {
1357                                                 persptoetsen(PAD2);
1358                                         }
1359                                 } else if( G.qual & LR_CTRLKEY ) {
1360                                         if( G.qual & LR_ALTKEY ) { 
1361                                                 G.qual &= ~LR_CTRLKEY;
1362                                                 persptoetsen(PAD4);
1363                                                 G.qual |= LR_CTRLKEY;
1364                                         } else {
1365                                                 persptoetsen(PAD4);
1366                                         }
1367                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1368                                         persptoetsen(PADMINUS);
1369                                 else
1370                                         persptoetsen(PADPLUSKEY);
1371
1372                                 doredraw= 1;
1373                                 break;
1374
1375                         case WHEELDOWNMOUSE:
1376                                 /* Regular:   Zoom out */
1377                                 /* Shift:     Scroll down */
1378                                 /* Ctrl:      Scroll left */
1379                                 /* Alt-Shift: Rotate down */
1380                                 /* Alt-Ctrl:  Rotate left */
1381
1382                                 if( G.qual & LR_SHIFTKEY ) {
1383                                         if( G.qual & LR_ALTKEY ) { 
1384                                                 G.qual &= ~LR_SHIFTKEY;
1385                                                 persptoetsen(PAD8);
1386                                                 G.qual |= LR_SHIFTKEY;
1387                                         } else {
1388                                                 persptoetsen(PAD8);
1389                                         }
1390                                 } else if( G.qual & LR_CTRLKEY ) {
1391                                         if( G.qual & LR_ALTKEY ) { 
1392                                                 G.qual &= ~LR_CTRLKEY;
1393                                                 persptoetsen(PAD6);
1394                                                 G.qual |= LR_CTRLKEY;
1395                                         } else {
1396                                                 persptoetsen(PAD6);
1397                                         }
1398                                 } else if(U.uiflag & USER_WHEELZOOMDIR) 
1399                                         persptoetsen(PADPLUSKEY);
1400                                 else
1401                                         persptoetsen(PADMINUS);
1402                                 
1403                                 doredraw= 1;
1404                                 break;
1405
1406                         case UKEY:
1407                                 if(G.qual==LR_ALTKEY) {
1408                                         remake_editText();
1409                                         doredraw= 1;
1410                                 } 
1411                                 else {
1412                                         do_textedit(event, val, ascii);
1413                                 }
1414                                 break;
1415                         case VKEY:
1416                                 if(G.qual==LR_ALTKEY) {
1417                                         paste_editText();
1418                                         doredraw= 1;
1419                                 } 
1420                                 else {
1421                                         do_textedit(event, val, ascii);
1422                                 }
1423                                 break;
1424                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1425                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1426                         case PADENTER:
1427                                 persptoetsen(event);
1428                                 doredraw= 1;
1429                                 break;
1430                                 
1431                         default:
1432                                 do_textedit(event, val, ascii);
1433                                 break;
1434                         }
1435                 }
1436                 else if(!G.obedit && (G.f & G_SCULPTMODE)) {
1437                         SculptData *sd= sculpt_data();
1438                         SculptSession *ss= sculpt_session();
1439                         BrushData *br= sculptmode_brush();
1440                         Mesh *me= get_mesh(OBACT);
1441                         char update_prop= 0;
1442                         
1443                         if(U.flag & USER_NONUMPAD) {
1444                                 event= convert_for_nonumpad(event);
1445                         }
1446                         
1447                         switch(event) {
1448                         case LEFTMOUSE:
1449                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1450                                         sculptmode_pmv(0);
1451                                 else if(!(ss && ss->radialcontrol))
1452                                         sculpt();
1453                                 break;
1454                         /* View */
1455                         case MIDDLEMOUSE:
1456                                 handle_view_middlemouse();
1457                                 break;
1458                         case WHEELUPMOUSE:
1459                                 handle_view_wheelup();
1460                                 doredraw= 1;
1461                                 break;
1462                         case WHEELDOWNMOUSE:
1463                                 handle_view_wheeldown();
1464                                 doredraw= 1;
1465                                 break;
1466                         case RIGHTMOUSE:
1467                                 if(G.qual==LR_SHIFTKEY+LR_CTRLKEY)
1468                                         sculptmode_pmv(1);
1469                                 break;
1470                         case CKEY:
1471                                 if(G.qual==LR_SHIFTKEY) {
1472                                         view3d_home(1);
1473                                         curs= give_cursor();
1474                                         curs[0]=curs[1]=curs[2]= 0.0;
1475                                         allqueue(REDRAWVIEW3D, 0);
1476                                 }
1477                                 else if(G.qual==0) {
1478                                         if (G.vd->persp==V3D_CAMOB)
1479                                                 /* center the camera offset */
1480                                                 G.vd->camdx= G.vd->camdy= 0.0;
1481                                         else {
1482                                                 /*non camera center*/
1483                                                 float new_ofs[3];
1484                                                 curs= give_cursor();
1485                                                 new_ofs[0]= -curs[0];
1486                                                 new_ofs[1]= -curs[1];
1487                                                 new_ofs[2]= -curs[2];
1488                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1489                                         }
1490                                 }
1491                                 doredraw= 1;
1492                                 break;
1493                         case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
1494                         case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
1495                         case PADPLUSKEY:
1496                         case PADMINUS:
1497                         case PADENTER:
1498                                 persptoetsen(event);
1499                                 doredraw= 1;
1500                                 break;
1501                         case BKEY:
1502                                 if(G.qual==LR_ALTKEY)
1503                                         view3d_edit_clipping(v3d);
1504                                 else if(G.qual==LR_SHIFTKEY) {
1505                                         if(G.vd->persp==V3D_CAMOB)
1506                                                 set_render_border();
1507                                         else
1508                                                 view3d_border_zoom();
1509                                 }
1510                                 break;
1511                         case PADSLASHKEY:
1512                                 if(!G.qual) {
1513                                         if(G.vd->localview) {
1514                                                 G.vd->localview= 0;
1515                                                 endlocalview(curarea);
1516                                         }
1517                                         else {
1518                                                 G.vd->localview= 1;
1519                                                 initlocalview();
1520                                         }
1521                                         allqueue(REDRAWVIEW3D, 1);
1522                                 }
1523                                 break;
1524                         /* Brush properties */
1525                         case AKEY:
1526                                 br->flag ^= SCULPT_BRUSH_AIRBRUSH;
1527                                 update_prop= 1; break;
1528                         case FKEY:
1529                                 if(ss) {
1530                                         sculpt_radialcontrol_start(G.qual == 0 ? RADIALCONTROL_SIZE :
1531                                                                    G.qual == LR_SHIFTKEY ? RADIALCONTROL_STRENGTH :
1532                                                                    G.qual == LR_CTRLKEY ? RADIALCONTROL_ROTATION :
1533                                                                    RADIALCONTROL_NONE);
1534                                 }
1535                                 break;
1536                         case VKEY:
1537                                 br->dir= br->dir==1 ? 2 : 1;
1538                                 update_prop= 1; break;
1539                         /* Set brush */
1540                         case DKEY:
1541                                 sd->brush_type= DRAW_BRUSH;
1542                                 update_prop= 1; break;
1543                         case SKEY:
1544                                 sd->brush_type= SMOOTH_BRUSH;
1545                                 update_prop= 1; break;
1546                         case PKEY:
1547                                 sd->brush_type= PINCH_BRUSH;
1548                                 update_prop= 1; break;
1549                         case IKEY:
1550                                 sd->brush_type= INFLATE_BRUSH;
1551                                 update_prop= 1; break;
1552                         case GKEY:
1553                                 sd->brush_type= GRAB_BRUSH;
1554                                 update_prop= 1; break;
1555                         case LKEY:
1556                                 sd->brush_type= LAYER_BRUSH;
1557                                 update_prop= 1; break;
1558                         case TKEY:
1559                                 sd->brush_type= FLATTEN_BRUSH;
1560                                 update_prop= 1; break;
1561                         /* Symmetry */
1562                         case XKEY:
1563                                 sd->symm^= SYMM_X;
1564                                 update_prop= 1; break;
1565                         case YKEY:
1566                                 sd->symm^= SYMM_Y;
1567                                 update_prop= 1; break;
1568                         case ZKEY:
1569                                 sd->symm^= SYMM_Z;
1570                                 update_prop= 1; break;
1571                         /* Interface */
1572                         case NKEY:
1573                                 if(G.qual==0) {
1574                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
1575                                         allqueue(REDRAWVIEW3D, 0);
1576                                 }
1577                                 break;
1578                         /* Multires */
1579                         case PAGEUPKEY:
1580                                 if(me && me->mr) {
1581                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
1582                                         multires_set_level_cb(ob, ob->data);
1583                                 }
1584                                 break;
1585                         case PAGEDOWNKEY:
1586                                 if(me && me->mr) {
1587                                         me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
1588                                         multires_set_level_cb(ob, ob->data);
1589                                 }
1590                                 break;
1591                         /* Partial Visibility */
1592                         case HKEY:
1593                                 if(G.qual==LR_ALTKEY) {
1594                                         waitcursor(1);
1595                                         mesh_pmv_off(ob, get_mesh(ob));
1596                                         BIF_undo_push("Partial mesh hide");
1597                                         allqueue(REDRAWVIEW3D,0);
1598                                         waitcursor(0);
1599                                 }
1600                                 break;
1601                         /* Layers */
1602                         case ONEKEY:
1603                                 do_layer_buttons(0); break;
1604                         case TWOKEY:
1605                                 do_layer_buttons(1); break;
1606                         case THREEKEY:
1607                                 do_layer_buttons(2); break;
1608                         case FOURKEY:
1609                                 do_layer_buttons(3); break;
1610                         case FIVEKEY:
1611                                 do_layer_buttons(4); break;
1612                         case SIXKEY:
1613                                 do_layer_buttons(5); break;
1614                         case SEVENKEY:
1615                                 do_layer_buttons(6); break;
1616                         case EIGHTKEY:
1617                                 do_layer_buttons(7); break;
1618                         case NINEKEY:
1619                                 do_layer_buttons(8); break;
1620                         case ZEROKEY:
1621                                 do_layer_buttons(9); break;
1622                         case MINUSKEY:
1623                                 do_layer_buttons(10); break;
1624                         case EQUALKEY:
1625                                 do_layer_buttons(11); break;
1626                         case ACCENTGRAVEKEY:
1627                                 do_layer_buttons(-1); break;
1628                         
1629                         case NDOFMOTION:                
1630                                 if (G.vd->ndofmode == 0) {
1631                                         viewmoveNDOF(1);
1632                                 } else if (G.vd->ndofmode == 1) {
1633                                         viewmoveNDOFfly(1);
1634                                 } else {
1635                                         NDofTransform();
1636                                 }
1637                 break;
1638                                 
1639             case NDOFBUTTON:
1640                                 if (val == 1) {
1641                                         G.vd->ndofmode +=1;
1642                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1643                                                 G.vd->ndofmode = 0;
1644                                 }
1645                                 if (val == 2) {
1646                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1647                                 }
1648                                 allqueue(REDRAWHEADERS, 0);
1649                 break;
1650                                 
1651                         }
1652                         
1653                         /* Redraw buttons window as well as view 3d (for floating panel) */
1654                         if(update_prop) {
1655                                 allqueue(REDRAWVIEW3D, 0);
1656                                 allqueue(REDRAWBUTSEDIT, 0);
1657                         }
1658                 } else {
1659
1660                         if (U.flag & USER_NONUMPAD) {
1661                                 event= convert_for_nonumpad(event);
1662                         }
1663
1664                         switch(event) {
1665                         
1666                         /* Afterqueue events */
1667                         case BACKBUFDRAW:
1668                                 backdrawview3d(1);
1669                                 break;
1670                         case RENDERPREVIEW:
1671                                 BIF_view3d_previewrender(sa);
1672                                 break;
1673                                 
1674                         case TABKEY:
1675                                 /* Shift-Tabe handling (other cases are in toets) */
1676                                 if (G.qual == LR_SHIFTKEY)
1677                                 {
1678                                         /* Snap toggle only when supported */
1679                                         if (BIF_snappingSupported())
1680                                         {
1681                                                 G.scene->snap_flag ^= SCE_SNAP;
1682                                                 allqueue(REDRAWHEADERS, 0);
1683                                         }                                       
1684                                 }
1685                                 break;
1686                                 
1687                         /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
1688                          * based on user preference USER_LMOUSESELECT
1689                          */
1690                         case LEFTMOUSE: 
1691                                 if ((G.obedit) || !(G.f&(G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT|G_PARTICLEEDIT))) {
1692                                         mouse_cursor();
1693                                 }
1694                                 else if (G.f & G_WEIGHTPAINT) {
1695                                         weight_paint();
1696                                 }
1697                                 else if (G.f & G_VERTEXPAINT) {
1698                                         vertex_paint();
1699                                 }
1700                                 else if (G.f & G_TEXTUREPAINT) {
1701                                         imagepaint_paint(L_MOUSE, 1);
1702                                 }
1703                                 else if (G.f & G_PARTICLEEDIT) {
1704                                         if(G.qual & LR_CTRLKEY)
1705                                                 mouse_cursor();
1706                                         else if(!PE_brush_particles())
1707                                                 mouse_cursor();
1708                                 }
1709                                 break;
1710                         case MIDDLEMOUSE:
1711                                 handle_view_middlemouse();
1712                                 break;
1713                         case RIGHTMOUSE:
1714                                 if((G.obedit) && (G.qual & LR_CTRLKEY)==0) {
1715                                         if(G.obedit->type==OB_MESH)
1716                                                 mouse_mesh();
1717                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1718                                                 mouse_nurb();
1719                                         else if(G.obedit->type==OB_MBALL)
1720                                                 mouse_mball();
1721                                         else if(G.obedit->type==OB_LATTICE)
1722                                                 mouse_lattice();
1723                                         else if(G.obedit->type==OB_ARMATURE)
1724                                                 mouse_armature();
1725                                 }
1726                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY)))
1727                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1728                                 else if((G.obedit && G.obedit->type==OB_MESH) && (G.qual == (LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)))
1729                                         mouse_mesh();   /* loop select for 1 mousebutton dudes */
1730                                 else if(G.qual==LR_CTRLKEY)
1731                                         mouse_select(); /* also allow in editmode, for vertex parenting */
1732                                 else if(FACESEL_PAINT_TEST)
1733                                         face_select();
1734                                 else if( G.f & (G_VERTEXPAINT|G_TEXTUREPAINT))
1735                                         sample_vpaint();
1736                                 else if( G.f & G_PARTICLEEDIT)
1737                                         PE_mouse_particles();
1738                                 else
1739                                         mouse_select(); /* does poses too */
1740                                 break;
1741                         case WHEELUPMOUSE:
1742                                 handle_view_wheelup();
1743                                 doredraw= 1;
1744                                 break;
1745                         case WHEELDOWNMOUSE:
1746                                 handle_view_wheeldown();
1747                                 doredraw= 1;
1748                                 break;
1749
1750             case NDOFMOTION:            
1751                                 if (G.vd->ndofmode == 0) {
1752                                         viewmoveNDOF(1);
1753                                 } else if (G.vd->ndofmode == 1) {
1754                                         viewmoveNDOFfly(1);
1755                                 } else {
1756                                         NDofTransform();
1757                                 }
1758                 break;
1759
1760             case NDOFBUTTON:
1761                                 if (val == 1) {
1762                                         G.vd->ndofmode +=1;
1763                                         if (G.vd->ndofmode > 2)         /* we have currently 3 modes : 0 original, 1 fly, 2 transform */
1764                                                 G.vd->ndofmode = 0;
1765                                 }
1766                                 if (val == 2) {
1767                                         G.vd->ndoffilter =(G.vd->ndoffilter == 1 ? 0 : 1);
1768                                 }
1769                                 allqueue(REDRAWHEADERS, 0);
1770                 break;
1771                                 
1772                         case ONEKEY:
1773                                 if(G.qual==LR_CTRLKEY) {
1774                                         flip_subdivison(1);
1775                                 }
1776                                 else do_layer_buttons(0); 
1777                                 break;
1778                                 
1779                         case TWOKEY:
1780                                 if(G.qual==LR_CTRLKEY) {
1781                                         flip_subdivison(2);
1782                                 }
1783                                 else do_layer_buttons(1); 
1784                                 break;
1785                                 
1786                         case THREEKEY:
1787                                 if(G.qual==LR_CTRLKEY) {
1788                                         flip_subdivison(3);
1789                                 }
1790                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1791                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1792                                                 select_faces_by_numverts(3);
1793                                 }
1794                                 else do_layer_buttons(2); 
1795                                 break;
1796                                 
1797                         case FOURKEY:
1798                                 if(G.qual==LR_CTRLKEY) {
1799                                         flip_subdivison(4);
1800                                 }
1801                                 else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1802                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1803                                                 select_faces_by_numverts(4);
1804                                 }
1805                                 else do_layer_buttons(3); 
1806                                 break;
1807                                 
1808                         case FIVEKEY:
1809                                 if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
1810                                         if ( (G.obedit) && (G.obedit->type==OB_MESH) )
1811                                                 select_faces_by_numverts(5);
1812                                 }
1813                                 
1814                                 else if(G.qual==LR_CTRLKEY) {}
1815                                 else do_layer_buttons(4);
1816                                 break;
1817
1818                         case SIXKEY:
1819                                 if(G.qual==LR_CTRLKEY) {}
1820                                 else do_layer_buttons(5);
1821                                 break;
1822                         case SEVENKEY:
1823                                 if(G.qual==LR_CTRLKEY) {}
1824                                 else do_layer_buttons(6);
1825                                 break;
1826                         case EIGHTKEY:
1827                                 if(G.qual==LR_CTRLKEY) {}
1828                                 else do_layer_buttons(7);
1829                                 break;
1830                         case NINEKEY:
1831                                 if(G.qual==LR_CTRLKEY) {}
1832                                 else do_layer_buttons(8);
1833                                 break;
1834                         case ZEROKEY:
1835                                 if(G.qual==LR_CTRLKEY) {}
1836                                 else do_layer_buttons(9);
1837                                 break;
1838                         case MINUSKEY:
1839                                 if(G.qual==LR_CTRLKEY) {}
1840                                 else do_layer_buttons(10);
1841                                 break;
1842                         case EQUALKEY:
1843                                 if(G.qual==LR_CTRLKEY) {}
1844                                 else do_layer_buttons(11);
1845                                 break;
1846                         case ACCENTGRAVEKEY:
1847                                 do_layer_buttons(-1);
1848                                 break;
1849                         
1850                         case SPACEKEY:
1851                                 if(G.qual == LR_CTRLKEY) {
1852                                         val= pupmenu("Manipulator%t|Enable/Disable|Translate|Rotate|Scale|Combo");
1853                                         if(val>0) {
1854                                                 if(val==1) v3d->twflag ^= V3D_USE_MANIPULATOR;
1855                                                 else {
1856                                                         if(val==2) v3d->twtype= V3D_MANIP_TRANSLATE;
1857                                                         else if(val==3) v3d->twtype= V3D_MANIP_ROTATE;
1858                                                         else if(val==4) v3d->twtype= V3D_MANIP_SCALE;
1859                                                         else if(val==5) v3d->twtype= V3D_MANIP_TRANSLATE|V3D_MANIP_ROTATE|V3D_MANIP_SCALE;
1860                                                         v3d->twflag |= V3D_USE_MANIPULATOR;
1861                                                 }
1862                                                 doredraw= 1;
1863                                         }
1864                                 }
1865                                 else if(G.qual == LR_ALTKEY) {
1866                                         BIF_selectOrientation();
1867                                         doredraw= 1;
1868                                 }
1869
1870                                 break;
1871                                 
1872                         case AKEY:
1873                                 if(G.qual == (LR_CTRLKEY|LR_ALTKEY)) {
1874                                         if(G.obedit == 0)
1875                                                 alignmenu();
1876                                         else if(G.obedit->type==OB_ARMATURE)
1877                                                 align_selected_bones();
1878                                 }
1879                                 else if(G.qual & LR_CTRLKEY) { /* also with shift! */
1880                                         apply_object(); 
1881                                 }
1882                                 else if((G.qual==LR_SHIFTKEY)) {
1883                                         toolbox_n_add();
1884                                 }
1885                                 else {
1886                                         if(G.obedit) {
1887                                                 if(G.obedit->type==OB_MESH)
1888                                                         deselectall_mesh();
1889                                                 else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
1890                                                         deselectall_nurb();
1891                                                 else if(G.obedit->type==OB_MBALL)
1892                                                         deselectall_mball();
1893                                                 else if(G.obedit->type==OB_LATTICE)
1894                                                         deselectall_Latt();
1895                                                 else if(G.obedit->type==OB_ARMATURE)
1896                                                         deselectall_armature(1, 1);     /* 1 == toggle */
1897                                         }
1898                                         else if (ob && (ob->flag & OB_POSEMODE)){
1899                                                 deselectall_posearmature(ob, 1, 1);
1900                                         }
1901                                         else {
1902                                                 if(FACESEL_PAINT_TEST) deselectall_tface();
1903                                                 else if(G.f & G_PARTICLEEDIT) PE_deselectall();
1904                                                 else {
1905                                                         /* by design, the center of the active object 
1906                                                          * (which need not necessarily by selected) will
1907                                                          * still be drawn as if it were selected.
1908                                                          */
1909                                                         deselectall();
1910                                                 }
1911                                         }
1912                                 }
1913                                 break;
1914                         case BKEY:
1915                                 if(G.qual==LR_ALTKEY)
1916                                         view3d_edit_clipping(v3d);
1917                                 else if(G.qual==LR_SHIFTKEY)
1918                                 {
1919                                         if(G.vd->persp==V3D_CAMOB)
1920                                                 set_render_border();
1921                                         else
1922                                                 view3d_border_zoom();
1923                                 }
1924                                 else if(G.qual==LR_CTRLKEY) {
1925                                         extern void pointcache_bake(PTCacheID *pid, int startframe);
1926                                         extern void pointcache_free(PTCacheID *pid, int cacheonly);
1927                                         extern void fluidsimBake(Object *ob);
1928                                         extern void fluidsimFreeBake(Object *ob);
1929                                         int pupval;
1930
1931                                         pupval= pupmenu("Physics Baking%t|Bake selected %x1|Free bake selected %x2|Free cache selected %x3");
1932
1933                                         if(pupval > 0) {
1934                                                 if(pupval == 1) {
1935                                                         pointcache_bake(NULL, 0);
1936                                                         /* also bake first domain of selected objects... */
1937                                                         fluidsimBake(NULL);
1938                                                 }
1939                                                 else if(pupval == 2) {
1940                                                         pointcache_free(NULL, 0);
1941                                                         fluidsimFreeBake(NULL);
1942                                                 }
1943                                                 else if(pupval == 3)
1944                                                         pointcache_free(NULL, 1);
1945                                         }
1946                                 }
1947                                 else if(G.qual== (LR_ALTKEY|LR_CTRLKEY))
1948                                         objects_bake_render_menu();
1949                                 else if(G.qual==0)
1950                                         borderselect();
1951                                 break;
1952                         case CKEY:
1953                                 if(G.qual==LR_CTRLKEY) {
1954                                         if(ob && (ob->flag & OB_POSEMODE))
1955                                                 pose_copy_menu();       /* poseobject.c */
1956                                         else
1957                                                 copy_attr_menu();
1958                                 }
1959                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) 
1960                                         gpencil_convert_menu(); /* gpencil.c */
1961                                 else if(G.qual==LR_ALTKEY) {
1962                                         if(ob && (ob->flag & OB_POSEMODE))
1963                                                 pose_clear_constraints();       /* poseobject.c */
1964                                         else
1965                                                 convertmenu();  /* editobject.c */
1966                                 }
1967                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) 
1968                                         add_constraint(0);      /* editconstraint.c, generic for objects and posemode */
1969                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY)) {
1970                                         BIF_manageTransformOrientation(0, 1);
1971                                         allqueue(REDRAWVIEW3D, 0);
1972                                 }
1973                                 else if((G.qual==LR_SHIFTKEY)) {
1974                                         view3d_home(1);
1975                                         curs= give_cursor();
1976                                         curs[0]=curs[1]=curs[2]= 0.0;
1977                                         allqueue(REDRAWVIEW3D, 0);
1978                                 }
1979                                 else if((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF) ) {
1980                                         makecyclicNurb();
1981                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1982                                         allqueue(REDRAWVIEW3D, 0);
1983                                 }
1984                                 else if((G.qual==0)){
1985                                         if (G.vd->persp==V3D_CAMOB)
1986                                                 /* center the camera offset */
1987                                                 G.vd->camdx= G.vd->camdy= 0.0;
1988                                         else {
1989                                                 /*non camera center*/
1990                                                 float new_ofs[3];
1991                                                 curs= give_cursor();
1992                                                 new_ofs[0]= -curs[0];
1993                                                 new_ofs[1]= -curs[1];
1994                                                 new_ofs[2]= -curs[2];
1995                                                 smooth_view(G.vd, new_ofs, NULL, NULL, NULL);
1996                                         }
1997                                         scrarea_queue_winredraw(curarea);
1998                                 }
1999                                 break;
2000                         case DKEY:
2001                                 if((G.qual==LR_SHIFTKEY)) {
2002                                         duplicate_context_selected();
2003                                 }
2004                                 else if(G.qual==LR_ALTKEY) {
2005                                         if(ob && (ob->flag & OB_POSEMODE))
2006                                                 error ("Duplicate not possible in posemode.");
2007                                         else if((G.obedit==NULL))
2008                                                 adduplicate(0, 0);
2009                                 }
2010                                 else if(G.qual==LR_CTRLKEY) {
2011                                         imagestodisplist(); // removed
2012                                 }
2013                                 else if((G.qual==0)){
2014                                         pupval= pupmenu("Draw mode%t|BoundBox %x1|Wire %x2|OpenGL Solid %x3|Shaded Solid %x4|Textured Solid %x5");
2015                                         if(pupval>0) {
2016                                                 G.vd->drawtype= pupval;
2017                                                 doredraw= 1;
2018                                         }
2019                 }
2020                                 
2021                                 break;
2022                         case EKEY:
2023                                 if (G.qual==0){
2024                                         if(G.obedit) {
2025                                                 if(G.obedit->type==OB_MESH)
2026                                                         extrude_mesh();
2027                                                 else if(G.obedit->type==OB_CURVE)
2028                                                         addvert_Nurb('e');
2029                                                 else if(G.obedit->type==OB_SURF)
2030                                                         extrude_nurb();
2031                                                 else if(G.obedit->type==OB_ARMATURE)
2032                                                         extrude_armature(0);
2033                                         }
2034                                 }
2035                                 else if (G.qual==LR_CTRLKEY) {
2036                                         if(G.obedit && G.obedit->type==OB_MESH)
2037                                                 Edge_Menu();
2038                                         else if (FACESEL_PAINT_TEST)
2039                                                 seam_mark_clear_tface(0);
2040                                 }
2041                                 else if (G.qual==LR_SHIFTKEY) {
2042                                         if (G.obedit && G.obedit->type==OB_MESH &&
2043                                             !multires_level1_test()) {
2044                                                 initTransform(TFM_CREASE, CTX_EDGE);
2045                                                 Transform();
2046                                         }
2047                                         else if (G.obedit && G.obedit->type==OB_ARMATURE) {
2048                                                 extrude_armature(1);
2049                                         }
2050                                 }
2051                                 else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
2052                                         if (G.obedit && G.obedit->type==OB_MESH &&
2053                                             !multires_level1_test()) {
2054                                                 if (G.scene->selectmode & SCE_SELECT_VERTEX) {
2055                                                         initTransform(TFM_BWEIGHT, CTX_NONE);
2056                                                 }
2057                                                 else {
2058                                                         initTransform(TFM_BWEIGHT, CTX_EDGE);
2059                                                 }
2060                                                 Transform();
2061                                         }
2062                                 }
2063                                 break;
2064                         case FKEY:
2065                                 if(G.obedit) {
2066                                         if(G.obedit->type==OB_MESH) {
2067                                                 if(G.qual == LR_CTRLKEY)
2068                                                         Face_Menu();
2069                                                 else if((G.qual==LR_SHIFTKEY))
2070                                                         fill_mesh();
2071                                                 else if(G.qual==LR_ALTKEY)
2072                                                         beauty_fill();
2073                                                 else if(G.qual==(LR_CTRLKEY|LR_SHIFTKEY))
2074                                                         edge_flip();
2075                                                 else if (G.qual==0)
2076                                                         addedgeface_mesh();
2077                                                 else if ( G.qual == 
2078                                                          (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2079                                                         select_linked_flat_faces();
2080                                                 }
2081
2082                                         }
2083                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
2084                                                 addsegment_nurb();
2085                                         }
2086                                         else if(G.obedit->type == OB_ARMATURE) {
2087                                                 fill_bones_armature();
2088                                         }
2089                                 }
2090                                 else if(G.qual==LR_CTRLKEY)
2091                                         sort_faces();
2092                                 else if((G.qual==LR_SHIFTKEY)) {
2093                                         if(ob && (ob->flag & OB_POSEMODE))
2094                                            pose_activate_flipped_bone();
2095                                         else if(G.f & G_WEIGHTPAINT)
2096                                                 pose_activate_flipped_bone();
2097                                         else if(G.f & G_PARTICLEEDIT)
2098                                                 PE_radialcontrol_start(RADIALCONTROL_STRENGTH);
2099                                         else
2100                                                 fly();
2101                                 }
2102                                 else if((G.qual==LR_ALTKEY)) {
2103                                         if(ob && (ob->flag & OB_POSEMODE))
2104                                                 if(okee("Flip quaternion rotations"))
2105                                                         pose_flipquats();
2106                                 }
2107                                 else {
2108                                         if (G.f & (G_VERTEXPAINT|G_WEIGHTPAINT|G_TEXTUREPAINT)){
2109                                                 G.f ^= G_FACESELECT;
2110                                                 allqueue(REDRAWVIEW3D, 1);
2111                                                 allqueue(REDRAWBUTSEDIT, 1);
2112                                         }
2113                                         else if(G.f & G_PARTICLEEDIT) {
2114                                                 PE_radialcontrol_start(RADIALCONTROL_SIZE);
2115                                         } else {
2116                                                 pupmenu("Note%t|UV/Face Select was removed. Editmode now allows UV editing, Add a UV layer or Unwrap (UKey)");
2117                                         }
2118                                 }
2119                                 
2120                                 break;
2121                         case GKEY:
2122                                 if((G.qual == LR_CTRLKEY)) {
2123                                         if(G.obedit) {
2124                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2125                                                         vgroup_assign_with_menu();
2126                                         }
2127                                         else if(ob && (ob->flag & OB_POSEMODE))
2128                                                 pgroup_operation_with_menu();
2129                                         else
2130                                                 group_operation_with_menu();
2131                                 }
2132                                 else if((G.qual == (LR_CTRLKEY|LR_SHIFTKEY))) {
2133                                         if(G.obedit) {
2134                                                 if(ELEM(G.obedit->type, OB_MESH, OB_LATTICE))
2135                                                         vgroup_operation_with_menu();
2136                                         }
2137                                 }
2138                                 else if((G.qual==LR_SHIFTKEY)) {
2139                                         if(G.obedit) {
2140                                                 if(G.obedit->type==OB_MESH)
2141                                                         select_mesh_group_menu();
2142                                         } 
2143                                         else if(ob && (ob->flag & OB_POSEMODE))
2144                                                 pose_select_grouped_menu();
2145                                         else if (ob)
2146                                                 select_object_grouped_menu();
2147                                 }
2148                                 else if((G.obedit==0) && G.qual==LR_ALTKEY) {
2149                                         if(okee("Clear location")) {
2150                                                 clear_object('g');
2151                                         }
2152                                 }
2153                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2154                                         v3d->twtype= V3D_MANIP_TRANSLATE;
2155                                         doredraw= 1;
2156                                 }
2157                                 else if((G.qual==0)) {
2158                                         initTransform(TFM_TRANSLATION, CTX_NONE);
2159                                         Transform();
2160                                 }
2161                                 break;
2162                         case HKEY:
2163                                 if(G.obedit) {
2164                                         if(G.obedit->type==OB_MESH) {
2165                                                 if(G.qual==LR_CTRLKEY)
2166                                                         add_hook_menu();
2167                                                 else if(G.qual==LR_ALTKEY)
2168                                                         reveal_mesh();
2169                                                 else if((G.qual==LR_SHIFTKEY))
2170                                                         hide_mesh(1);
2171                                                 else if((G.qual==0)) 
2172                                                         hide_mesh(0);
2173                                         }
2174                                         else if(G.obedit->type== OB_SURF) {
2175                                                 if(G.qual==LR_CTRLKEY)
2176                                                         add_hook_menu();
2177                                                 else if(G.qual==LR_ALTKEY)
2178                                                         revealNurb();
2179                                                 else if((G.qual==LR_SHIFTKEY))
2180                                                         hideNurb(1);
2181                                                 else if((G.qual==0))
2182                                                         hideNurb(0);
2183                                         }
2184                                         else if(G.obedit->type==OB_CURVE) {
2185                                                 if(G.qual==LR_CTRLKEY)
2186                                                         add_hook_menu();
2187                                                 else if(G.qual==LR_ALTKEY)
2188                                                         revealNurb();
2189                                                 /* should be G.qual==LR_SHIFTKEY, but that is taken fro handles already */
2190                                                 else if((G.qual==(LR_ALTKEY|LR_SHIFTKEY))) 
2191                                                         hideNurb(1);
2192                                                 /* should be G.qual==0, but that is taken for handles already */
2193                                                 else if((G.qual==(LR_ALTKEY|LR_CTRLKEY))) 
2194                                                         hideNurb(0);
2195                                                 else {
2196                                                         if(G.qual==LR_CTRLKEY) /* conflict */
2197                                                                 autocalchandlesNurb_all(1);     /* flag=1, selected */
2198                                                         else if((G.qual==LR_SHIFTKEY))
2199                                                                 sethandlesNurb(1);
2200                                                         else if((G.qual==0))
2201                                                                 sethandlesNurb(3);
2202                                                         
2203                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2204                                                         BIF_undo_push("Handle change");
2205                                                         allqueue(REDRAWVIEW3D, 0);
2206                                                 }
2207                                         }
2208                                         else if(G.obedit->type==OB_LATTICE) {
2209                                                 if(G.qual==LR_CTRLKEY) add_hook_menu();
2210                                         }
2211                                         else if(G.obedit->type==OB_MBALL) {
2212                                                 if(G.qual==LR_ALTKEY)
2213                                                         reveal_mball();
2214                                                 else if((G.qual==LR_SHIFTKEY))
2215                                                         hide_mball(1);
2216                                                 else if((G.qual==0)) 
2217                                                         hide_mball(0);
2218                                         }
2219                                         else if(G.obedit->type==OB_ARMATURE) {
2220                                                 if (G.qual==0)
2221                                                         hide_selected_armature_bones();
2222                                                 else if (G.qual==LR_SHIFTKEY)
2223                                                         hide_unselected_armature_bones();
2224                                                 else if (G.qual==LR_ALTKEY)
2225                                                         show_all_armature_bones();
2226                                         }
2227                                 }
2228                                 else if(FACESEL_PAINT_TEST)
2229                                         hide_tface();
2230                                 else if(G.f & G_PARTICLEEDIT) {
2231                                         if(G.qual == LR_ALTKEY)
2232                                                 PE_hide(0);
2233                                         else if(G.qual == LR_SHIFTKEY)
2234                                                 PE_hide(1);
2235                                         else if(G.qual == 0)
2236                                                 PE_hide(2);
2237                                 }
2238                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2239                                         if (G.qual==0)
2240                                                 hide_selected_pose_bones();
2241                                         else if (G.qual==LR_SHIFTKEY)
2242                                                 hide_unselected_pose_bones();
2243                                         else if (G.qual==LR_ALTKEY)
2244                                                 show_all_pose_bones();
2245                                 }
2246                                 /* Object mode only, other modes are accounted for above */
2247                                 else if ((G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
2248                                         if(G.qual==LR_CTRLKEY)hookmenu();
2249                                         else if(G.qual==LR_ALTKEY) show_objects();
2250                                         else if(G.qual==LR_SHIFTKEY) hide_objects(0);
2251                                         else hide_objects(1);
2252                                 }
2253                                 break;
2254                         case IKEY:
2255                                 if(G.qual==LR_CTRLKEY) {
2256                                         if((ob) && (ob->flag & OB_POSEMODE) && (ob->type==OB_ARMATURE))
2257                                                 deselectall_posearmature(ob, 3, 1);
2258                                         else if(ob && G.obedit) {
2259                                                 if(G.obedit->type == OB_ARMATURE)
2260                                                         deselectall_armature(3, 1);
2261                                                 else
2262                                                         selectswap_mesh();
2263                                         }
2264                                         else
2265                                                 selectswap();
2266                                 }
2267                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY)) {
2268                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2269                                                 pose_clear_IK();
2270                                 }
2271                                 else if(G.qual==LR_SHIFTKEY) {
2272                                         if(ob && (ob->flag & OB_POSEMODE) && ob->type==OB_ARMATURE)
2273                                                 pose_add_IK();
2274                                 }
2275                                 break;
2276                                 
2277                         case JKEY:
2278                                 if(G.qual==LR_CTRLKEY) {
2279                                         if( ob ) {
2280                                                 join_menu();
2281                                         }
2282                                         else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
2283                                                 addsegment_nurb();
2284                                         } else {
2285                                                 error("Can't join unless there is an active object");
2286                                         }
2287                                         
2288                                 }
2289                                 else if(G.obedit) {
2290                                         if(G.obedit->type==OB_MESH) {
2291                                                 join_triangles();
2292                                         }
2293                                 }
2294
2295                                 break;
2296                         case KKEY:
2297                                 if(G.obedit) {
2298                                         if (G.obedit->type==OB_MESH) {
2299                                                 if (G.qual==LR_SHIFTKEY)
2300                                                         KnifeSubdivide(KNIFE_PROMPT);
2301                                                 else if (G.qual==0)
2302                                                         LoopMenu();
2303                                         }
2304                                         else if(G.obedit->type==OB_SURF)
2305                                                 printknots();
2306                                 }
2307                                 else {
2308                                         if((G.qual==LR_SHIFTKEY)) {
2309                                                 if(FACESEL_PAINT_TEST)
2310                                                         if (G.f & G_WEIGHTPAINT)
2311                                                                 clear_wpaint_selectedfaces();
2312                                                         else
2313                                                                 clear_vpaint_selectedfaces();
2314                                                 else if(G.f & G_VERTEXPAINT)
2315                                                         clear_vpaint();
2316                                                 else
2317                                                         select_select_keys();
2318                                         }
2319                                         else if (G.qual==0)
2320                                                 set_ob_ipoflags();
2321                                 }
2322                                 
2323                                 break;
2324                         case LKEY:
2325                                 if(G.obedit) {
2326                                         if(G.obedit->type==OB_MESH) {
2327                                                 if (G.qual & LR_CTRLKEY) {
2328                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2329                                                                 selectconnected_mesh_all(); /* normal select linked */
2330                                                         } else {
2331                                                                 selectconnected_delimit_mesh_all(); /* select linked with edge crease delimiting */
2332                                                         }
2333                                                 } else {
2334                                                         if ((G.scene->selectmode & SCE_SELECT_FACE) == 0) {
2335                                                                 selectconnected_mesh();
2336                                                         } else {
2337                                                                 selectconnected_delimit_mesh();
2338                                                         }
2339                                                 }
2340                                         }
2341                                         if(G.obedit->type==OB_ARMATURE)
2342                                                 selectconnected_armature();
2343                                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
2344                                                 selectconnected_nurb();
2345                                 }
2346                                 else if(ob && (ob->flag & OB_POSEMODE)) {
2347                                         if (G.qual == LR_CTRLKEY) 
2348                                                 poselib_preview_poses(ob, 0);
2349                                         else if (G.qual == LR_SHIFTKEY) 
2350                                                 poselib_add_current_pose(ob, 0);
2351                                         else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
2352                                                 poselib_rename_pose(ob);
2353                                         else if (G.qual == LR_ALTKEY)
2354                                                 poselib_remove_pose(ob, NULL);
2355                                         else
2356                                                 selectconnected_posearmature();
2357                                 }
2358                                 else {
2359                                         if(FACESEL_PAINT_TEST) {
2360                                                 if((G.qual==0))
2361                                                         select_linked_tfaces(0);
2362                                                 else if((G.qual==LR_SHIFTKEY))
2363                                                         select_linked_tfaces(1);
2364                                                 else if(G.qual==LR_CTRLKEY)
2365                                                         select_linked_tfaces(2);
2366                                         }
2367                                         else if(G.f & G_PARTICLEEDIT) {
2368                                                 if(G.qual==0)
2369                                                         PE_select_linked();
2370                                         }
2371                                         else {
2372                                                 if((G.qual==0))
2373                                                         make_local_menu();
2374                                                 else if((G.qual==LR_SHIFTKEY))
2375                                                         selectlinks_menu();
2376                                                 else if(G.qual==LR_CTRLKEY)
2377                                                         make_links_menu();
2378                                         }
2379                                 }
2380                                 break;
2381                         case MKEY:
2382                                 if(G.obedit){
2383                                         if (ELEM(G.qual, 0, LR_SHIFTKEY) && (G.obedit->type==OB_ARMATURE)) {
2384                                                 pose_movetolayer();
2385                                         }
2386                                         else if (G.qual==LR_ALTKEY) {
2387                                                 if (G.obedit->type == OB_MESH) {
2388                                                         mergemenu();
2389                                                         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2390                                                 }
2391                                                 else if (G.obedit->type == OB_ARMATURE) {
2392                                                         merge_armature();
2393                                                 }
2394                                         }
2395                                         else if ((G.qual==0) || (G.qual==LR_CTRLKEY)) {
2396                                                 mirrormenu();
2397                                         }
2398                                         else if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2399                                                 if(G.obedit->type==OB_MESH) select_non_manifold();
2400                                         }
2401                                 }
2402                                 else if(G.qual & LR_CTRLKEY) {
2403                                         mirrormenu();
2404                                 }
2405                                 else if(G.qual==0 || G.qual==LR_SHIFTKEY) {
2406                                         if(ob && (ob->flag & OB_POSEMODE))
2407                                                 pose_movetolayer();
2408                                         else
2409                                                 movetolayer();
2410                                 }
2411                                 break;
2412                         case NKEY:
2413                                 if((G.qual==0)) {
2414                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_OBJECT, UI_PNL_TO_MOUSE);
2415                                         allqueue(REDRAWVIEW3D, 0);
2416                                 }
2417                                 else if(G.obedit) {
2418                                         switch (G.obedit->type){
2419                                         case OB_ARMATURE:
2420                                                 if(G.qual==LR_CTRLKEY) {
2421                                                         pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
2422                                                         if (pupval > 0) {
2423                                                                 auto_align_armature(pupval - 1);
2424                                                                 allqueue(REDRAWVIEW3D, 0);
2425                                                         }
2426                                                 }
2427                                                 break;
2428                                         case OB_MESH: 
2429                                                 if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2430                                                         if(okee("Recalculate normals inside")) {
2431                                                                 righthandfaces(2);
2432                                                                 allqueue(REDRAWVIEW3D, 0);
2433                                                                 BIF_undo_push("Recalculate normals inside");
2434                                                         }
2435                                                 }
2436                                                 else if(G.qual==LR_CTRLKEY){
2437                                                         if(okee("Recalculate normals outside")) {
2438                                                                 righthandfaces(1);
2439                                                                 allqueue(REDRAWVIEW3D, 0);
2440                                                                 BIF_undo_push("Recalculate normals outside");
2441                                                         }
2442                                                 }
2443                                                 break;
2444                                         }
2445                                 }
2446                                 
2447                                 break;
2448                         case OKEY:
2449                                 if (G.obedit || G.f&G_PARTICLEEDIT) {
2450                                         if (G.qual==LR_SHIFTKEY) {
2451                                                 G.scene->prop_mode = (G.scene->prop_mode+1)%7;
2452                                                 allqueue(REDRAWHEADERS, 0);
2453                                         }
2454                                         else if((G.qual==LR_ALTKEY)) {
2455                                                 if(G.scene->proportional==2) G.scene->proportional= 1;
2456                                                 else G.scene->proportional= 2;
2457                                                 allqueue(REDRAWHEADERS, 0);
2458                                         }
2459                                         else if((G.qual==0)) {
2460                                                 G.scene->proportional= !G.scene->proportional;
2461                                                 allqueue(REDRAWHEADERS, 0);
2462                                         }
2463                                 }
2464                                 else if((G.qual==LR_SHIFTKEY || G.qual==(LR_ALTKEY|LR_SHIFTKEY))) {
2465                                         flip_subdivison(-1);
2466                                 }
2467                                 else if(G.qual==LR_ALTKEY) {
2468                                         if(okee("Clear origin")) {
2469                                                 clear_object('o');
2470                                         }
2471                                 }
2472                                 break;
2473
2474                         case PKEY:
2475                                 if(G.obedit) {
2476                                         if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2477                                                 if(G.obedit->type==OB_ARMATURE)
2478                                                         make_bone_parent();
2479                                                 else
2480                                                         make_parent();
2481                                         }
2482                                         
2483                                         else if(G.qual==LR_ALTKEY && G.obedit->type==OB_ARMATURE)
2484                                                 clear_bone_parent();
2485                                         else if((G.qual==0) && (G.obedit->type==OB_ARMATURE)) 
2486                                                 armature_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2487                                         else if((G.qual==(LR_CTRLKEY|LR_ALTKEY)) && (G.obedit->type==OB_ARMATURE))
2488                                                 separate_armature();
2489                                         else if((G.qual==0) && G.obedit->type==OB_MESH)
2490                                                 separatemenu();
2491                                         else if ((G.qual==0) && ELEM(G.obedit->type, OB_CURVE, OB_SURF))
2492                                                 separate_nurb();
2493                                         else if (G.qual==LR_SHIFTKEY) {
2494                                                 initTransform(TFM_PUSHPULL, CTX_NONE);
2495                                                 Transform();
2496                                         }
2497                                 }
2498                                 else if(G.qual==LR_CTRLKEY || G.qual==(LR_SHIFTKEY|LR_CTRLKEY))
2499                                         make_parent();
2500                                 else if(G.qual==LR_SHIFTKEY) {
2501                                         toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0);
2502                                         doredraw= 1;
2503                                 }
2504                                 else if(G.qual==(LR_ALTKEY|LR_SHIFTKEY)) {
2505                                         initTransform(TFM_PUSHPULL, CTX_NONE);
2506                                         Transform();
2507                                 }
2508                                 else if(G.qual==LR_ALTKEY)
2509                                         clear_parent();
2510                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY))
2511                                         make_proxy();
2512                                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
2513                         start_RBSimulation();
2514                                 }
2515                                 else if((G.qual==0) && (OBACT) && (OBACT->type==OB_ARMATURE) && (OBACT->flag & OB_POSEMODE))
2516                                         pose_select_hierarchy(BONE_SELECT_PARENT, 1); // 1 = add to selection
2517                                 else if((G.qual==0)) {
2518                         start_game();
2519                                 }
2520                                 break;                          
2521                         case RKEY:
2522                                 if((G.obedit==0) && G.qual==LR_ALTKEY) {
2523                                         if(okee("Clear rotation")) {
2524                                                 clear_object('r');
2525                                         }
2526                                 } 
2527                                 else if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2528                                         v3d->twtype= V3D_MANIP_ROTATE;
2529                                         doredraw= 1;
2530                                 }
2531                                 else if (G.obedit) {
2532                                         if((G.qual==LR_SHIFTKEY)) {
2533                                                 if ELEM(G.obedit->type,  OB_CURVE, OB_SURF)                                     
2534                                                         selectrow_nurb();
2535                                         }
2536                                         else if(G.qual==LR_CTRLKEY) {
2537                                                 if (G.obedit->type==OB_MESH) {
2538                                                         CutEdgeloop(1);
2539                                                         BIF_undo_push("Cut Edgeloop");
2540                                                 }
2541                                                 else if (G.obedit->type==OB_ARMATURE) {
2542                                                         initTransform(TFM_BONE_ROLL, CTX_NONE);
2543                                                         Transform();
2544                                                 }
2545                                         }
2546                                         else if((G.qual==0)) {
2547                                                 initTransform(TFM_ROTATION, CTX_NONE);
2548                                                 Transform();
2549                                         }
2550                                 }
2551                                 else if((G.qual==0)) {
2552                                         initTransform(TFM_ROTATION, CTX_NONE);
2553                                         Transform();
2554                                 }
2555                                 break;
2556                         case SKEY:
2557                                 if(G.qual== (LR_CTRLKEY|LR_ALTKEY)) {
2558                                         v3d->twtype= V3D_MANIP_SCALE;
2559                                         doredraw= 1;
2560                                 }
2561                                 else if(G.obedit) {
2562                                         
2563                                         if(G.qual==LR_ALTKEY) {
2564                                                 if(G.obedit->type==OB_ARMATURE) {
2565                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2566                                                 }
2567                                                 else if (G.obedit->type==OB_CURVE) {
2568                                                         initTransform(TFM_CURVE_SHRINKFATTEN, CTX_NONE);
2569                                                 } else {
2570                                                         initTransform(TFM_SHRINKFATTEN, CTX_NONE);
2571                                                 }
2572                                                 Transform();
2573                                         }
2574                                         else if(G.qual==LR_CTRLKEY) {
2575                                                 initTransform(TFM_SHEAR, CTX_NONE);
2576                                                 Transform();
2577                                         }
2578                                         else if(G.qual==LR_SHIFTKEY)
2579                                                 snapmenu();
2580                                         else if(G.qual==0) {
2581                                                 if(G.obedit->type==OB_ARMATURE) {
2582                                                         bArmature *arm= G.obedit->data;
2583                                                         if(arm->drawtype==ARM_ENVELOPE)
2584                                                                 initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
2585                                                         else
2586                                                                 initTransform(TFM_RESIZE, CTX_NONE);
2587                                                 }
2588                                                 else
2589                                                         initTransform(TFM_RESIZE, CTX_NONE);
2590                                                 Transform();
2591                                         }
2592                                         else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
2593                                                 initTransform(TFM_TOSPHERE, CTX_NONE);
2594                                                 Transform();
2595                                         }
2596                                         if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
2597                                                 if(G.obedit->type==OB_MESH) select_sharp_edges();
2598                                         }
2599                                 }
2600                                 else if(G.qual==LR_ALTKEY) {
2601                                         if(G.f & G_WEIGHTPAINT)
2602                                                 ob= ob->parent;
2603                                         if(ob && (ob->flag & OB_POSEMODE)) {
2604                                                 bArmature *arm= ob->data;
2605                                                 if( arm->drawtype==ARM_ENVELOPE) {
2606                                                         initTransform(TFM_BONESIZE, CTX_NONE);
2607                                                         Transform();
2608                                                         break;
2609                                                 }
2610                                         }
2611                                         
2612                                         if(okee("Clear scale")) {
2613                                                 clear_object('s');
2614                                         }
2615                                 }
2616                                 else if(G.qual==LR_SHIFTKEY) {
2617                                         snapmenu();
2618                                 }
2619                                 else if((G.qual==0)) {
2620                                         initTransform(TFM_RESIZE, CTX_NONE);
2621                                         Transform();
2622                                 }
2623                                 else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
2624                                         initTransform(TFM_TOSPHERE, CTX_NONE);
2625                                         Transform();
2626                                 }
2627                                 else if(G.qual==(LR_CTRLKEY|LR_ALTKEY|LR_SHIFTKEY)) {
2628                                         initTransform(TFM_SHEAR, CTX_NONE);
2629                                         Transform();
2630                                 }
2631                                 break;
2632                         case TKEY:
2633                                 if(G.qual == LR_SHIFTKEY) { /* toggle texture in solid draw mode */
2634                                         G.vd->flag2 ^= V3D_SOLID_TEX;
2635                                         allqueue(REDRAWVIEW3D, 0);
2636                                 } else if(G.obedit){
2637                                         if((G.qual & LR_CTRLKEY) && G.obedit->type==OB_MESH) {
2638                                                 convert_to_triface(G.qual & LR_SHIFTKEY);
2639                                                 allqueue(REDRAWVIEW3D, 0);
2640                                                 if (EM_texFaceCheck())
2641                                                         allqueue(REDRAWIMAGE, 0);
2642                                                 
2643                                                 countall();
2644                                                 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2645                                         }
2646                                         if (G.obedit->type==OB_CURVE) {
2647                                                 if (G.qual==LR_ALTKEY) {
2648                                                         clear_tilt();
2649                                                 }
2650                                                 else if (G.qual==0) {
2651                                                         initTransform(TFM_TILT, CTX_NONE);
2652                                                         Transform();
2653             &