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